一个组件上只能定义一个 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