text: import ElCheckbox from 'element-ui/packages/checkbox';
  import ElTag from 'element-ui/packages/tag';
  import objectAssign from 'element-ui/src/utils/merge';
  import { getValueByPath } from './util';
  
  let columnIdSeed = 1;
  
  const defaults = {
    // 这里默认设置了对应列的类型，
    // 首先第一种类型是 默认的 defaults  类型
    default: {
      order: ''
    },
  
    // selection 类型表示该列显示显示多选
    selection: {
      width: 48,
      minWidth: 48,
      realWidth: 48,
      order: '',
      className: 'el-table-column--selection'
    },
    //  则 表示显示为一可以被打开的，或者是关闭的一个名包包块。 这里的快读和长度都是hi固定
    expand: {
      width: 48,
      minWidth: 48,
      realWidth: 48,
      order: ''
    },
      // 设置成index，则表示 改行的索引（开始显示索）从1 开始计数 ，
    index: {
      // 这里 设置了固定的跨度
      width: 48,
      minWidth: 48,
      realWidth: 48,
      order: ''
    }
  };
  
  const forced = {
    selection: {
      // 默认使用渲染 多选框列的头部是，使用ElCheckbox 组件渲染头部
      // 点击 头部的 复选框时，触发 toggleAllSelection 全选还是 全不选 事件
      renderHeader: function(h) {
        return <el-checkbox
          nativeOn-click={ this.toggleAllSelection }
          value={ this.isAllSelected } />;
      },
     // 渲染 多选框列 对应的多选框的内容，使用ElCheckbox 组件
      renderCell: function(h, { row, column, store, $index }) {
        return <el-checkbox
          value={ store.isSelected(row) }
          disabled={ column.selectable ? !column.selectable.call(null, row, $index) : false }
          on-input={ () => { store.commit('rowSelectedChanged', row); } } />;
      },
    //  默认 多选框的 列不可排序，不可通过拖拽改变宽度
      sortable: false,
      resizable: false
    },
    index: {
      // 加入索引的渲染时，类渲染头部，直接返回数据的label
      renderHeader: function(h, { column }) {
        return column.label || '#';
      },
      //  下面的内容渲染时，以当前索引为内容
      renderCell: function(h, { $index }) {
        return <div>{ $index + 1 }</div>;
      },
      sortable: false
    },
    expand: {
      // 渲染一个可展开的列时i，不渲染头部，
      renderHeader: function(h, {}) {
        return '';
      },
      //  渲染被隐藏的内容时，加上左侧的向右图标
      renderCell: function(h, { row, store }, proxy) {
        const expanded = store.states.expandRows.indexOf(row) > -1;
        return <div class={ 'el-table__expand-icon ' + (expanded ? 'el-table__expand-icon--expanded' : '') }
                    on-click={ () => proxy.handleExpandClick(row) }>
          <i class='el-icon el-icon-arrow-right'></i>
        </div>;
      },
      sortable: false,
      resizable: false,
      className: 'el-table__expand-column'
    }
  };
  
  //  这里计算默认的 组件，
  //把用户设置的 参数和默认的column 参数对象合并 返回的是所有的
  const getDefaultColumn = function(type, options) {
    const column = {};
  
    objectAssign(column, defaults[type || 'default']);
  
    for (let name in options) {
      if (options.hasOwnProperty(name)) {
        const value = options[name];
        if (typeof value !== 'undefined') {
          column[name] = value;
        }
      }
    }
  
      // 在column 属性中设置最小的宽度 为80 ( 如果用户没有设置minWidth 的话)
    if (!column.minWidth) {
      column.minWidth = 80;
    }
  
    column.realWidth = column.width || column.minWidth;
  
    return column;
  };
  
  const DEFAULT_RENDER_CELL = function(h, { row, column }) {
    const property = column.property;
    const value = property && property.indexOf('.') === -1
      ? row[property]
      : getValueByPath(row, property);
    if (column && column.formatter) {
      return column.formatter(row, column, value);
    }
    return value;
  };
  
  export default {
    name: 'ElTableColumn',
  
    props: {
      type: {
        type: String,
        default: 'default'
      },
      label: String,
      className: String,
      labelClassName: String,
      property: String,
      prop: String,
      width: {},
      minWidth: {},
      renderHeader: Function,
      sortable: {
        type: [String, Boolean],
        default: false
      },
      sortMethod: Function,
      resizable: {
        type: Boolean,
        default: true
      },
      context: {},
      columnKey: String,
      align: String,
      headerAlign: String,
      showTooltipWhenOverflow: Boolean,
      showOverflowTooltip: Boolean,
      fixed: [Boolean, String],
      formatter: Function,
      selectable: Function,
      reserveSelection: Boolean,
      filterMethod: Function,
      filteredValue: Array,
      filters: Array,
      filterPlacement: String,
      filterMultiple: {
        type: Boolean,
        default: true
      }
    },
  
    data() {
      return {
        isSubColumn: false,
        columns: []
      };
    },
  
    beforeCreate() {
      this.row = {};
      this.column = {};
      this.$index = 0;
    },
  
    components: {
      ElCheckbox,
      ElTag
    },
  
    computed: {
      // 这里的owner  可以标识 当前 table=-column 标签的父类table 标签
      owner() {
        //  通过while循环，向上遍历找到el-table 标签，在最外层的父标签中，会有一个tableId 来作为标识
        let parent = this.$parent;
        while (parent && !parent.tableId) {
          parent = parent.$parent;
        }
        return parent;
      }
    },
  
    created() {
      this.customRender = this.$options.render;
      this.$options.render = h => h('div', this.$slots.default);
      //  table -column 的节点id 会自增，每次挂载都会 不同
      this.columnId = (this.$parent.tableId || (this.$parent.columnId + '_')) + 'column_' + columnIdSeed++;
  
      let parent = this.$parent;
      let owner = this.owner;
      this.isSubColumn = owner !== parent;
  
      let type = this.type;
  
      let width = this.width;
      if (width !== undefined) {
        width = parseInt(width, 10);
        if (isNaN(width)) {
          //  如果宽度 没有设置，则默认设置成 null
          width = null;
        }
      }
  
      let minWidth = this.minWidth;
      if (minWidth !== undefined) {
        minWidth = parseInt(minWidth, 10);
        if (isNaN(minWidth)) {
           // 最小宽度如果没有被设置，则默认设置成80
          minWidth = 80;
        }
      }
  
      let isColumnGroup = false;
  
      let column = getDefaultColumn(type, {
        id: this.columnId,
        columnKey: this.columnKey,
        label: this.label,
        className: this.className,
        labelClassName: this.labelClassName,
        property: this.prop || this.property,
        type,
        renderCell: null,
        renderHeader: this.renderHeader,
        minWidth,
        width,
        isColumnGroup,
        context: this.context,
        align: this.align ? 'is-' + this.align : null,
        headerAlign: this.headerAlign ? 'is-' + this.headerAlign : (this.align ? 'is-' + this.align : null),
        sortable: this.sortable === '' ? true : this.sortable,
        sortMethod: this.sortMethod,
        resizable: this.resizable,
        showOverflowTooltip: this.showOverflowTooltip || this.showTooltipWhenOverflow,
        formatter: this.formatter,
        selectable: this.selectable,
        reserveSelection: this.reserveSelection,
        fixed: this.fixed === '' ? true : this.fixed,
        filterMethod: this.filterMethod,
        filters: this.filters,
        filterable: this.filters || this.filterMethod,
        filterMultiple: this.filterMultiple,
        filterOpened: false,
        filteredValue: this.filteredValue || [],
        filterPlacement: this.filterPlacement || ''
      });
       // 强制更新 renderHeader 和 renderCell 函数，使用默认的渲染方法
      objectAssign(column, forced[type] || {});
  
      //  将 column 中的标签 用户设置的的属性通过columnConfig 传递给父table 标签中
      this.columnConfig = column;
      // 定义 renderCell 的 默认的 renderCell 渲染函数
      let renderCell = column.renderCell;
      let _self = this;
       //  如果是可以折叠的 类
      if (type === 'expand') {
        owner.renderExpanded = function(h, data) {
          return _self.$scopedSlots.default
            ? _self.$scopedSlots.default(data)
            : _self.$slots.default;
        };
  
        column.renderCell = function(h, data) {
          return <div class="cell">{ renderCell(h, data, this._renderProxy) }</div>;
        };
  
        return;
      }
  
      column.renderCell = function(h, data) {
        // 未来版本移除
        if (_self.$vnode.data.inlineTemplate) {
          renderCell = function() {
            data._self = _self.context || data._self;
            if (Object.prototype.toString.call(data._self) === '[object Object]') {
              for (let prop in data._self) {
                if (!data.hasOwnProperty(prop)) {
                  data[prop] = data._self[prop];
                }
              }
            }
            // 静态内容会缓存到 _staticTrees 内，不改的话获取的静态数据就不是内部 context
            data._staticTrees = _self._staticTrees;
            data.$options.staticRenderFns = _self.$options.staticRenderFns;
            return _self.customRender.call(data);
          };
        } else if (_self.$scopedSlots.default) {
          renderCell = () => _self.$scopedSlots.default(data);
        }
  
        if (!renderCell) {
          renderCell = DEFAULT_RENDER_CELL;
        }
  
        return _self.showOverflowTooltip || _self.showTooltipWhenOverflow
          ? <div class="cell el-tooltip" style={'width:' + (data.column.realWidth || data.column.width) + 'px'}>{ renderCell(h, data) }</div>
          : <div class="cell">{ renderCell(h, data) }</div>;
      };
    },
  
    destroyed() {
      if (!this.$parent) return;
      this.owner.store.commit('removeColumn', this.columnConfig);
    },
  
  //   在 watch  方法中实时监听监听 column 中传来的传来的自定义属性值
    watch: {
      label(newVal) {
        if (this.columnConfig) {
          this.columnConfig.label = newVal;
        }
      },
      prop(newVal) {
        if (this.columnConfig) {
          this.columnConfig.property = newVal;
        }
      },
      property(newVal) {
        if (this.columnConfig) {
          this.columnConfig.property = newVal;
        }
      },
      filters(newVal) {
        if (this.columnConfig) {
          this.columnConfig.filters = newVal;
        }
      },
  
      filterMultiple(newVal) {
        if (this.columnConfig) {
          this.columnConfig.filterMultiple = newVal;
        }
      },
  
      align(newVal) {
        if (this.columnConfig) {
          this.columnConfig.align = newVal ? 'is-' + newVal : null;
  
          if (!this.headerAlign) {
            this.columnConfig.headerAlign = newVal ? 'is-' + newVal : null;
          }
        }
      },
  
      headerAlign(newVal) {
        if (this.columnConfig) {
          this.columnConfig.headerAlign = 'is-' + (newVal ? newVal : this.align);
        }
      },
  
      width(newVal) {
        if (this.columnConfig) {
          this.columnConfig.width = newVal;
          this.owner.store.scheduleLayout();
        }
      },
  
      minWidth(newVal) {
        if (this.columnConfig) {
          this.columnConfig.minWidth = newVal;
          this.owner.store.scheduleLayout();
        }
      },
  
      fixed(newVal) {
        if (this.columnConfig) {
          this.columnConfig.fixed = newVal;
          this.owner.store.scheduleLayout();
        }
      },
  
      sortable(newVal) {
        if (this.columnConfig) {
          this.columnConfig.sortable = newVal;
        }
      }
    },
  
    mounted() {
      const owner = this.owner;
      const parent = this.$parent;
      let columnIndex;
  
      if (!this.isSubColumn) {
        columnIndex = [].indexOf.call(parent.$refs.hiddenColumns.children, this.$el);
      } else {
        columnIndex = [].indexOf.call(parent.$el.children, this.$el);
      }
     // 前面在 created 的生命周期中 创建的 columnConfig 参数，传到公共的table-store 全局的数据方法中，让在table 作用域的范围中，来渲染cell表格
      owner.store.commit('insertColumn', this.columnConfig, columnIndex, this.isSubColumn ? parent.columnConfig : null);
    }
  };
  