• vue之自行实现派发与广播-dispatch与broadcast


    要解决的问题

    主要针对组件之间的跨级通信

    为什么要自己实现dispatch与broadcast?

    因为在做独立组件开发或库时,最好是不依赖第三方库

    为什么不使用provide与inject?

    因为它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。
    然后有两种场景它不能很好的解决:
    父组件向子组件(支持跨级)传递数据;
    子组件向父组件(支持跨级)传递数据。

    代码如下:

    emitter.js
    
    function broadcast(componentName, eventName, params) {
      this.$children.forEach(child => {
        const name = child.$options.name;
    
        if (name === componentName) {
          child.$emit.apply(child, [eventName].concat(params));
        } else {
          // todo 如果 params 是空数组,接收到的会是 undefined
          broadcast.apply(child, [componentName, eventName].concat([params]));
        }
      });
    }
    export default {
      methods: {
        dispatch(componentName, eventName, params) {
          let parent = this.$parent || this.$root;
          let name = parent.$options.name;
    
          while (parent && (!name || name !== componentName)) {
            parent = parent.$parent;
    
            if (parent) {
              name = parent.$options.name;
            }
          }
          if (parent) {
            parent.$emit.apply(parent, [eventName].concat(params));
          }
        },
        broadcast(componentName, eventName, params) {
          broadcast.call(this, componentName, eventName, params);
        }
      }
    };
    
    这里面的核心思想是通过递归或遍历来查找要broadcast或dispatch的组件名字,然后在组件自身上emit与on
    
    
    parent.vue
    
    <template>
      <div>
        <h1>我是父组件</h1>
        <button @click="handleClick">触发事件</button> <child />
      </div>
    </template>
    <script>
    import Emitter from "@/mixins/emitter.js";
    import Child from "./child";
    export default {
      name: "componentA",
      mixins: [Emitter],
      created() {
        this.$on("child-to-p", this.handleChild);
      },
      methods: {
        handleClick() {
          this.broadcast("componentB", "on-message", "Hello Vue.js");
        },
        handleChild(val) {
          alert(val);
        }
      },
      components: {
        Child
      }
    };
    </script>
    
    
    
    child.vue
    
    <template>
      <div>我是子组件</div>
    </template>
    <script>
    import Emitter from "@/mixins/emitter.js";
    export default {
      name: "componentB",
      mixins: [Emitter],
      created() {
        this.$on("on-message", this.showMessage);
        this.dispatch("componentA", "child-to-p", "hello parent");
      },
      methods: {
        showMessage(text) {
          window.alert(text);
        }
      }
    };
    </script>
    
    

    这样就能实现跨级组件自定义通信了,但是,要注意其中一个问题:订阅必须先于发布,也就是说先有on再有emit

    父子组件渲染顺序,实例创建顺序

    子组件先于父组件前渲染,所以在子组的mounted派发事件时,在父组件中的mounte中是监听不到的。
    而父组件的create是先于子组件的,所以可以在父组件中的create可以监听到
    
    
  • 相关阅读:
    Linux XOR.DDoS样本取证特征与清除
    利用Volatility对Linux内存取证分析-常用命令翻译
    【黑客免杀攻防】读书笔记14
    CertUtil.exe被利用来下载恶意软件
    利用rundll32执行程序的函数执行程序
    揭秘Patchwork APT攻击-恶意软件样本BADNEWS
    【CTF MISC】pyc文件反编译到Python源码-2017世安杯CTF writeup详解
    [ 总结 ] 删除通过find查找到的文件
    [ 脚本 ] RHEL6.x 及Centos6.x 初始化脚本
    [ 手记 ] 联想rd650服务器整列及系统安装
  • 原文地址:https://www.cnblogs.com/raind/p/10241720.html
Copyright © 2020-2023  润新知