element 学习借鉴 p1

463 阅读1分钟

近来在学习element源码, 作为国内首屈一指的vue组建库。有很多值得学习的地方,这里记录一些值得借鉴或者可以直接搬到自己项目的东西

No.1: scss

  • ele项目将所有的css属性提前定义出来了, 一般在packages/theme-chalk/src/common/var.scss,其他的scss全部引用这个,后期可以很方便的全局修改、定制主题。
  • 在packages/theme-chalk/src/mixins/mixins.scss 里面保存了很多工具函数, 用于生成特殊的class类名。 其中用了很多的scss高级方法, 和我们平时简单的使用sass完全不同。
生成el前缀, 一般是最外层容器 -> el-select
@mixin b($block) {
  $B: $namespace+'-'+$block !global;

  .#{$B} {
    @content;
  }
}
// 生成内部元素 ->  el-select__tags
@mixin e($element) {
  $E: $element !global;
  $selector: &;
  $currentSelector: "";
  @each $unit in $element {
    $currentSelector: #{$currentSelector + "." + $B + $element-separator + $unit + ","};
  }

  @if hitAllSpecialNestRule($selector) {
    @at-root {
      #{$selector} {
        #{$currentSelector} {
          @content;
        }
      }
    }
  } @else {
    @at-root {
      #{$currentSelector} {
        @content;
      }
    }
  }
}
// 生成状态  -> is-disabled
@mixin when($state) {
  @at-root {
    &.#{$state-prefix + $state} {
      @content;
    }
  }
}
//  媒体查询
@mixin res($key, $map: $--breakpoints) {
  // 循环断点Map,如果存在则返回
  @if map-has-key($map, $key) {
    @media only screen and #{inspect(map-get($map, $key))} {
      @content;
    }
  } @else {
    @warn "Undefeined points: `#{$map}`";
  }
}

以后再创建项目的时候, 完全可以直接使用ele的scss框架。 方便的管理css

N0.2 组建通信broadcast、dispatch

src/mixins/emitter.js文件中, 以mixin的方式保存了2个方法。用于复杂组建的通信方式。

    function broadcast(componentName, eventName, params) {
  this.$children.forEach(child => {
    var name = child.$options.componentName;

    if (name === componentName) {
      child.$emit.apply(child, [eventName].concat(params));
    } else {
      broadcast.apply(child, [componentName, eventName].concat([params]));
    }
  });
}
export default {
  methods: {
    dispatch(componentName, eventName, params) {
      var parent = this.$parent || this.$root;
      var name = parent.$options.componentName;

      while (parent && (!name || name !== componentName)) {
        parent = parent.$parent;

        if (parent) {
          name = parent.$options.componentName;
        }
      }
      if (parent) {
        parent.$emit.apply(parent, [eventName].concat(params));
      }
    },
    broadcast(componentName, eventName, params) {
      broadcast.call(this, componentName, eventName, params);
    }
  }
};

其中 dispatch用于朝上查找指定的元素触发指定的事件, broadcast递归的朝下查找子元素触发事件。 这种方式就避免了多级嵌套的时候一级一级的朝上传递事件和参数。