为什么this.$bus.$emit会不执行呢?
emit后面执行,所以在on来接受参数,导致第一次触发时不能执行
业务场景:涉及到父子、兄弟组件通信(A页面里有B、C组件/ C组件也有有B、O组件/ B组件是表单提交,同时用了wtach监听)
1.在A页面触发了事件
2.需要通知到C组件,还需要通知B组件更新数据
3.C组件接收到了A组件的通知做响应的处理,C组件中正展示B组件操作数据
4.C组件同时需要通知A跟B组件更新数据
5.A、C组件做处理
页面结构:(自己画的图太丑了,看个大致吧!公司的页面不敢截图 写了那么多文字都不如一张图实际,圈圈的地方是触发提示的地方,因为AC都含有B表单组件,所以需要弹窗提示用户)
重点:
通知emit的地方写:this.$bus.$emit('dataChangeFalse',false)
接收on数据的地方需要写在created里面
因为created的时会先挂载on事件
以下是重点代码可参考
页面结构
页面A
<template>
<header>
<el-tabs v-model="activeName" :before-leave="leave">
<el-tab-pane
v-for="item in tabs"
:key="item.name"
:label="item.label"
:name="item.name"
></el-tab-pane>
</el-tabs>
<el-button @click="toC">自定义排序</el-button> //给tab排序 此处省略弹层
</header>
<keep-alive>
<template>
<component :is="activeName
@change="change"
:data="data"
>
</component>
</template>
</keep-alive>
</template>
<script>
export default{
data(){
return{
activeName:B,
tabs: [
{ label: "个人中心", name: "D" },
{ label: "表单组件", name: "B" },
{ label: "消息中心", name: "C" }
],
dataChanged:false
}
},
methods:{
leave(newName, oldName) {
if (
(oldName === "B" || oldName === "C") &&
this.dataChanged
) {
return this.$confirm("编辑数据未保存,确定要切换吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
customClass:"out" //给弹层写样式用
}).then(() => {
this.dataChanged = false;
})
}
},
toC(){
if (
(oldName === "B" || oldName === "C") &&
this.dataChanged
) {
return this.$confirm("编辑数据未保存,确定要切换吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
customClass:"out" //给弹层写样式用
}).then(() => {
this.dataChanged = false;//用户选择确定切换 后续不会出现弹窗提示
this.$bus.$emit('dataChangeFalse',false)
//因为C组件也有表单 需通知C此时不需要弹窗了
//A组件此时用户有操作数据但是未保存 需要清除用户操作的数据
//用户提示操作完成后打开弹层
············此处省略打开弹层的代码
})
}
},
}
}
</script>
~~分割线~~
组件C
<template>
<div class="detailHead">
<el-radio-group v-model="detailStep" size="small" @change="radioChange">
<el-radio-button label="1">去表单组件</el-radio-button>
<el-radio-button label="2">消息列表</el-radio-button>
</el-radio-group>
</div>
<div>
<B :isDetail="true" @followChanged="followChanged" @save="save"></B>
<other></other>
</div>
</template>
<script>
export default{
data(){
dataChanged:false
}
},
created(){
this.$bus.$on('dataChangeFalse',this.flag) //这里是重点接收A组件通知
},
methods:{
flag(val){
this.dataChanged = val
},
radioChange(){
if (this.dataChanged) {
this.$confirm('编辑数据未保存,确定要切换吗?','提示',{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
customClass:"out"
})
.then(() => {
this.detailStep = '2'
this.dataChanged = false
this.$emit('followChanged', false) //通知A
})
.catch(()=> {
this.detailStep = '1'
})
}
},
followChanged (val) {
this.dataChanged = val
this.$emit('followChanged', val) //通知A
},
save(){
//接收B组件通知
},
}
}
</script>
~~分割线~~
组件B
<template>
<form>
//大量的表单元素
//提交操作
</form>
</template>
<script>
export default{
data(){
form:{
//大量的表单数据
},
formAId:'',
formCId:'',
},
props:{
isDetail:
}
created(){
this.$bus.$on('dataChangeFalse',this.reLoadflag) //接收A组件通知 更新数据
},
methods:{
reLoadflag(val){
this.reset() //关闭弹窗需要重置数据
},
reset(){
this.form = {//恢复初始值},
if(this.isDetail){
this.getC()
}else{
this.getB()
}
},
getC(){
//获取C组件的默认表单信息
this.form.name = data.name
...
},
getB(){
//获取B组件的默认表单信息
this.form.name = data.name
...
},
}
}
</script>