开门见山⛰
.sync就是一个语法糖。为父组件监听子组件更新某个
props
的请求这种特定的模式提供了缩写语法。
单向绑定的限制
- Vue中的
props
是单向向下绑定的,也就是说,每次父组件更新时,子组件中的所有props
都会刷新为最新的值,反过来却不行。 - 但是如果尝试在子组件中修改
props
呢?如果你这样做了,Vue会向你发出一个警告。 - 一种更好的解决办法是,子组件在希望修改
props
时,触发一个事件通知父组件去修改,父组件收到事件后会修改对应的数据,这样由于props
的特性,子组件中的数据也会相应的自动更新。 - Talk is cheap, show me the code.
- 我们实现了一个「用不同语言打招呼」的小功能:
父组件(Hello.vue):
<template>
<div id="hello">
<div>{{ hello }}</div>
<hr>
<Change :length="languages.length" :language="language" :current="current" v-on:update:current="current=$event"/>
</div>
</template>
<script>
import Change from "@/components/Change";
export default {
name: "Hello",
data() {
return {
languages: [
{'英语': 'Hello'},
{'中文': '你好'},
{'西班牙语': 'Hola'},
{'韩语': '안녕하세요'},
{'法语': 'Sulut'},
{'意大利语': 'Ciao'},
{'阿拉伯语': 'هتاف للترحيب, أهل'},
{'日语': 'こんにちは'}
],
current: 0
}
},
computed: {
hello() {
return Object.values(this.languages[this.current])[0]
},
language() {
return Object.keys(this.languages[this.current])[0]
}
},
components: {
Change: Change
}
}
</script>
子组件(Change.vue):
<template>
<div id="change">
<span>当前语言:{{ language }} </span>
<button @click="$emit('update:current', Math.floor(Math.random() * (length - 1)))"><span>更换语言</span></button>
</div>
</template>
<script>
export default {
name: "Change",
props: ["language", "current", "length"]
}
</script>
当点击子组件中的按钮,会触发
update:language
事件,父组件收到这个事件会执行对应的操作,也就是将current
的值更新。
使用.sync修饰符
对于上面父组件代码中的下面这一段👇
<Change :length="languages.length" :language="language" :current="current" v-on:update:current="current=$event"/>
其中下面这部分,表示如果子组件触发了一个
update:current
事件想修改current
的值,父组件会收到消息并修改自己的current
的值。<Change :current="current" v-on:update:current="current=$event"/>
我们可以用
.sync
修饰符简写为:<Change :current.sync="current">
也就是说,
.sync
相当于一个语法糖,提供了一套父组件监听子组件更新某个props的请求这种模式的缩写形式。