如果你使用过 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,可以这样改写:

    1. <template>
    2. <div>
    3. <button @click="increase(-1)">减 1</button>
    4. <span style="color: red;padding: 6px">{{ value }}</span>
    5. <button @click="increase(1)">加 1</button>
    6. </div>
    7. </template>
    8. <script>
    9. export default {
    10. name: 'InputNumber',
    11. props: {
    12. value: {
    13. type: Number
    14. }
    15. },
    16. methods: {
    17. increase (val) {
    18. this.$emit('update:value', this.value + val);
    19. }
    20. }
    21. }
    22. </script>

    用例:

    1. <template>
    2. <InputNumber :value.sync="value" />
    3. </template>
    4. <script>
    5. import InputNumber from '../components/input-number/input-number.vue';
    6. export default {
    7. components: { InputNumber },
    8. data () {
    9. return {
    10. value: 1
    11. }
    12. }
    13. }
    14. </script>

    看起来要比 v-model 的实现简单多,实现的效果是一样的。v-model 在一个组件中只能有一个,但 .sync 可以设置很多个。.sync 虽好,但也有限制,比如:

    • 不能和表达式一起使用(如 v-bind:title.sync="doc.title + '!'" 是无效的);
    • 不能用在字面量对象上(如 v-bind.sync="{ title: doc.title }" 是无法正常工作的)。