Vuejs - 如何使用单个表单添加和编辑
Posted
技术标签:
【中文标题】Vuejs - 如何使用单个表单添加和编辑【英文标题】:Vuejs - How to use a single form to add and edit 【发布时间】:2020-02-21 04:28:15 【问题描述】:我正在尝试使用相同的组件来处理我的应用程序的添加和编辑部分。我正在使用 Firebase,所以我正在检查路由参数中是否有 id
,如果有,它将呈现为编辑表单,如果没有,则呈现为添加表单。但这不起作用,而且有一些奇怪的行为。
这是ContactForm
组件的代码
<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
components:
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>
这是github link 和live app
【问题讨论】:
控制台中有错误信息吗? 不...什么都没有 如果你只保留创建的钩子呢?我认为它不会改变任何东西,只是尝试任何可以尝试的东西...... 我不明白,你能解释一下吗? 您确定您的联系人集合中有数据并且没有阻止读取数据的安全规则? 【参考方案1】:我刚刚克隆了您的存储库并在本地进行了测试,添加了修复以使用单一表单进行编辑和添加
这是以下文件的代码,只需将此代码复制粘贴到以下文件中
src/components/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
components:
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/components/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/components/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 "@/components/contact/ContactForm.vue";
export default
name: "home",
data()
return
formType: '',
;
,
components:
ContactForm
,
watch:
'$route.query.type':
handler: function(type)
this.formType = type;
,
deep: true,
immediate: true
;
</script>
【讨论】:
感谢您抽出宝贵时间提供帮助。你能解释一下你的代码吗?我不想只是复制和粘贴:) 是的,当你想添加一个新联系人时,this.contact 在创建时会有一个空表单,但是当你有一个 id 时,这意味着编辑,你会得到你的 this.contact 预填充基于 id 的联系人。以前,您在此组件中全局拥有姓名、电子邮件、电话,而不是仅依赖 this.contact。现在我已经重构为 add 和 edit 共享此表单。您还有其他说明吗? ,如果不接受并赞成这个答案 另外,问题似乎仍然存在。尝试单击编辑图标使表单显示为编辑模式,然后尝试单击导航栏中的 添加 链接,您会注意到尽管 URL 已更改,但仍处于编辑模式 我理解你的解释,但这并不能解决问题。虽然它之前工作过,但当我点击主页上的 编辑图标 时,我的表单会被预先填写。主要问题是获得正确的表单以正确呈现如上所述 这就是你写的逻辑,添加 else 块,如果没有 id 存在,它应该重置 this.contact 对象以上是关于Vuejs - 如何使用单个表单添加和编辑的主要内容,如果未能解决你的问题,请参考以下文章
如何在 VueJS 文件中添加 Laravel CSRF 令牌? [复制]