Vue的.sync修饰符是个啥?

197 阅读2分钟

举个例子

又到了我最喜欢的举例子环节

一个场景:

像大多数学生,还没有经济独立,要花钱咋办?

那还不简单,找他爸啊,

他爸已经准备好了10000块,用于给儿花销,

但是怕儿子一下子把钱全花光了,于是没有直接给儿子,

儿子每次用钱时,就告诉他爸(触发事件),向他爸要钱,花多少,给多少

以下是非完整版的Vue

//App.vue
<template>
  <div class="app">
    App.vue 我现在有 {{total}}
    <hr>
    <Child />
  </div>
</template>

<script>
import Child from "./Child.vue";
export default {
  data() {
    return { total: 10000 };
  },
  components: { Child: Child }
};
</script>

<style>
.app {
  border: 3px solid red;
  padding: 10px;
}
</style>

APP.vue里有一个子组件,来自于Child.vue(下方代码),

这里data里面写入10000,告诉Child,咱家就只能给你花这么多钱,多的没有~

于是,在<child />里写入

//App.vue
<child:money="total">

Child接受这个信息

//Child.vue
<template>
  <div class="child">
    {{money}}
    <button @click=" ">
      <span>花钱</span>
    </button>
  </div>
</template>

<script>
export default {
  props: ["money"]
};
</script>


<style>
.child {
  border: 3px solid green;
}
</style>

把10000,显示在了{{money}}

QQ图片20220108212644

并且儿子有一个按钮,每一次点击,就会花100块

按照这个需求,我们新手可能会这样写

//Child.vue
<button @click="money -= 100">

但这样按钮是不生效的,因为不能直接更改外部的数据props,(钱在你爸手上,你怎么能直接花呢?)

所以,儿子要老老实实地找他爸要(触发update:money事件)

//Child.vue
 <button @click="$emit('update:money', money-100)">

他爸就要监听他的儿子要不要花钱

//App.vue
<Child :money="total" v-on:update:money="total = $event"/>

他爸发现了update:money事件被触发后,就会把儿子传过来的参数(money-100),通过$event拿到,从而改变剩余钱的值

花钱

sync

上述例子是Vue中经常遇到的一个场景:

  • 我把一个数据给你
  • 你要改的话,你得通知我,你不能自己改
  • 这是Vue规定的

但像上面一样写,是不是有点繁琐?

于是Vue把它封装了一下

//App.vue
<Child :money.sync="total"/>

它的含义就与<Child :money="total" v-on:update:money="total = $event"/>相同,所以实现的功能也相同。

这就是.sync的作用

总结

  • Vue规则:组件不能修改props外部数据
  • Vue规则:$emit可以触发事件,并传参
  • Vue规则:$event可以获取$emit的参数

由于把这些规则结合起来的场景太常见,于是尤雨溪发明了.sync

Vue 修饰符.sync的功能:当一个子组件改变了一个 props 的值时,这个变化也会同步到父组件中所绑定。这时使用.sync可以使我们的代码更加简洁

.sync这种写法就叫做语法糖

补充

Vue3 推荐使用 v-model 替代 sync