子父组件通信
例如:
<template>
<el-dialog
title="提示"
:visible.sync="flag"
<el-button @click="hidden">取 消</el-button>
width="30%">
<span>这是一段信息</span>
<span slot="footer" class="dialog-footer">
</span>
</el-dialog>
</template>
<script>
export default {
name: "add-subject",
props: ["flag"],
//还可以写成这种
// props: {
// flag: {
// type:boolean,
// required:true
// }
// }
method:{
hidden:function(){
//错误写法
this.flag=false;
}
}
</script>
子组件接收来自父组件的值可以接受到,但是子组件不能直接修改这个变量的值。
例如上面的案例,当调用hidden方法时,子组件虽然可以成功的修改flag的值,但是父组件将报错,而且父组件接受不到子组件的修改。
所以如果要对flag操作,可以通过$emit向父组件发送消息,通过父组件去修改flag的值。
例如:
子组件:
<template>
<el-dialog
title="提示"
:visible.sync="flag"
<el-button @click="hidden">取 消</el-button>
width="30%">
<span>这是一段信息</span>
<span slot="footer" class="dialog-footer">
</span>
</el-dialog>
</template>
<script>
export default {
name: "add-subject",
props: ["flag"],
method:{
hidden:function(){
//错误写法
//this.flag=false;
//正确写法
this.$emit("hiddenDialog", false);
}
}
</script>
父组件:
<template>
<el-button @click="add">添加 </el-button>
<add-subject :flag="flag" @hiddenDialog="alertTip"></add-subject>
</template>
<script>
export default {
components: {AddSubject},
data() {
return {
flag: false,
}
},
methods: {
add:function () {
this.flag = true;
},
//data是来自与子组件中的值
alertTip: function (data) {
this.flag = data;
}
}
}
</script>
以上代码只截取了部分,大致的效果如下:
这样就可以实现实现子父组件动态修改同一个变量的值了。
当然除了使用$emit之外,在子组件中也可以使用watch监听flag的值。也可以实现类似的效果,不过这种方式就是父组件单方面的修改flag的值了。
如果父组件传递给子组件的数据是对象或者数组的话,子组件该变量对象或者属性的值,父组件不会报错,可以直接操作,因为对象和数组是双向绑定的操作。类似于java中的基本数据和引用数据的区别吧。
最好还是不
总而言之,最不要在子组件中直接修改父组件传递过来的变量,否则很容易遭成一些莫名其妙的问题。
兄弟组件通信
实现方式,通过一个Vue对象作为事件中心,管理兄弟组件的事件,实现兄弟组件通信。
父组件:
<template>
<div>
<btn1></btn1>
<btn2></btn2>
</div>
</template>
<script>
import Btn1 from "../../components/btn1";
import Btn2 from "../../components/btn2";
export default {
name: "parent",
components: {Btn2, Btn1}
}
</script>
<style scoped>
</style>
btn1和btn2作为兄弟组件。
这里采用创建一个Vue对象来作为事件注册中心。
在该/utils/目录下创建Hub.js,内容如下:
//这个作为兄弟组件通信的事件注册中心
import Vue from 'vue'
export default new Vue();
btn1
<template>
<el-row>
<el-button @click="add">增加值</el-button>
<span>{{num}}</span>
</el-row>
</template>
<script>
import Hub from '../utils/Hub'
export default {
name: "btn1",
data(){
return{
num:10
}
},
methods: {
//发送数据给btn2
add: function () {
Hub.$emit("add", 1);
}
},
//监听来自btn2的数据
mounted:function(){
Hub.$on('sub',(val)=>{
this.num-=val;
})
}
}
</script>
<style scoped>
</style>
btn2
<template>
<el-row>
<el-button @click="div">减少</el-button>
<span>{{num}}</span>
</el-row>
</template>
<script>
import Hub from '../utils/Hub'
export default {
name: "btn2",
data(){
return{
num:0
}
},
methods:{
div:function () {
//发送给btn1的数据
Hub.$emit('sub',1);
}
},
mounted:function () {
//监听btn1的add事件,val就是传递过来的数据
Hub.$on("add",(val)=>{
this.num+=val;
})
}
}
</script>
<style scoped>
</style>
效果图:
组件通信:
1、子向父,通过$emit自定义事件。
2、父向子,通过props自定义属性通信。
3、Pub/Sub插件通信,需要额外安装插件。
4、子父组件互相通信,solt插槽。
5、兄弟组件通信,利用事件中心,搭配 $emit, $on监听事件传递数据。