完整示例理解vue的.sync修饰符

3,376 阅读2分钟

关于 vue 的 .sync 修饰符,许多小伙伴看了官方文档:vue .sync 修饰符之后,还是无法完全理解,本文先介绍一下 .sync 的历史,再用一个完整的示例帮助大家理解。

vue .sync的历史

vue .sync 修饰符最初存在于 vue 1.0 版本里,但是在 2.0 中被移除了。但是在 2.0 发布之后的实际应用中,vue 官方发现 .sync 还是有其适用之处,比如在开发可复用的组件库时。开发者需要做的只是让子组件改变父组件状态的代码更容易被区分。从 2.3.0 起官方重新引入了 .sync 修饰符,但是这次它只是作为一个编译时的语法糖存在。它会被扩展为一个自动更新父组件属性的 v-on 监听器。

完整示例

假设这么一个场景:假设小明的父亲有1000块钱,小明一次花掉100元,就是点击一次花钱按钮父亲的钱减少100。

不用.sync修饰符

让我们先不用.sync修饰符来实现这个简单需求,

父亲组件

<template>
  <div class="app">
    小明的爸爸现在有 {{ total }} 元
    <hr>
    <Child :money="total" v-on:update:money="total = $event"/>
  </div>
</template>

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

<style>
.app {
  padding: 10px;
}
</style>

小明组件

<template>
  <div class="child">
    <span>小明每次花100元</span>
    <button @click="$emit('update:money', money - 100)">花钱</button>
    爸爸还剩 {{money}} 元
  </div>
</template>

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

<style>
button {
  margin: 0 10px;
}
</style>

main.js

import Vue from "vue";
import App from "./App.vue";

Vue.config.productionTip = false;

new Vue({
  render: h => h(App)
}).$mount("#app");

结果如下图,点击一次花钱,减少100元,因为emit()的第二个参数money - 100会被赋给$event,所以可以实现子组件更新父组件的数据。

使用.sync

让我们给小明爸爸加入.sync,

<template>
  <div class="app">
    小明的爸爸现在有 {{ total }} 元
    <hr>
    <Child :money.sync="total"/>
  </div>
</template>

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

<style>
.app {
  padding: 10px;
}
</style>

小明花钱爸爸口袋里的钱同样减少了!

.sync 为什么这么香?

因为<Child :money.sync="total"/>这一句,其实经过vue的编译,变成了<Child :money="total" v-on:update:money="total = $event"/>,vue的编译器会把子组件$emit('update:money', money - 100)的第二个参数自动地绑定到父组件.sync修饰的变量上。

这就是一个vue的语法糖,而我更愿意把它叫做vue的一个隐藏技能,会用的人可以节省很多代码,使代码看起来更简洁。

编程语言的隐藏技能其实有很多,最典型就是python的lambda表达式, 有时候我们花时间学一些编程语言的语法糖,最终会发现,整体效率其实是上升的,这也印证了那句古话,磨刀不误砍柴工嘛!