大家先一起看一下官方解释
可以看出.sync的目的是实现双向绑定(这里的双向绑定指的是子组件共享父组件的数据,父组件的数据改变子组件的数据会跟着一起改变,子组件也能改变父组件的数据)
自己实现双向绑定
父组件
<template>
<div>
<div>parent:{{msg}}</div>
//自定义一个handleMsg事件,子组件通过$emit调用
<Child :msg="msg" @handleMsg="changeMsg"></Child>
<button @click="changeMsg">父组件按钮</button>
</div>
</template>
<script>
import Child from './Child.vue'
export default {
data(){
return {
msg : 'hello'
}
},
components: {
Child
},
methods: {
changeMsg(){
this.msg = Date.now().toString();
}
},
}
</script>
子组件
<template>
<div>
child:{{msg}}
<button @click="$emit('handleMsg')">子组件按钮</button>
</div>
</template>
<script>
export default {
props: {
msg: String
}
};
</script>
效果展示
.sync修饰符的实现(传单个值)
其实.sync修饰就是对上面代码的简写,但是有一些额外的限制与局限;
父组件
<template>
<div>
<div>parent:{{msg}}</div>
//对父级的msg绑定sync修饰符,不需要在绑定额外的事件
<Child :msg.sync="msg"></Child>
<button @click="changeMsg">父组件按钮</button>
</div>
</template>
<script>
import Child from './Child.vue'
export default {
data(){
return {
msg : 'hello'
}
},
components: {
Child
},
methods: {
changeMsg(){
this.msg = Date.now().toString();
}
},
}
</script>
子组件
<template>
<div>
child:{{msg}}
// 此处$emit调用的事件'update:msg'是内部实现好的,这里update是写死的,必须是update,
// msg是父组件sync修饰符绑定的变量,'666'是赋给父组件sync修饰符绑定的变量
// 由于用法是写死的,所以sync修饰符常被用来改变父组件的boolean类型的变量
<button @click="$emit('update:msg','666')">子组件按钮</button>
</div>
</template>
<script>
export default {
//如果js内部不使用父组件传过来的msg,这里可以不用props接收,程序仍能正常运行
props: {
msg: String
}
};
</script>
效果展示
虽然通过.sync修饰符我们很简单的实现了与上面一样的功能,但是.sync只能做一些简单的事,过于复杂的功能他就帮不上什么忙了.sync修饰符的实现(传多个值)
父组件
<template>
<div>
<Slider v-bind.sync="doc"></Slider>
<div>{{this.doc.x}}</div>
<div>{{this.doc.y}}</div>
</div>
</template>
<script>
import Child from './Child.vue'
export default {
data(){
return {
doc:{
x:0,
y:100
}
}
},
components: {
Child
},
}
</script>
子组件
<template>
<div class="slider">
<div @click="$emit('update:x',2)">slider111</div>
<div @click="$emit('update:y',20)">slider222</div>
</div>
</template>
通过这种方式,我们把doc对象中的每一个属性都作为一个独立的prop传进去,然后各自添加用于更新的v-on监听器
将 v-bind.sync
用在一个字面量的对象上,例如v-bind.sync=”{ title: doc.title }”
,是无法正常工作的,因为在解析一个像这样的复杂表达式的时候,有很多边缘情况需要考虑。