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 = {
    default: {
      order: ''
    },
    selection: {
      width: 48,
      minWidth: 48,
      realWidth: 48,
      order: ''
    },
    index: {
      width: 48,
      minWidth: 48,
      realWidth: 48,
      order: ''
    }
  };
  
  const forced = {
    selection: {
      renderHeader: function(h) {
        return <el-checkbox
          nativeOn-click={ this.toggleAllSelection }
          domProps-value={ this.isAllSelected } />;
      },
      renderCell: function(h, { row, column, store, $index }) {
        return <el-checkbox
          domProps-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: {
      renderHeader: function(h, { column }) {
        return column.label || '#';
      },
      renderCell: function(h, { $index }) {
        return <div>{ $index + 1 }</div>;
      },
      sortable: false
    }
  };
  
  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;
        }
      }
    }
  
    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;
    if (column && column.formatter) {
      return column.formatter(row, column);
    }
  
    if (property && property.indexOf('.') === -1) {
      return row[property];
    }
  
    return getValueByPath(row, property);
  };
  
  export default {
    name: 'el-table-column',
  
    props: {
      type: {
        type: String,
        default: 'default'
      },
      label: String,
      className: String,
      property: String,
      prop: String,
      width: {},
      minWidth: {},
      renderHeader: Function,
      sortable: {
        type: [Boolean, String],
        default: false
      },
      sortMethod: Function,
      resizable: {
        type: Boolean,
        default: true
      },
      context: {},
      align: String,
      showTooltipWhenOverflow: Boolean,
      showOverflowTooltip: Boolean,
      fixed: [Boolean, String],
      formatter: Function,
      selectable: Function,
      reserveSelection: Boolean,
      filterMethod: Function,
      filters: Array,
      filterMultiple: {
        type: Boolean,
        default: true
      }
    },
  
    render() {
      return (<div>{ this._t('default') }</div>);
    },
  
    data() {
      return {
        isSubColumn: false,
        columns: []
      };
    },
  
    beforeCreate() {
      this.row = {};
      this.column = {};
      this.$index = 0;
    },
  
    components: {
      ElCheckbox,
      ElTag
    },
  
    computed: {
      owner() {
        let parent = this.$parent;
        while (parent && !parent.tableId) {
          parent = parent.$parent;
        }
        return parent;
      }
    },
  
    created() {
      this.customRender = this.$options.render;
      this.$options.render = (h) => {
        return (<div>{ this._t('default') }</div>);
      };
  
      let columnId = 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)) {
          width = null;
        }
      }
  
      let minWidth = this.minWidth;
      if (minWidth !== undefined) {
        minWidth = parseInt(minWidth, 10);
        if (isNaN(minWidth)) {
          minWidth = 80;
        }
      }
  
      let isColumnGroup = false;
  
      let column = getDefaultColumn(type, {
        id: columnId,
        label: this.label,
        className: this.className,
        property: this.prop || this.property,
        type,
        renderCell: null,
        renderHeader: this.renderHeader,
        minWidth,
        width,
        isColumnGroup,
        context: this.context,
        align: this.align ? 'is-' + this.align : null,
        sortable: 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,
        filterMethod: this.filterMethod,
        filters: this.filters,
        filterable: this.filters || this.filterMethod,
        filterMultiple: this.filterMultiple,
        filterOpened: false,
        filteredValue: []
      });
  
      objectAssign(column, forced[type] || {});
  
      let renderCell = column.renderCell;
      let _self = this;
  
      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)) {
                  // _self.$set(data, prop, data._self[prop]);
                  data[prop] = data._self[prop];
                }
              }
            }
            // 静态内容会缓存到 _staticTrees 内，不改的话获取的静态数据就不是内部 context
            data._staticTrees = _self._staticTrees;
            data.$options.staticRenderFns = _self.$options.staticRenderFns;
            return _self.customRender.call(data);
          };
        }
  
        if (!renderCell) {
          renderCell = DEFAULT_RENDER_CELL;
        }
  
        return _self.showOverflowTooltip || _self.showTooltipWhenOverflow
          ? <el-tooltip
              effect={ this.effect }
              placement="top"
              disabled={ this.tooltipDisabled }>
              <div class="cell">{ renderCell(h, data) }</div>
              <span slot="content">{ renderCell(h, data) }</span>
            </el-tooltip>
          : <div class="cell">{ renderCell(h, data) }</div>;
      };
  
      this.columnConfig = column;
    },
  
    destroyed() {
      if (!this.$parent) return;
      this.owner.store.commit('removeColumn', this.columnConfig);
    },
  
    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;
        }
      },
  
      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();
        }
      }
    },
  
    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);
      }
  
      owner.store.commit('insertColumn', this.columnConfig, columnIndex, this.isSubColumn ? parent.columnConfig : null);
    }
  };
  