开门见山⛰

.sync就是一个语法糖。为父组件监听子组件更新某个props的请求这种特定的模式提供了缩写语法

单向绑定的限制

  • Vue中的 props 是单向向下绑定的,也就是说,每次父组件更新时,子组件中的所有 props 都会刷新为最新的值,反过来却不行。
  • 但是如果尝试在子组件中修改 props 呢?如果你这样做了,Vue会向你发出一个警告。
  • 一种更好的解决办法是,子组件在希望修改 props 时,触发一个事件通知父组件去修改,父组件收到事件后会修改对应的数据,这样由于 props 的特性,子组件中的数据也会相应的自动更新。
  • Talk is cheap, show me the code.
  • 我们实现了一个「用不同语言打招呼」的小功能:

changeLanguage.gif

  • 父组件(Hello.vue):

    1. <template>
    2. <div id="hello">
    3. <div>{{ hello }}</div>
    4. <hr>
    5. <Change :length="languages.length" :language="language" :current="current" v-on:update:current="current=$event"/>
    6. </div>
    7. </template>
    1. <script>
    2. import Change from "@/components/Change";
    3. export default {
    4. name: "Hello",
    5. data() {
    6. return {
    7. languages: [
    8. {'英语': 'Hello'},
    9. {'中文': '你好'},
    10. {'西班牙语': 'Hola'},
    11. {'韩语': '안녕하세요'},
    12. {'法语': 'Sulut'},
    13. {'意大利语': 'Ciao'},
    14. {'阿拉伯语': '‏هتاف للترحيب, ‏أهل'},
    15. {'日语': 'こんにちは'}
    16. ],
    17. current: 0
    18. }
    19. },
    20. computed: {
    21. hello() {
    22. return Object.values(this.languages[this.current])[0]
    23. },
    24. language() {
    25. return Object.keys(this.languages[this.current])[0]
    26. }
    27. },
    28. components: {
    29. Change: Change
    30. }
    31. }
    32. </script>
  • 子组件(Change.vue):

    1. <template>
    2. <div id="change">
    3. <span>当前语言:{{ language }} </span>
    4. <button @click="$emit('update:current', Math.floor(Math.random() * (length - 1)))"><span>更换语言</span></button>
    5. </div>
    6. </template>
    1. <script>
    2. export default {
    3. name: "Change",
    4. props: ["language", "current", "length"]
    5. }
    6. </script>
  • 当点击子组件中的按钮,会触发 update:language 事件,父组件收到这个事件会执行对应的操作,也就是将 current 的值更新。

使用.sync修饰符

  • 对于上面父组件代码中的下面这一段👇

    1. <Change :length="languages.length" :language="language" :current="current" v-on:update:current="current=$event"/>
  • 其中下面这部分,表示如果子组件触发了一个 update:current 事件想修改 current 的值,父组件会收到消息并修改自己的 current 的值。

    1. <Change :current="current" v-on:update:current="current=$event"/>
  • 我们可以用 .sync 修饰符简写为:

    1. <Change :current.sync="current">
  • 也就是说,.sync 相当于一个语法糖,提供了一套父组件监听子组件更新某个props的请求这种模式的缩写形式。