eventBus的this.$bus.$emit第一次不执行

320 阅读1分钟

为什么this.$bus.$emit会不执行呢?

onon在emit后面执行,所以在emit执行时没有emit执行时 没有on来接受参数,导致第一次触发时不能执行

业务场景:涉及到父子、兄弟组件通信(A页面里有B、C组件/ C组件也有有B、O组件/ B组件是表单提交,同时用了wtach监听)
1.在A页面触发了事件
2.需要通知到C组件,还需要通知B组件更新数据 
3.C组件接收到了A组件的通知做响应的处理,C组件中正展示B组件操作数据
4.C组件同时需要通知AB组件更新数据
5.A、C组件做处理

页面结构:(自己画的图太丑了,看个大致吧!公司的页面不敢截图 写了那么多文字都不如一张图实际,圈圈的地方是触发提示的地方,因为AC都含有B表单组件,所以需要弹窗提示用户)

easy.png

重点:

通知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>