table-column组件源码探秘

497 阅读2分钟

在使用Element table表格组件时,除了需要使用el-table外,我们还需要使用到el-table-column 那既然有了el-table,为什么还需要有el-table-column呢?它的作用又是什么?带着疑惑去源码中寻找答案

table-column的created部分

created() {
    // columnOrTableParent是一个computed属性 用于寻找父级,如果没有tableId和columnId会接着向上查找
    const parent = this.columnOrTableParent;
    // owner也是一个用于查找父级的计算属性,但是owner是如果没有tableId会接着向上查找
    // 这里isSubColumn的值为false,为true的话则说明这个table-column是被另外一个table-column嵌套的
    this.isSubColumn = this.owner !== parent;
    this.columnId = (parent.tableId || parent.columnId) + '_column_' + columnIdSeed++;

    const type = this.type || 'default';
    const sortable = this.sortable === '' ? true : this.sortable;
    const defaults = {
      ...cellStarts[type],
      id: this.columnId,
      type: type,
      property: this.prop || this.property,
      align: this.realAlign,
      headerAlign: this.realHeaderAlign,
      showOverflowTooltip: this.showOverflowTooltip || this.showTooltipWhenOverflow,
      // filter 相关属性
      filterable: this.filters || this.filterMethod,
      filteredValue: [],
      filterPlacement: '',
      isColumnGroup: false,
      filterOpened: false,
      // sort 相关属性
      sortable: sortable,
      // index 列
      index: this.index
    };

    const basicProps = ['columnKey', 'label', 'className', 'labelClassName', 'type', 'renderHeader', 'formatter', 'fixed', 'resizable'];
    const sortProps = ['sortMethod', 'sortBy', 'sortOrders'];
    const selectProps = ['selectable', 'reserveSelection'];
    const filterProps = ['filterMethod', 'filters', 'filterMultiple', 'filterOpened', 'filteredValue', 'filterPlacement'];
    // 获取列的props
    let column = this.getPropsData(basicProps, sortProps, selectProps, filterProps);
    // 合并props并将值为undefined的删除
    column = mergeOptions(defaults, column);

    // 注意 compose 中函数执行的顺序是从右到左
    // compose函数 将需要嵌套执行的函数平铺 嵌套执行就是一个函数的返回值将作为另一个函数的参数
    // compose函数的实现可以使用reduceRight加箭头函数更简洁的实现
    const chains = compose(this.setColumnRenders, this.setColumnWidth, this.setColumnForcedProps);
    column = chains(column);
    //赋值给变量columnConfig
    this.columnConfig = column;

    // 注册 watcher
    // 使用watch监听属性
    this.registerNormalWatchers();
    // 监听width minWidth fixed
    // 执行scheduleLayout
    this.registerComplexWatchers();
  },

table-column的mounted部分

mounted() {
    const owner = this.owner;
    const parent = this.columnOrTableParent;
    const children = this.isSubColumn ? parent.$el.children : parent.$refs.hiddenColumns.children;
    // 获取列的index
    const columnIndex = this.getColumnElIndex(children, this.$el);
    // 触发store的insertColumn方法,就是将columnConfig保存在store里的_column里
    owner.store.commit('insertColumn', this.columnConfig, columnIndex, this.isSubColumn ? parent.columnConfig : null);
  },

总结

其实最终el-table-column的渲染会在table组件的<div class="hidden-columns" ref="hiddenColumns"><slot></slot></div>里,是不直接对应画面显示的,而el-table-column的作用是将传递给它的prop和一些状态放入store中,供其他部分使用。

table-column.png