Vue中.sync的作用

184 阅读3分钟

.sync修饰符

.sync修饰符可以实现子组件与父组件的双向绑定,并且可以实现子组件同步修改父组件的值。

一般情况下,想要实现父子组件间值的传递,通常使用的是props和自定义事件emit。其中,父组件通过props将值传给子组件,子组件再通过emit将值传给父组件,父组件通过事件监听获取子组件传过来的值。如果想要简化这里的代码,可以使用.sync修饰符,实际上就是一个语法糖。

理解.sync

首先看一下官方文档的介绍

2.3.0+ 新增
在有些情况下,我们可能需要对一个 prop 进行“双向绑定”。不幸的是,真正的双向绑定会带来维护上的问题,因为子组件可以变更父组件,且在父组件和子组件都没有明显的变更来源。
这也是为什么我们推荐以 update:myPropName 的模式触发事件取而代之。举个例子,在一个包含 title prop 的假设的组件中,我们可以用以下方法表达对其赋新值的意图:

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。