一个组件上只能定义一个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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。