.sync修饰符
.sync修饰符可以实现子组件与父组件的双向绑定,并且可以实现子组件同步修改父组件的值。
一般情况下,想要实现父子组件间值的传递,通常使用的是props和自定义事件emit。其中,父组件通过props将值传给子组件,子组件再通过emit将值传给父组件,父组件通过事件监听获取子组件传过来的值。如果想要简化这里的代码,可以使用.sync修饰符,实际上就是一个语法糖。
理解.sync
首先看一下官方文档的介绍
2.3.0+ 新增
在有些情况下,我们可能需要对一个 prop 进行“双向绑定”。不幸的是,真正的双向绑定会带来维护上的问题,因为子组件可以变更父组件,且在父组件和子组件都没有明显的变更来源。
这也是为什么我们推荐以update:myPropName的模式触发事件取而代之。举个例子,在一个包含titleprop 的假设的组件中,我们可以用以下方法表达对其赋新值的意图:
this.$emit('update:title', newTitle)
然后父组件可以监听那个事件并根据需要更新一个本地的数据 property。例如:
<text-document
v-bind:title="doc.title"
v-on:update:title="doc.title = $event"
></text-document>
为了方便起见,我们为这种模式提供一个缩写,即
.sync修饰符:
<text-document v-bind:title.sync="doc.title"></text-document>
根据生活场景理解.sync
场景描述
- 爸爸手里钱,儿子要花钱怎么办
- 儿子是不是要爸爸,给我点钱用用吧
- 然后爸爸给了儿子钱用
很简单的场景,但是我们要明确一点,钱的所有权还是在爸爸那里的,儿子只是有使用权
我们用代码来实现以下这个场景吧
爸爸组件
<template>
<div id="app">
爸爸现在有{{total}}块钱
<hr>
<Child :money='total'/>
</div>
</template>
<script>
export default {
data(){ total:10000
}
}
</script>
total为现在爸爸有的钱,爸爸将钱作为money传给了儿子
儿子组件,假如儿子拿到了钱就开花,也不通知爸爸一声
<template>
<div class="child">
{{money}}
<button @click='money-=100'></button>
<span>花钱</span>
</div>
</template>
<script>
export default {
props:['money']
}
</script>
此时就会出现报错
儿子要花钱,得通知爸爸
所以要改为,其中update:money是vue推荐的写法,将这个事件和结果传给父组件
<button @click='$emit('update:money',money-100)'></button>
父组件中接收事件 爸爸监听了儿子要不要花钱,使用$event就能知道子组件传的值
<Child :money='total' v-on:update:money='total=$event'/>
但是这样写好长啊
所以vue提供了一个修饰符.sync来进行缩写
整个v-on:update:money='total=$event'变成了.sync
<Child :money.sync='total'/>
总结:
组件不能修改
props外部数据
this.$emit可以触发事件,并传参
$event可以获取$emit的参数
.sync的用处就是,当一个子组件改变了一个prop的值时,这个变化也会同步到父组件中所绑定,由于使用了事件监听,导致实现起来比较长,所以通过.sync达到简化代码的目的。
.sync是语法糖。vue 修饰符sync的功能是:当一个子组件改变了一个 prop 的值时,这个变化也会同步到父组件中所绑定。如果我们不用.sync,我们想做上面的那个弹窗功能,我们也可以props传初始值,然后事件监听,实现起来也不算复杂。这里用sync实现,只是给大家提供一个思路,让其明白他的实现原理,可能有其它复杂的功能适用sync。