美文网首页
element-ui dispatch和broadcast

element-ui dispatch和broadcast

作者: 如果俞天阳会飞 | 来源:发表于2021-12-13 20:22 被阅读0次

    src/mixins/emitter.js中有两个方法:dispatch和broadcast,这两个方法在多处用到:
    例如 在packages/select/src/select.vue中,value的监控方法中用到dispatch和broadcast:

    watch: {
      value(val, oldVal) {
        if (!valueEquals(val, oldVal)) {
           this.dispatch('ElFormItem', 'el.form.change', val);
        }
      },
      visible(val) {
        if (!val) {
           this.broadcast('ElSelectDropdown', 'destroyPopper');
        }
      }
    }
    

    一、dispatch(子组件发送消息给上层组件)

    dispatch(componentName, eventName, params) {
          // 当前父组件
          var parent = this.$parent || this.$root;
          // 当前父组件的组件名
          var name = parent.$options.componentName;
    
          // 通过$parent,一直向上找,直到组件名等于componentName
          while (parent && (!name || name !== componentName)) {
            parent = parent.$parent;
    
            if (parent) {
              name = parent.$options.componentName;
            }
          }
          if (parent) {
            // 如果找到目标组件,那么调用目标组件的$emit方法
            parent.$emit.apply(parent, [eventName].concat(params));
          }
        }
    

    还是以packages/select/src/select.vue为例:

    <el-form>
      <el-form-item>
        <el-select>
        </el-select>
      </el-form-item>
    </el-form>
    

    <meta charset="utf-8">

    el-select组件中调用dispatch方法(this.dispatch('ElFormItem', 'el.form.change', val)),通过while循环,找到上层名为ElFormItem的组件,并在上层组件实例中

    on方法捕获该事件:

    addValidateEvents() {
            ......
            if (rules.length || this.required !== undefined) {
              ......
              this.$on('el.form.change', this.onFieldChange);
            }
    }
    

    二、broadcast(上层组件通知下层组件)

    function broadcast(componentName, eventName, params) {
      // 遍历所有子组件
      this.$children.forEach(child => {
        var name = child.$options.componentName;
        // 找到组件名为componentName的子组件,并调用该子组件的$emit方法;
        // 否则,继续递归
        if (name === componentName) {
          child.$emit.apply(child, [eventName].concat(params));
        } else {
          broadcast.apply(child, [componentName, eventName].concat([params]));
        }
      });
    }
    

    还是以packages/select/src/select.vue为例:

    <el-select>
     <el-option></el-option>
     <el-option></el-option>
    </el-select>
    

    el-select组件中调用broadcast方法:

    handleQueryChange(val) {
            ......
            this.broadcast('ElOption', 'queryChange', val);
            ......
    } 
    

    上面代码,会向所有el-option子组件广播queryChange事件并携带数据,在el-option组件的created方法中会通过$on方法响应:

    created() {
          ......
          this.$on('queryChange', this.queryChange);
          ......
    }
    

    参考来源: https://www.jianshu.com/p/ebf8d6fae1f2

    相关文章

      网友评论

          本文标题:element-ui dispatch和broadcast

          本文链接:https://www.haomeiwen.com/subject/azrcfrtx.html