复习之用v-bind 指令的修饰符.sync实现双向数据绑定 - 知乎
除了使用 v-model 指令实现组件与外部数据的双向绑定外,我们还可以用 v-bind 指令的修饰符 .sync 来实现。
那么,该如何实现呢?
先回忆一下,不利用 v-model 指令来实现组件的双向数据绑定:
html
<div id="app">
<!-- 双向数据绑定,手动绑定 -->
<base-input
:value="name"
@input="name = $event"
>
</div>
<script>
Vue.component('base-input', {
props: {
value: String
},
template: `
<label>
姓名:
<input type="text" :value="value"
@input="$emit('input', $event.target.value)"/>
</label>
`
})
const vm = new Vue({
el: "#app",
data: {
name: 'hello'
}
})
</script>
那么,我们也可以试着,将监听的事件名进行更改,如:
html
<div id="app">
<!-- 双向数据绑定,手动绑定 -->
<base-input
:value="name"
@update:value="name = $event"
>
</div>
<script>
Vue.component('base-input', {
props: {
value: String
},
template: `
<label>
姓名:
<input type="text" :value="value"
@input="$emit('update:value', $event.target.value)"/>
</label>
`
})
const vm = new Vue({
el: "#app",
data: {
name: 'hello'
}
})
</script>
这样也是可以实现双向数据绑定的。
那么和 .sync 修饰符 有什么关系呢?
此时,我们对代码进行修改:
html
<div id="app">
<!-- 双向数据绑定,手动绑定 -->
<base-input
:value.sync="name"
>
</div>
<script>
Vue.component('base-input', {
props: {
value: String
},
template: `
<label>
姓名:
<input type="text" :value="value"
@input="$emit('update:value', $event.target.value)"/>
</label>
`
})
const vm = new Vue({
el: "#app",
data: {
name: 'hello'
}
})
</script>
所以,.sync 修饰符 本质上也是一个语法糖,在组件上使用:
html
<base-input :value.sync="name"></base-input>
等价于:
html
<base-input
:value="name"
@update:value="name = $event"
/>
当我们用一个对象同时设置多个prop时,也可以将.sync修饰符和 v-bind配合使用:
html
<base-input v-bind.sync="obj"></base-input>
注意:
带有.sync修饰符的v-bind指令,只能提供想要绑定的属性名,****不能****和表达式一起使用,如:``:title.sync="1+1"``,这样操作是无效的。
将 ``v-bind.sync`` 用在 一个字面量对象上,如 ``v-bind.sync="{ title: 'haha' }"``,是无法工作的,因为在解析一个像这样的复杂表达式的时候,有很多边缘情况需要考虑。
v-model 与 .sync 的区别?
先明确一件事情,在 vue 1.x 时,就已经支持 .sync 语法,但是此时的 .sync 可以完全在子组件中修改父组件的状态,造成整个状态的变换很难追溯,所以官方在2.0时移除了这个特性。然后在 vue2.3时,.sync又回归了,跟以往不同的是,现在的.sync完完全全就是一个语法糖的作用,跟v-model的实现原理是一样的,也不容易破环院有的数据模型,所以使用上更安全也更方便。
- 两者都是用于实现双向数据传递的,实现方式都是语法糖,最终通过 ``prop`` + ``事件`` 来达成目的。
- vue 1.x 的 .sync 和 v-model 是完全两个东西,vue 2.3 之后可以理解为一类特性,使用场景略微有区别。
- 当一个组件对外只暴露一个受控的状态,并且都符合统一标准的时候,我们会使用v-model来处理。.sync则更为灵活,凡是需要双向数据传递时,都可以去使用。