关于.sync
在了解这个语法糖时,首先我们要了解的是vue组件之间的通信规则是单向数据流即:
vuet提倡单向数据流,即父级 props 的更新会流向子组件,但是反过来则不行。这是为了防止意外的改变父组件状态,使得应用的数据流变得难以理解。如果破坏了单向数据流,当应用复杂时,debug 的成本会非常高。
我们一般的做法是:
//父组件
<template>
<right-toolbar :show-search="showSearch" @targger="reverseTem"></right-toolbar>
</template>
<script>
import rightToolbar from "@/comoinents/rightToolbar";
export default {
name: 'Parent',
components: {
rightToolbar
},
data() {
return {
showSearch: true,
};
},
methods: {
reverseTem(){
this.showSearch = !this.showSearch
},
}
};
</script>
//子组件
<template>
<div>
<div v-show="showSearch">我是显示隐藏控件</div>
<button @click="handleBtnClick">按钮</button>
</div>
</template>
<script>
export default {
name: 'children',
props{
showSearch(){
type:Boolean,
default:true
}
},
methods: {
handleBtnClick(){
this.$emit('targger')
}
}
};
</script>
上面我们就能够实现控制组件中元素单元的显示与隐藏功能了,但是这样写给人的感觉就是非常的繁琐,还很绕所以:
.sync 修饰符
在有些情况下,我们可能需要对一个 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>
引申到我们的示例中:
//父组件
<template>
<right-toolbar :showSearch.sync="showSearch"></right-toolbar>
</template>
<script>
import rightToolbar from "@/comoinents/rightToolbar";
export default {
name: 'Parent',
components: {
rightToolbar
},
data() {
return {
showSearch: true,
};
}
};
</script>
//子组件
<template>
<div>
<div v-show="showSearch">我是显示隐藏控件</div>
<button @click="handleBtnClick">按钮</button>
</div>
</template>
<script>
export default {
name: 'children',
props{
showSearch(){
type:Boolean,
default:true
}
},
methods: {
handleBtnClick(){
this.$emit('update:showSearch',!this.showSearch)
}
}
};
</script>
注意: 必须要使用update:myPropName的形式添加自定义事件