一个组件上只能定义一个v-model,如果其余prop也要实现双向绑定的成果该怎么办呢? 简略的办法是子组件向父组件发射一个事件,父组件监听该事件,而后更新prop。具体如下:
<template> <!-- info.vue组件定义了一个value 属性, 和一个valueChanged事件 --> <div> <input @input="onInput" :value="value" /> </div></template><script>export default { props: { value: { type: String, default: "" } }, data() { return {}; }, methods: { onInput(e) { // 形式1 this.$emit("valueChanged", e.target.value); // 形式2 this.$emit("update:value", e.target.value); // 多个prop都要实现双向绑定、简化版本 this.$emit("update:a", e.target.value); this.$emit("update:c", e.target.value); } }};</script>
父组件index.vue
<template><div> <!-- 父子组件间双向数据绑定 --> <h3>形式1: 传统形式</h3> <info :value="myValue" @valueChanged="change"></info> <p>{{ myValue }}</p></div> </template> <script>import info from "./sub_index_6/info.vue";export default { components: { info }, data() { return { // 形式1 传统形式 myValue: "1234", }; }, methods: { // 形式1 传统形式 change(e) { this.myValue = e; } }};</script>
上述写法太麻烦了,通过.sync能够简化下面代码,只须要修两个中央:
- 组件内触发的事件名称以“update:myPropName”命名,相应的上述info组件改为 update:value
- 父组件v-bind:value 加上.sync修饰符,即 v-bind:value.sync
这样父组件就不必再手动绑定@update:value事件了。
用法1: v-bind:prop.sync="propvalue"
// info.vue组件 ... methods: { onInput(e) { // 形式2 this.$emit("update:value", e.target.value); } }
父组件
<h3>形式2: .sync</h3> <info :value.sync="myValue2"></info> <p>{{ myValue2 }}</p> ...data(){ return { // 形式2 .sync myValue2: "5678", } }
用法2 v-bind.sync="obj"
如果一个组件的多个prop都要实现双向绑定,依据下面学到的常识,只须要每个prop加sync修饰符
<template> <!-- info.vue组件定义了一个value 属性, 和一个valueChanged事件 --> <div> <input @input="onInput" :value="value" /> </div></template><script>export default { props: { value: { type: String, default: "" }, a: { type: String, default: "" }, b: { type: String, default: "" }, c: { type: String, default: "" }, d: { type: String, default: "" } }, data() { return {}; }, methods: { onInput(e) { // 多个prop都要实现双向绑定、简化版本 this.$emit("update:a", e.target.value); this.$emit("update:c", e.target.value); } }};</script>
父组件
<h4>多个prop都要实现双向绑定</h4> <info :a.sync="value1" :b.sync="value2" :c.sync="value3" :d.sync="value4" ></info> <p>{{ value1 }} -- {{ value2 }} -- {{ value3 }} -- {{ value4 }}</p> ...data(){ return { // 多个prop都要实现双向绑定 value1: "1", value2: "2", value3: "3", value4: "4", } }
这样写太麻烦,vue提供了一种更简便的办法, v-bind.sync = "对象"
残缺代码
父组件
<template><div> <!-- 父子组件间双向数据绑定 --> <h3>形式1: 传统形式</h3> <info :value="myValue" @valueChanged="change"></info> <p>{{ myValue }}</p> <hr /> <h3>形式2: .sync</h3> <info :value.sync="myValue2"></info> <p>{{ myValue2 }}</p> <h4>多个prop都要实现双向绑定</h4> <info :a.sync="value1" :b.sync="value2" :c.sync="value3" :d.sync="value4" ></info> <p>{{ value1 }} -- {{ value2 }} -- {{ value3 }} -- {{ value4 }}</p> <h4>简化版本</h4> <info v-bind.sync="obj"></info> <p>{{ obj.a }} -- {{ obj.b }} -- {{ obj.c }} -- {{ obj.d }}</p></div></template><script>import info from "./sub_index_6/info.vue";export default { components: { info }, data() { return { // 形式1 传统形式 myValue: "1234", // 形式2 .sync myValue2: "5678", // 多个prop都要实现双向绑定 value1: "1", value2: "2", value3: "3", value4: "4", // 简化版本 obj: { a: "1", b: "2", c: "3", d: "4" } }; }, methods: { // 形式1 传统形式 change(e) { this.myValue = e; } }};</script>
子组件
<template> <!-- info.vue组件定义了一个value 属性, 和一个valueChanged事件 --><div> <input @input="onInput" :value="value" /></div></template><script>export default { props: { value: { type: String, default: "" }, a: { type: String, default: "" }, b: { type: String, default: "" }, c: { type: String, default: "" }, d: { type: String, default: "" }},data() { return {};},methods: { onInput(e) { // 形式1 this.$emit("valueChanged", e.target.value); // 形式2 this.$emit("update:value", e.target.value); // 多个prop都要实现双向绑定、简化版本 this.$emit("update:a", e.target.value); this.$emit("update:c", e.target.value); }}};</script>
效果图
留神:
带有.sync修饰符的v-bind不能喝表达式一起应用(例如 v-bind:title.sync = "doc.title + '!'"是有效的)。取而代之的是,你只能绑定你想要绑定的属性名。
小结
一个组件须要提供多个双向绑定的属性时应用,只能选用一个属性来提供 v-model 性能,但如果有其余属性也要提供双向绑定,就须要.sync