element 學習借鑑 p1

xanggang發表於2018-11-01

近來在學習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遞迴的朝下查詢子元素觸發事件。 這種方式就避免了多級巢狀的時候一級一級的朝上傳遞事件和引數。

相關文章