sync修饰符是一个语法糖,类似v-model,它主要是解决了父子组件的双向绑定问题。因为vue提倡的是单向数据流动,因此不能直接在子组件里面修改父组件传过来的数据,因此我们必须这么写:
<template>
<div id="app">
<button @click="visible=true">显示</button>
<my-alert :visible="visible" @close="closeAlert"></my-alert>
</div>
</template>
<script>
import myalert from './components/myalert'
export default {
name: 'App',
components:{'my-alert': myalert},
data(){
return {
visible:false
}
},
methods:{
closeAlert(value){
this.visible = value
}
}
}
</script>
myalert.vue:
<template>
<div class="cont" v-show="visible">
<h2>这是一个对话框</h2>
<button @click="closeAlert">关闭</button>
</div>
</template>
<script>
export default {
name: "myalert",
props:{
visible:{
type:Boolean,
default:false
}
},
methods:{
closeAlert(){
this.$emit('close',false)
}
}
}
</script>
<style scoped>
.cont{
width:500px;
height:200px;
border:1px solid #ccc;
margin:50px auto;
text-align: center;
}
</style>
一个数据就要带一个自定义事件才能实现双向绑定,为了避免乱起名引起的混乱,事件名我们最好约定一下规则。
因为是修改visible这个数据,因此事件我们统一就叫@update:visible
<template>
<div id="app">
<button @click="visible=true">点击</button>
<my-alert :visible="visible" @update:visible="value => visible=value"></my-alert>
</div>
</template>
<script>
import myalert from './components/myalert'
export default {
name: 'App',
components:{'my-alert': myalert},
data(){
return {
visible:false
}
}
}
</script>
myalert.vue:
<template>
<div class="cont" v-show="visible">
<h2>这是一个对话框</h2>
<button @click="closeAlert">关闭</button>
</div>
</template>
<script>
export default {
name: "myalert",
props:{
visible:{
type:Boolean,
default:false
}
},
methods:{
closeAlert(){
this.$emit('update:visible',false)
}
}
}
</script>
<style scoped>
.cont{
width:500px;
height:200px;
border:1px solid #ccc;
margin:50px auto;
text-align: center;
}
</style>
这么写还是太麻烦了,但有了统一的规则,系统就可以帮我们自动生成不必要的代码,这就是sync修饰符的作用,它让写法更为简洁:
<template>
<div id="app">
<button @click="visible=true">点击</button>
<my-alert :visible.sync="visible"></my-alert>
</div>
</template>
<script>
import myalert from './components/myalert'
export default {
name: 'App',
components:{'my-alert': myalert},
data(){
return {
visible:false
}
},
}
</script>
myalert.vue:
<template>
<div class="cont" v-show="visible">
<h2>这是一个对话框</h2>
<button @click="closeAlert">关闭</button>
</div>
</template>
<script>
export default {
name: "myalert",
props:{
visible:{
type:Boolean,
default:false
}
},
methods:{
closeAlert(){
this.$emit('update:visible',false)
}
}
}
</script>
<style scoped>
.cont{
width:500px;
height:200px;
border:1px solid #ccc;
margin:50px auto;
text-align: center;
}
</style>
sync修饰符其实是做了两步动作:
1、声明传的数据visible
2、声明@update:visible事件
sync和v-model的区别
v-model必须是input标签,它做了两步动作:
1、父组件传给子组件value
2、子组件通过触发input事件来修改value
因此,子组件必须有input标签才行。
而sync不限制标签,因此子组件在修改数据时,就必须约定使用@update:xxx