使用前提:
首先,我们需要明确的是,子父组件之间通讯,子组件是不能直接改变父组件的值的。(父组件是大佬,小弟不能改变大佬的值,但是父组件可以改变子组件的值)
作用:
通过某种方式,子组件可以”直接“改变父组件的值。
方法:
场景:控制弹框的显示与关闭。在父组件中打开子组件弹框,然后在点击子组件中的按钮关闭弹框。
- 一般我们子父传值的处理如下:
// 父组件
<template>
<div>
<input type="button"
value="打开子组件"
@click="show">
<child @changeVisibleState="changeVisible" :visible="childShow"/>
</div>
</template>
<script>
import child from "@/components/child"
export default {
data() {
return {
childShow:false
}
},
components:{
child
},
methods:{
show(){
this.childShow=true;
},
changeVisible(val){
this.childShow=val;
}
}
}
</script>
// 子组件
<template>
<div>
点我关闭子组件
<input type="button" value="点我隐身" @click="doClose" v-show="visible">
</div>
</template>
<script>
export default {
props:['visible']
methods:{
doClose(){
this.$emit("changeVisibleState",false);
}
}
}
</script>
- 改进
这样的写法没错,但是显的比较臃肿,明明我只是要改一个值,就不能简单点?
答案是,当然是可以的。
大家肯定会想,那我不能直接改变父组件的值?想v-model那样,多爽。
vue也是考虑到了这点,所以提供了一个更好的解决方案。
// 父组件
// 先把方法写到行内,箭头函数的写法。
// 方法名为什么是update:visible,是下面子组件的emit方法定义的。
<template>
<div>
<input type="button"
value="打开子组件"
@click="show">
<child @update:visible="(val)=>{childShow = val}" :visible="childShow"
/>
</div>
</template>
<script>
import child from "@/components/child"
export default {
data() {
return {
childShow:false
}
},
components:{
child
},
methods:{
show(){
this.childShow=true;
}
}
}
</script>
// 子组件
<template>
<div>
点我关闭子组件
<input type="button" value="点我隐身" @click="doClose" v-show="visible">
</div>
</template>
<script>
export default {
props:['visible']
methods:{
doClose(){
// 改变子组件中的写法
this.$emit("update:visible",false);
}
}
}
</script>
其中,
对于 @update:visible="(val)=>{childShow = val}" :visible="childShow",vue提供了一个语法糖,将其替换成 :visible.sync = "childShow" ,这样是不是看起来简洁多了。
那么就变成了:
// 父组件
<template>
<div>
<input type="button"
value="打开子组件"
@click="show">
<child :visible.sync = "childShow"/>
</div>
</template>
<script>
import child from "@/components/child"
export default {
data() {
return {
childShow:false
}
},
components:{
child
},
methods:{
show(){
this.childShow=true;
}
}
}
</script>
// 子组件
<template>
<div>
点我关闭子组件
<input type="button" value="点我隐身" @click="doClose" v-show="visible">
</div>
</template>
<script>
export default {
props:['visible']
methods:{
doClose(){
//emit中的函数名,一定要以这种格式哟~,"update:props",其中props就是我们子父之间通讯的值
this.$emit("update:visible",false);
}
}
}
</script>
总结:
其实.sync就是一个语法糖,将我们平时正常的子父之间传值的过程,进行了写法上的简化,本质还是没有变的。