I'm trying to use the same ponent to handle the Add and Edit part of my app. I'm using Firebase, so I'm checking if there is an id
in the route params, if there is, it renders as the edit form, if not, renders as the add form. But this doesn't work and it has some wierd behaviour.
Here is the code for the ContactForm
ponent
<template>
<div>
<div class="card mb-3">
<div class="card-header">{{ editing ? 'Edit' : 'Add' }} Contact</div>
<div class="card-body">
<form @submit.prevent="addContact">
<TextInputGroup
label="Name"
name="name"
placeholder="Enter your name..."
v-model="contact.name"
for="name"
/>
<TextInputGroup
type="email"
label="Email"
name="email"
placeholder="Enter your email..."
v-model="contact.email"
/>
<TextInputGroup
type="phone"
label="Phone"
name="phone"
placeholder="Enter your phone number..."
v-model="contact.phone"
/>
<input type="submit" value="Add Contact" class="btn btn-block btn-light" />
</form>
</div>
</div>
</div>
</template>
<script>
import TextInputGroup from "../layout/TextInputGroup";
import { db } from "../../firebase";
export default {
ponents: {
TextInputGroup
},
data() {
return {
contact: "",
editing: false,
email: "",
name: "",
phone: ""
};
},
methods: {
addContact() {
const newContact = {
name: this.name,
email: this.email,
phone: this.phone,
createdAt: new Date()
};
db.collection("contacts")
.add(newContact)
.then(docRef => {
console.log("Document written with ID: ", docRef.id);
})
.catch(error => {
console.error("Error adding document: ", error);
});
this.$router.push("/");
},
getContactById() {
db.collection("contacts")
.doc(this.$route.params.id)
.get()
.then(snapshot => {
if (!snapshot.exists) return;
this.contact = snapshot.data();
});
},
updateContact() {
const newContact = {
name: this.contact.name,
email: this.contact.email,
phone: this.contact.phone
};
db.collection("contacts")
.doc(this.$route.params.id)
.update(newContact)
.then(() => {
console.log("Updated document with ID: ");
})
.catch(function(error) {
console.error("Error updating document: ", error);
});
this.$router.push("/");
}
},
mounted() {
if ("id" in this.$route.params) {
this.getContactById();
this.editing = true;
console.log("id");
} else {
console.log("ups");
// this
}
}
};
</script>
This is the github link and the live app
I'm trying to use the same ponent to handle the Add and Edit part of my app. I'm using Firebase, so I'm checking if there is an id
in the route params, if there is, it renders as the edit form, if not, renders as the add form. But this doesn't work and it has some wierd behaviour.
Here is the code for the ContactForm
ponent
<template>
<div>
<div class="card mb-3">
<div class="card-header">{{ editing ? 'Edit' : 'Add' }} Contact</div>
<div class="card-body">
<form @submit.prevent="addContact">
<TextInputGroup
label="Name"
name="name"
placeholder="Enter your name..."
v-model="contact.name"
for="name"
/>
<TextInputGroup
type="email"
label="Email"
name="email"
placeholder="Enter your email..."
v-model="contact.email"
/>
<TextInputGroup
type="phone"
label="Phone"
name="phone"
placeholder="Enter your phone number..."
v-model="contact.phone"
/>
<input type="submit" value="Add Contact" class="btn btn-block btn-light" />
</form>
</div>
</div>
</div>
</template>
<script>
import TextInputGroup from "../layout/TextInputGroup";
import { db } from "../../firebase";
export default {
ponents: {
TextInputGroup
},
data() {
return {
contact: "",
editing: false,
email: "",
name: "",
phone: ""
};
},
methods: {
addContact() {
const newContact = {
name: this.name,
email: this.email,
phone: this.phone,
createdAt: new Date()
};
db.collection("contacts")
.add(newContact)
.then(docRef => {
console.log("Document written with ID: ", docRef.id);
})
.catch(error => {
console.error("Error adding document: ", error);
});
this.$router.push("/");
},
getContactById() {
db.collection("contacts")
.doc(this.$route.params.id)
.get()
.then(snapshot => {
if (!snapshot.exists) return;
this.contact = snapshot.data();
});
},
updateContact() {
const newContact = {
name: this.contact.name,
email: this.contact.email,
phone: this.contact.phone
};
db.collection("contacts")
.doc(this.$route.params.id)
.update(newContact)
.then(() => {
console.log("Updated document with ID: ");
})
.catch(function(error) {
console.error("Error updating document: ", error);
});
this.$router.push("/");
}
},
mounted() {
if ("id" in this.$route.params) {
this.getContactById();
this.editing = true;
console.log("id");
} else {
console.log("ups");
// this
}
}
};
</script>
This is the github link and the live app
Share Improve this question edited Dec 7, 2020 at 10:16 Serhiy 4,1413 gold badges38 silver badges66 bronze badges asked Oct 24, 2019 at 19:29 PeorayPeoray 1,9253 gold badges15 silver badges24 bronze badges 9- Any error message in the console? – Renaud Tarnec Commented Oct 24, 2019 at 20:02
- no...there is nothing – Peoray Commented Oct 24, 2019 at 20:09
- And what if you only keep the created hook? I don't think it will change anything but just trying anything that can be tried.... – Renaud Tarnec Commented Oct 24, 2019 at 20:10
- I don't understand, can you explain further? – Peoray Commented Oct 24, 2019 at 20:13
- You are sure there is data in your contact collection and there is no security rule that prevent reading the data? – Renaud Tarnec Commented Oct 24, 2019 at 20:13
1 Answer
Reset to default 5I just cloned you repository and tested in local, Added fixes to use single form for editing and adding
Here is the code for following files, just copy paste this code in below mentioned files
src/ponents/contact/ContactForm.vue
<template>
<div>
<div class="card mb-3">
<div class="card-header">{{ editing ? 'Edit' : 'Add' }} Contact</div>
<div class="card-body">
<form @submit.prevent="addContact">
<TextInputGroup
label="Name"
name="name"
placeholder="Enter your name..."
v-model="contact.name"
for="name"
/>
<TextInputGroup
type="email"
label="Email"
name="email"
placeholder="Enter your email..."
v-model="contact.email"
/>
<TextInputGroup
type="phone"
label="Phone"
name="phone"
placeholder="Enter your phone number..."
v-model="contact.phone"
/>
<input type="submit" value="Add Contact" class="btn btn-block btn-light" />
</form>
</div>
</div>
</div>
</template>
<script>
import TextInputGroup from "../layout/TextInputGroup";
import { db } from "../../firebase";
var temp = Object.freeze({
name: '',
email: '',
phone: '',
});
export default {
ponents: {
TextInputGroup
},
props: {
type: {
type: String,
default: '',
},
},
data() {
return {
contact: Object.assign({}, temp),
editing: false,
};
},
methods: {
addContact() {
this.contact.createdAt = new Date();
db.collection("contacts")
.add(this.contact)
.then(docRef => {
console.log("Document written with ID: ", docRef.id);
})
.catch(error => {
console.error("Error adding document: ", error);
});
this.$router.push("/");
},
getContactById() {
db.collection("contacts")
.doc(this.$route.params.id)
.get()
.then(snapshot => {
if (!snapshot.exists) return;
this.contact = snapshot.data();
});
},
updateContact() {
db.collection("contacts")
.doc(this.$route.params.id)
.update(this.contact)
.then(() => {
console.log("Updated document with ID: ");
})
.catch(function(error) {
console.error("Error updating document: ", error);
});
this.$router.push("/");
}
},
created() {
if ("id" in this.$route.params) {
this.getContactById();
this.editing = true;
console.log("id");
} else {
console.log("ups");
// this
}
},
watch: {
type(val) {
if (val == 'add') {
this.contact = Object.assign({}, temp);
}
}
}
};
</script>
src/ponents/contact/ContactItem.vue
<template>
<div>
<div class="card card-body mb-3">
<h4>
{{ contact.name }}
<i
class="fas fa-sort-down pointer"
@click="showContactInfo = !showContactInfo"
></i>
<i class="fas fa-times delete right delete" @click="deleteContact(contact.id)"></i>
<router-link :to="{path: `contact/edit/${contact.id}`, params: { id: contact.id }, query: { type: 'edit' }}">
<i class="fas fa-pencil-alt edit right"></i>
</router-link>
</h4>
<ul class="list-group" v-if="showContactInfo">
<li class="list-group-item">Email: {{ contact.email }}</li>
<li class="list-group-item">Phone: {{ contact.phone }}</li>
</ul>
</div>
</div>
</template>
<script>
import { db } from "../../firebase";
export default {
props: {
contact: {
type: Object,
required: true
}
},
data() {
return {
showContactInfo: false
};
},
methods: {
deleteContact(id) {
db.collection("contacts")
.doc(id)
.delete()
.then(function() {
console.log("Document successfully deleted!");
})
.catch(function(error) {
console.error("Error removing document: ", error);
});
}
}
};
</script>
<style scoped>
.pointer {
cursor: pointer;
}
.right {
cursor: pointer;
float: right;
}
.edit {
color: black;
margin-right: 1rem;
}
.delete {
color: red;
}
</style>
src/ponents/layout/Navbar.vue
<template>
<div>
<nav class="navbar navbar-expand-sm navbar-dark bg-danger mb-3 py-0">
<div class="container">
<a href="/" class="navbar-brand">Contact Manager</a>
<div>
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<router-link to="/" class="nav-link">
<i class="fas fa-home" />
Home
</router-link>
</li>
<li class="nav-item">
<router-link :to="{ path: '/contact/add', query: { type: 'add' } }" class="nav-link">
<i class="fas fa-plus" />
Add
</router-link>
</li>
<li class="nav-item">
<router-link to="/about" class="nav-link">
<i class="fas fa-question" />
About
</router-link>
</li>
</ul>
</div>
</div>
</nav>
</div>
</template>
src/views/ContactForm.vue
<template>
<ContactForm :type="formType" />
</template>
<script>
// @ is an alias to /src
import ContactForm from "@/ponents/contact/ContactForm.vue";
export default {
name: "home",
data() {
return {
formType: '',
};
},
ponents: {
ContactForm
},
watch: {
'$route.query.type': {
handler: function(type) {
this.formType = type;
},
deep: true,
immediate: true
}
}
};
</script>
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742345987a4426551.html
评论列表(0条)