如果你使用过 Vue.js 1.x,一定对 .sync
不陌生。在 1.x 里,可以使用 .sync 双向绑定数据,也就是父组件或子组件都能修改这个数据,是双向响应的。在 Vue.js 2.x 里废弃了这种用法,目的是尽可能将父子组件解耦,避免子组件无意中修改了父组件的状态。
不过在 Vue.js 2.3.0 版本,又增加了 .sync
修饰符,但它的用法与 1.x 的不完全相同。2.x 的 .sync 不是真正的双向绑定,而是一个语法糖,修改数据还是在父组件完成的,并非在子组件。
仍然是数字选择器的示例,这次不用 v-model,而是用 .sync,可以这样改写:
<template>
<div>
<button @click="increase(-1)">减 1</button>
<span style="color: red;padding: 6px">{{ value }}</span>
<button @click="increase(1)">加 1</button>
</div>
</template>
<script>
export default {
name: 'InputNumber',
props: {
value: {
type: Number
}
},
methods: {
increase (val) {
this.$emit('update:value', this.value + val);
}
}
}
</script>
用例:
<template>
<InputNumber :value.sync="value" />
</template>
<script>
import InputNumber from '../components/input-number/input-number.vue';
export default {
components: { InputNumber },
data () {
return {
value: 1
}
}
}
</script>
看起来要比 v-model 的实现简单多,实现的效果是一样的。v-model 在一个组件中只能有一个,但 .sync 可以设置很多个。.sync 虽好,但也有限制,比如:
- 不能和表达式一起使用(如
v-bind:title.sync="doc.title + '!'"
是无效的); - 不能用在字面量对象上(如
v-bind.sync="{ title: doc.title }"
是无法正常工作的)。