qingwei.li 9 жил өмнө
parent
commit
bca756d8dc

+ 6 - 6
bin/build-entry.js

@@ -14,13 +14,13 @@ const install = function(Vue) {
 
 {{install}}
 
-  // Vue.use(Loading);
+  Vue.use(Loading);
 
-  // Vue.prototype.$msgbox = MessageBox;
-  // Vue.prototype.$alert = MessageBox.alert;
-  // Vue.prototype.$confirm = MessageBox.confirm;
-  // Vue.prototype.$prompt = MessageBox.prompt;
-  // Vue.prototype.$notify = Notification;
+  Vue.prototype.$msgbox = MessageBox;
+  Vue.prototype.$alert = MessageBox.alert;
+  Vue.prototype.$confirm = MessageBox.confirm;
+  Vue.prototype.$prompt = MessageBox.prompt;
+  Vue.prototype.$notify = Notification;
 };
 
 // auto install

+ 1 - 1
examples/components/table-filter.vue

@@ -23,7 +23,7 @@
       }
     },
 
-    ready() {
+    mounted() {
       console.log('popup ready');
     }
   };

+ 46 - 19
examples/docs/table.md

@@ -1,6 +1,5 @@
 <script>
   import Vue from 'vue';
-  let popup = Vue.extend(require('examples/components/table-filter.vue'));
   export default {
     data() {
       return {
@@ -81,14 +80,24 @@
       };
     },
 
+    methods: {
+      handleSelectionChange(val) {
+        this.singleSelection = val;
+      },
+
+      // handleMultipleSelectionChange(val) {
+      //   this.multipleSelection = val;
+      // }
+    },
+
     watch: {
       singleSelection(val) {
         console.log('selection: ', val);
       },
 
-      multipleSelection(val) {
-        console.log('selection: ', val);
-      }
+      // multipleSelection(val) {
+      //   console.log('selection: ', val);
+      // }
     }
   };
 </script>
@@ -287,7 +296,7 @@
     <el-table-column property="address" label="地址"></el-table-column>
   </el-table>
 </template>
- 
+
 <script>
   export default {
     data() {
@@ -427,16 +436,16 @@
 
 ## 单选
 
-<el-table :data="tableData" selection-mode="single" :selection.sync="singleSelection" style="width: 520px" allow-no-selection>
+<el-table :data="tableData" selection-mode="single" @selectionchange="handleSelectionChange" style="width: 520px" allow-no-selection>
   <el-table-column property="date" label="日期" width="120"></el-table-column>
   <el-table-column property="name" label="姓名" width="120"></el-table-column>
   <el-table-column property="address" label="地址"></el-table-column>
 </el-table>
-<p>{{ singleSelection | json }}</p>
+<p>{{ singleSelection }}</p>
 
 ```html
 <template>
-  <el-table :data="tableData" selection-mode="single" :selection.sync="singleSelection">
+  <el-table :data="tableData" selection-mode="single" @selectionchange="handleSelectionChange">
     <el-table-column property="date" label="日期" width="120"></el-table-column>
     <el-table-column property="name" label="姓名" width="120"></el-table-column>
     <el-table-column property="address" label="地址"></el-table-column>
@@ -466,6 +475,12 @@
         }],
         singleSelection: {}
       }
+    },
+
+    methods: {
+      handleSelectionChange(val) {
+        this.singleSelection = val;
+      }
     }
   }
 </script>
@@ -473,19 +488,23 @@
 
 ## 多选
 
-<el-table :data="tableData3" selection-mode="multiple" :selection.sync="multipleSelection" style="width: 520px">
+<el-table :data="tableData3" selection-mode="multiple" style="width: 520px">
   <el-table-column type="selection" width="50"></el-table-column>
-  <el-table-column property="date" label="日期" width="120"></el-table-column>
+  <el-table-column inline-template property="date" label="日期" width="120">
+    <div>{{ row.date }}</div>
+  </el-table-column>
   <el-table-column property="name" label="姓名" width="120"></el-table-column>
   <el-table-column property="address" label="地址"></el-table-column>
 </el-table>
-<p>{{ multipleSelection | json }}</p>
+<p>{{ multipleSelection }}</p>
 
 ```html
 <template>
-  <el-table :data="tableData3" selection-mode="multiple" :selection.sync="multipleSelection">
+  <el-table :data="tableData3" selection-mode="multiple" @selectionchange="handleSelectionChange">
     <el-table-column type="selection" width="50"></el-table-column>
-    <el-table-column property="date" label="日期" width="120"></el-table-column>
+    <el-table-column inline-template property="date" label="日期" width="120">
+      <div>{{ row.date }}</div>
+    </el-table-column>
     <el-table-column property="name" label="姓名" width="120"></el-table-column>
     <el-table-column property="address" label="地址"></el-table-column>
   </el-table>
@@ -526,6 +545,12 @@
         }],
         multipleSelection: []
       }
+    },
+
+    methods: {
+      handleSelectionChange(val) {
+        this.multipleSelection = val;
+      }
     }
   }
 </script>
@@ -584,16 +609,15 @@
 | border | 是否带有纵向边框 | boolean | | false |
 | selectionMode | 列表项选择模式 | string | 'single', 'multiple', 'none' | 'none' |
 | allowNoSelection | 单选模式是否允许选项为空 | boolean | | false |
-| selection | 多选模式下返回数组,单选模式下返回选中的元素。 | array/object | | |
 | fixedColumnCount | 固定列的个数 | number | | 0 |
 
 ## el-table 事件
 | 事件名 | 说明 | 参数 |
 | ---- | ---- | ---- |
-| selection-change | 当选择项发生变化时会触发该事件 | selected |
-| cell-mouse-enter | 当单元格 hover 进入时会触发该事件 | row, column, cell, event |
-| cell-mouse-leave | 当单元格 hover 退出时会触发该事件 | row, column, cell, event |
-| cell-click | 当某个单元格被点击时会触发该事件 | row, column, cell, event |
+| selectionchange | 当选择项发生变化时会触发该事件 | selected |
+| cellmouseenter | 当单元格 hover 进入时会触发该事件 | row, column, cell, event |
+| cellmouseleave | 当单元格 hover 退出时会触发该事件 | row, column, cell, event |
+| cellclick | 当某个单元格被点击时会触发该事件 | row, column, cell, event |
 
 ## el-table-column API
 | 参数      | 说明          | 类型      | 可选值                           | 默认值  |
@@ -602,5 +626,8 @@
 | property | 对应列内容的字段名 | string | | '' |
 | width | 对应列的宽度 | string | | |
 | sortable | 对应列是否可以排序 | boolean | | false |
-| type | 对应列的类型。如果设置了 `selection` 则显示多选按钮,如果设置了 `index` 则显示该行的索引(从 1 开始计算) | string | 'selection', 'index' | 0 |
+| type | 对应列的类型。如果设置了 `selection` 则显示多选按钮,如果设置了 `index` 则显示该行的索引(从 1 开始计算) | string | 'selection', 'index', 'filter' | 0 |
 | formatter | 用来格式化内容,在 formatter 执行的时候,会传入 row 和 column | function | |  |
+| show-tooltip-when-overflow | 当过长被隐藏时显示 tooltip | Boolean | | false |
+| inline-template | 指定该属性后可以自定义 column 模板,参考多选的时间列,通过 row 获取行信息。此时不需要配置 property 属性  | | |
+

+ 155 - 0
packages/table/src/table-body.js

@@ -0,0 +1,155 @@
+const getColumnById = function(grid, columnId) {
+  let column = null;
+  grid.columns.forEach(function(item) {
+    if (item.id === columnId) {
+      column = item;
+    }
+  });
+  return column;
+};
+
+const getColumnByCell = function(grid, cell) {
+  const matches = (cell.className || '').match(/grid_[^\s]+/gm);
+  if (matches) {
+    return getColumnById(grid, matches[0]);
+  }
+  return null;
+};
+
+import { getValueByPath, getCell, orderBy, getChild } from './util';
+
+export default {
+  props: {
+    columns: {},
+    data: {},
+    fixed: {},
+    selection: {
+      default() {
+        return [];
+      }
+    }
+  },
+
+  render(h) {
+    return (
+      <table
+        class="el-table__body"
+        cellspacing="0"
+        cellpadding="0"
+        border="0">
+        <tbody>
+          {
+            this._l(this.data, (row, $index) =>
+              <tr
+                on-click={ ($event) => this.handleClick($event, row) }
+                on-mouseenter={ _ => this.handleMouseEnter($index) }
+                class={{
+                  'current-row': row === this.$parent.$parent.selected,
+                  'hover': this.$parent.$parent.hoverRowIndex === $index,
+                  'positive-row': row.$positive,
+                  'info-row': row.$info,
+                  'warning-row': row.$warning,
+                  'negative-row': row.$negative
+                }}>
+                {
+                  this._l(this.columns, (column) =>
+                    <td
+                      class={ column.id }
+                      on-mouseenter={ ($event) => this.handleCellMouseEnter($event, row) }
+                      on-mouseleave={ this.handleCellMouseLeave }>
+                      {
+                        column.template
+                          ? column.template.call(this._renderProxy, h, { row, column, $index })
+                          : <div class="cell">{ this.$getPropertyText(row, column.property, column.id) }</div>
+                      }
+                    </td>
+                  ).concat(this.fixed ? <td class="gutter" /> : '')
+                }
+              </tr>
+            )
+          }
+        </tbody>
+      </table>
+    );
+  },
+
+  data() {
+    return {
+      tooltipDisabled: true
+    };
+  },
+
+  filters: {
+    orderBy
+  },
+
+  methods: {
+    handleCellMouseEnter(event, row) {
+      let grid = this.$parent;
+      const cell = getCell(event);
+
+      if (cell) {
+        const column = getColumnByCell(grid, cell);
+        const hoverState = grid.hoverState = { cell: cell, column: column, row: row };
+        grid.$emit('cellmouseenter', hoverState.row, hoverState.column, hoverState.cell, event);
+      }
+
+      // 判断是否text-overflow, 如果是就显示tooltip
+      const cellChild = getChild(event);
+
+      if (cellChild.scrollWidth > cellChild.offsetWidth) {
+        this.tooltipDisabled = false;
+      } else {
+        this.tooltipDisabled = true;
+      }
+    },
+
+    handleCellMouseLeave(event) {
+      let grid = this.$parent;
+      const cell = getCell(event);
+
+      if (cell) {
+        const oldHoverState = grid.hoverState;
+        grid.$emit('cellmouseleave', oldHoverState.row, oldHoverState.column, oldHoverState.cell, event);
+      }
+    },
+
+    handleMouseEnter(index) {
+      this.$parent.hoverRowIndex = index;
+    },
+
+    handleClick(event, row) {
+      let grid = this.$parent;
+      const cell = getCell(event);
+
+      if (cell) {
+        const column = getColumnByCell(grid, cell);
+        if (column) {
+          grid.$emit('cellclick', row, column, cell, event);
+        }
+      }
+
+      if (grid.selectionMode === 'single') {
+        grid.selected = row;
+        grid.$emit('selectionchange', row);
+      }
+
+      grid.$emit('rowclick', row, event);
+    },
+
+    handleCreate(vm) {
+      document.body.appendChild(vm.$refs.popper);
+      vm.updatePopper();
+    },
+
+    $getPropertyText(row, property, columnId) {
+      let grid = this.$parent;
+      const column = getColumnById(grid, columnId);
+      if (column && column.formatter) {
+        return column.formatter(row, column);
+      }
+
+      return getValueByPath(row, property);
+    }
+  }
+};

+ 0 - 142
packages/table/src/table-body.vue

@@ -1,142 +0,0 @@
-<template>
-  <table class="el-table__body" cellspacing="0" cellpadding="0" border="0">
-    <tbody>
-    <tr v-for="row in data"
-      @click="handleClick($event, row)" @mouseenter="handleMouseEnter($index)"
-      :class="{
-        'current-row': row === $parent.$parent.selected,
-        hover: $parent.$parent.hoverRowIndex === $index,
-        'positive-row': row.$positive,
-        'info-row': row.$info,
-        'warning-row': row.$warning,
-        'negative-row': row.$negative
-      }">
-      <td v-for="column in columns" :class="column.id"
-          @mouseenter="handleCellMouseEnter($event, row)"
-          @mouseleave="handleCellMouseLeave($event)">
-        <partial v-if="column.template" :name="'template:' + column.id"></partial>
-        <partial v-else name="template:default"></partial>
-      </td>
-      <td class="gutter" v-if="!fixed"></td>
-    </tr>
-    </tbody>
-  </table>
-</template>
-
-<script type="text/babel">
-  const getColumnById = function(grid, columnId) {
-    let column = null;
-    grid.columns.forEach(function(item) {
-      if (item.id === columnId) {
-        column = item;
-      }
-    });
-    return column;
-  };
-
-  const getColumnByCell = function(grid, cell) {
-    const matches = (cell.className || '').match(/grid_[^\s]+/gm);
-    if (matches) {
-      return getColumnById(grid, matches[0]);
-    }
-    return null;
-  };
-
-  import { getValueByPath, getCell, orderBy, getChild } from './util';
-
-  export default {
-    props: {
-      columns: {},
-      data: {},
-      fixed: {},
-      selection: {
-        default() {
-          return [];
-        }
-      }
-    },
-
-    data() {
-      return {
-        tooltipDisabled: true
-      };
-    },
-
-    filters: {
-      orderBy
-    },
-
-    partials: {
-      'template:default': '<div class="cell">{{ $getPropertyText(row, column.property, column.id) }}</div>'
-    },
-
-    methods: {
-      handleCellMouseEnter(event, row) {
-        let grid = this.$parent;
-        const cell = getCell(event);
-
-        if (cell) {
-          const column = getColumnByCell(grid, cell);
-          const hoverState = grid.hoverState = { cell: cell, column: column, row: row };
-          grid.$emit('cell-mouse-enter', hoverState.row, hoverState.column, hoverState.cell, event);
-        }
-
-        // 判断是否text-overflow, 如果是就显示tooltip
-        const cellChild = getChild(event);
-        if (cellChild.scrollWidth > cellChild.offsetWidth) {
-          this.tooltipDisabled = false;
-        } else {
-          this.tooltipDisabled = true;
-        }
-      },
-
-      handleCellMouseLeave(event) {
-        let grid = this.$parent;
-        const cell = getCell(event);
-
-        if (cell) {
-          const oldHoverState = grid.hoverState;
-          grid.$emit('cell-mouse-leave', oldHoverState.row, oldHoverState.column, oldHoverState.cell, event);
-        }
-      },
-
-      handleMouseEnter(index) {
-        this.$parent.hoverRowIndex = index;
-      },
-
-      handleClick(event, row) {
-        let grid = this.$parent;
-        const cell = getCell(event);
-
-        if (cell) {
-          const column = getColumnByCell(grid, cell);
-          if (column) {
-            grid.$emit('cell-click', row, column, cell, event);
-          }
-        }
-
-        if (grid.selectionMode === 'single') {
-          grid.selected = row;
-          grid.$emit('selection-change', row);
-        }
-
-        grid.$emit('row-click', row, event);
-      },
-
-      handleCreate(vm) {
-        document.body.appendChild(vm.popper);
-        vm.updatePopper();
-      },
-
-      $getPropertyText(row, property, columnId) {
-        let grid = this.$parent;
-        const column = getColumnById(grid, columnId);
-        if (column && column.formatter) {
-          return column.formatter(row, column);
-        }
-
-        return getValueByPath(row, property);
-      }
-    }
-  };
-</script>

+ 255 - 0
packages/table/src/table-column.js

@@ -0,0 +1,255 @@
+import ElCheckbox from 'packages/checkbox/index.js';
+import ElTag from 'packages/tag/index.js';
+import objectAssign from 'object-assign';
+
+let columnIdSeed = 1;
+
+const defaults = {
+  default: {
+    direction: ''
+  },
+  selection: {
+    width: 48,
+    minWidth: 48,
+    realWidth: 48,
+    direction: ''
+  },
+  index: {
+    width: 48,
+    minWidth: 48,
+    realWidth: 48,
+    direction: ''
+  },
+  filter: {
+    headerTemplate: function(h) { return <span>filter header</span>; },
+    direction: ''
+  }
+};
+
+const forced = {
+  selection: {
+    headerTemplate: function(h) { return <div><el-checkbox nativeOn-click={ this.toggleAllSelection } domProps-value={ this.allSelected } on-input={ ($event) => this.$emit('allselectedchange', $event) } /></div>; },
+    template: function(h, { row }) { return <el-checkbox domProps-value={ row.$selected } on-input={ ($event) => {row.$selected = $event;} } />; },
+    sortable: false,
+    resizable: false
+  },
+  index: {
+    headerTemplate: function(h) { return <div>#</div>; },
+    template: function(h, { row, $index }) { return <div>{ $index + 1 }</div>; },
+    sortable: false
+  },
+  filter: {
+    headerTemplate: function(h) { return <div>#</div>; },
+    template: function(h, { row, column }) { return <el-tag type="primary" style="height: 16px; line-height: 16px; min-width: 40px; text-align: center">{ row[column.property] }</el-tag>; },
+    resizable: 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;
+      }
+    }
+  }
+
+  return column;
+};
+
+export default {
+  name: 'el-table-column',
+
+  props: {
+    type: {
+      type: String,
+      default: 'default'
+    },
+    label: String,
+    property: String,
+    width: {},
+    minWidth: {},
+    template: String,
+    sortable: {
+      type: Boolean,
+      default: false
+    },
+    resizable: {
+      type: Boolean,
+      default: true
+    },
+    showTooltipWhenOverflow: Boolean,
+    formatter: Function
+  },
+
+  render(h) {
+    return <div />;
+  },
+
+  data() {
+    return {
+      isChildColumn: false,
+      columns: [],
+      row: {}
+    };
+  },
+
+  components: {
+    ElCheckbox,
+    ElTag
+  },
+
+  created() {
+    let columnId = this.columnId = (this.$parent.gridId || (this.$parent.columnId + '_')) + 'column_' + columnIdSeed++;
+
+    let parent = this.$parent;
+    if (!parent.gridId) {
+      this.isChildColumn = true;
+    }
+
+    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;
+      }
+    } else {
+      minWidth = 80;
+    }
+
+    let isColumnGroup = false;
+    let template;
+
+    let property = this.property;
+    if (property) {
+      template = function(h, { row }) {
+        return <span>{ this.$getPropertyText(row, property, columnId) }</span>;
+      };
+    }
+
+    let column = getDefaultColumn(type, {
+      id: columnId,
+      label: this.label,
+      property: this.property,
+      type,
+      template,
+      minWidth,
+      width,
+      isColumnGroup,
+      realWidth: width || minWidth,
+      sortable: this.sortable,
+      resizable: this.resizable,
+      formatter: this.formatter
+    });
+
+    objectAssign(column, forced[type] || {});
+
+    let renderColumn = column.template;
+    let _self = this;
+    column.template = function(h, data) {
+      if (_self.$vnode.data.inlineTemplate) {
+        let costomRender = _self.$options.render;
+
+        renderColumn = function(_h) {
+          return costomRender.call(data, _h);
+        };
+      };
+
+      return _self.showTooltipWhenOverflow
+        ? <el-tooltip
+            on-created={ this.handleCreate }
+            effect={ this.effect }
+            placement="top"
+            disabled={ this.tooltipDisabled }>
+            <div class="cell">{ renderColumn.call(this._renderProxy, h, data) }</div>
+            <span slot="content">{ renderColumn.call(this._renderProxy, h, data) }</span>
+          </el-tooltip>
+        : <div class="cell">{ renderColumn.call(this._renderProxy, h, data) }</div>;
+    };
+
+    this.columnConfig = column;
+  },
+
+  destroyed() {
+    if (!this.$parent) {
+      return;
+    }
+    let columns = this.$parent.columns;
+    if (columns) {
+      let columnId = this.columnId;
+      for (let i = 0, j = columns.length; i < j; i++) {
+        let column = columns[i];
+
+        if (column.id === columnId) {
+          columns.splice(i, 1);
+          break;
+        }
+      }
+    }
+
+    if (this.isChildColumn) {
+      if (this.$parent.$parent.$ready) {
+        this.$parent.$parent.debouncedReRender();
+      }
+    } else {
+      if (this.$parent.$ready) {
+        this.$parent.debouncedReRender();
+      }
+    }
+  },
+
+  watch: {
+    label(newVal) {
+      if (this.columnConfig) {
+        this.columnConfig.label = newVal;
+      }
+    },
+
+    property(newVal) {
+      if (this.columnConfig) {
+        this.columnConfig.property = newVal;
+      }
+    }
+  },
+
+  mounted() {
+    let parent = this.$parent;
+    let columnConfig = this.columnConfig;
+    let columnIndex;
+
+    if (!this.isChildColumn) {
+      columnIndex = [].indexOf.call(parent.$refs.hiddenColumns.children, this.$el);
+    } else {
+      columnIndex = [].indexOf.call(parent.$el.children, this.$el);
+    }
+
+    parent.columns.splice(columnIndex, 0, columnConfig);
+
+    if (this.isChildColumn) {
+      parent.columnConfig.columns = parent.columns;
+
+      if (parent.$parent.$ready) {
+        parent.$parent.debouncedReRender();
+      }
+    } else {
+      if (parent.$ready) {
+        parent.debouncedReRender();
+      }
+    }
+  }
+};

+ 0 - 254
packages/table/src/table-column.vue

@@ -1,254 +0,0 @@
-<template>
-  <div><slot></slot></div>
-</template>
-
-<script type="text/babel">
-  import ElCheckbox from 'packages/checkbox/index.js';
-  import ElTag from 'packages/tag/index.js';
-
-  let columnIdSeed = 1;
-
-  const defaults = {
-    default: {
-      direction: ''
-    },
-    selection: {
-      width: 48,
-      minWidth: 48,
-      realWidth: 48,
-      direction: ''
-    },
-    index: {
-      width: 48,
-      minWidth: 48,
-      realWidth: 48,
-      direction: ''
-    },
-    filter: {
-      headerTemplate: 'filter header',
-      direction: ''
-    }
-  };
-
-  const forced = {
-    selection: {
-      // TODO :value.sync="$parent.$parent.selection"
-      headerTemplate: '<div><el-checkbox @click="toggleAllSelection($event)" :value.sync="allSelected"></el-checkbox></div>',
-      template: '<el-checkbox :value.sync="row.$selected"></el-checkbox>',
-      sortable: false,
-      resizable: false
-    },
-    index: {
-      headerTemplate: '<div>#</div>',
-      template: '{{ $parent.$index + 1 }}',
-      sortable: false
-    },
-    filter: {
-      headerTemplate: '<div>#</div>',
-      template: '<el-tag type="primary" style="height: 16px; line-height: 16px; min-width: 40px; text-align: center">{{ row[column.property] }}</el-tag>',
-      resizable: false
-    }
-  };
-
-  const getDefaultColumn = function(type, options) {
-    const column = {};
-
-    Object.assign(column, defaults[type || 'default']);
-
-    for (let name in options) {
-      if (options.hasOwnProperty(name)) {
-        const value = options[name];
-        if (typeof value !== 'undefined') {
-          column[name] = value;
-        }
-      }
-    }
-
-    return column;
-  };
-
-  import Vue from 'vue';
-
-  export default {
-    name: 'el-table-column',
-
-    props: {
-      type: {
-        type: String,
-        default: 'default'
-      },
-      label: String,
-      property: String,
-      width: {},
-      minWidth: {},
-      template: String,
-      sortable: {
-        type: Boolean,
-        default: false
-      },
-      resizable: {
-        type: Boolean,
-        default: true
-      },
-      formatter: Function
-    },
-
-    data() {
-      return {
-        isChildColumn: false,
-        columns: []
-      };
-    },
-
-    components: {
-      ElCheckbox,
-      ElTag
-    },
-
-    beforeCompile() {
-      let columnId = this.columnId = (this.$parent.gridId || (this.$parent.columnId + '_')) + 'column_' + columnIdSeed++;
-
-      let parent = this.$parent;
-      if (!parent.gridId) {
-        this.isChildColumn = true;
-      }
-
-      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;
-        }
-      } else {
-        minWidth = 80;
-      }
-
-      let options = this.$options;
-      let tagName = options.el.tagName.toLowerCase();
-      let isColumnGroup = false;
-      let template = this.template;
-
-      if (options._content) {
-        let content = options._content.innerHTML;
-        if (content.indexOf(`</${tagName}>`) === -1) {
-          options._content = null;
-          template = content;
-        } else {
-          template = null;
-          isColumnGroup = true;
-        }
-      }
-
-      let property = this.property;
-      if ((!template || /^\s*$/.test(template)) && property) {
-        template = `{{ $getPropertyText(row, '${property}', '${columnId}') }}`;
-      }
-
-      let column = getDefaultColumn(type, {
-        id: columnId,
-        label: this.label,
-        property: this.property,
-        type,
-        template,
-        minWidth,
-        width,
-        isColumnGroup,
-        realWidth: width || minWidth,
-        sortable: this.sortable,
-        resizable: this.resizable,
-        formatter: this.formatter
-      });
-
-      Object.assign(column, forced[type] || {});
-
-      if (column.headerTemplate) {
-        Vue.partial('headerTemplate:' + column.id, column.headerTemplate);
-      }
-
-      if (column.template) {
-//        Vue.partial('template:' + column.id, `<div class="cell">${column.template}</div>`);
-        Vue.partial('template:' + column.id, `<el-tooltip @created="handleCreate" :effect="effect" placement="top" :disabled="tooltipDisabled"><div class="cell">${column.template}</div><span slot="content">${column.template}</span></el-tooltip>`);
-      }
-
-      this.columnConfig = column;
-    },
-
-    detached() {
-      if (!this.$parent) {
-        return;
-      }
-      let columns = this.$parent.columns;
-      if (columns) {
-        let columnId = this.columnId;
-        for (let i = 0, j = columns.length; i < j; i++) {
-          let column = columns[i];
-
-          if (column.id === columnId) {
-            columns.splice(i, 1);
-            break;
-          }
-        }
-      }
-
-      if (this.isChildColumn) {
-        if (this.$parent.$parent.$ready) {
-          this.$parent.$parent.debouncedReRender();
-        }
-      } else {
-        if (this.$parent.$ready) {
-          this.$parent.debouncedReRender();
-        }
-      }
-    },
-
-    watch: {
-      label(newVal) {
-        if (this.columnConfig) {
-          this.columnConfig.label = newVal;
-        }
-      },
-
-      property(newVal) {
-        if (this.columnConfig) {
-          this.columnConfig.property = newVal;
-        }
-      }
-    },
-
-    ready() {
-      let parent = this.$parent;
-      let columnConfig = this.columnConfig;
-      let columnIndex;
-
-      if (!this.isChildColumn) {
-        columnIndex = [].indexOf.call(parent.$els.hiddenColumns.children, this.$el);
-      } else {
-        columnIndex = [].indexOf.call(parent.$el.children, this.$el);
-      }
-
-      parent.columns.splice(columnIndex, 0, columnConfig);
-
-      if (this.isChildColumn) {
-        parent.columnConfig.columns = parent.columns;
-
-        if (parent.$parent.$ready) {
-          parent.$parent.debouncedReRender();
-        }
-      } else {
-        if (parent.$ready) {
-          parent.debouncedReRender();
-        }
-      }
-    }
-  };
-</script>

+ 232 - 0
packages/table/src/table-header.js

@@ -0,0 +1,232 @@
+import ElCheckbox from 'packages/checkbox/index.js';
+import ElTag from 'packages/tag/index.js';
+
+export default {
+  name: 'el-table-header',
+
+  render(h) {
+    return (
+      <table
+        class="el-table__header"
+        cellspacing="0"
+        cellpadding="0"
+        border="0">
+        {
+          this._l(this.columns, column =>
+            <colgroup
+              name={ column.id }
+              width={ column.realWidth || column.width }
+            />).concat(
+              <thead>
+                <tr>
+                  {
+                    this._l(this.columns, column =>
+                      <th
+                        on-mousemove={ ($event) => this.handleMouseMove($event, column) }
+                        on-mouseout={ this.handleMouseOut }
+                        on-mousedown={ ($event) => this.handleMouseDown($event, column) }
+                        on-click={ ($event) => this.handleHeaderClick($event, column) }
+                        class={ [column.id, column.direction] }>
+                        {
+                          [
+                            column.headerTemplate
+                              ? column.headerTemplate.call(this._renderProxy, h)
+                              : <div>{ column.label }</div>,
+                            column.sortable
+                              ? <div class="caret-wrapper">
+                                  <i class="sort-caret ascending"></i>
+                                  <i class="sort-caret descending"></i>
+                                </div>
+                              : ''
+                          ]
+                        }
+                      </th>
+                    ).concat(<th
+                              class="gutter"
+                              style={{
+                                width: (this.$parent.showVScrollBar
+                                          ? this.$parent.gutterWidth
+                                          : 0
+                                        ) + 'px'
+                              }}>&nbsp;</th>)
+                  }
+                </tr>
+              </thead>
+            )
+        }
+      </table>
+    );
+  },
+
+  props: {
+    columns: {},
+    fixed: Boolean,
+    allSelected: {
+      default: Boolean
+    },
+    border: Boolean
+  },
+
+  components: {
+    ElCheckbox,
+    ElTag
+  },
+
+  methods: {
+    toggleAllSelection($event) {
+      this.$parent.toggleAllSelection($event);
+    },
+
+    handleMouseDown(event, column) {
+      if (this.draggingColumn && this.border) {
+        this.dragging = true;
+
+        this.$parent.resizeProxyVisible = true;
+
+        const gridEl = this.$parent.$el;
+        const gridLeft = gridEl.getBoundingClientRect().left;
+        const columnEl = this.$el.querySelector(`th.${column.id}`);
+        const columnRect = columnEl.getBoundingClientRect();
+        const minLeft = columnRect.left - gridLeft + 30;
+
+        columnEl.classList.add('noclick');
+
+        this.dragState = {
+          startMouseLeft: event.clientX,
+          startLeft: columnRect.right - gridLeft,
+          startColumnLeft: columnRect.left - gridLeft,
+          gridLeft: gridLeft
+        };
+
+        const resizeProxy = this.$parent.$refs.resizeProxy;
+        resizeProxy.style.left = this.dragState.startLeft + 'px';
+
+        document.onselectstart = function() { return false; };
+        document.ondragstart = function() { return false; };
+
+        const mousemove = (event) => {
+          const deltaLeft = event.clientX - this.dragState.startMouseLeft;
+          const proxyLeft = this.dragState.startLeft + deltaLeft;
+
+          resizeProxy.style.left = Math.max(minLeft, proxyLeft) + 'px';
+        };
+
+        const mouseup = () => {
+          if (this.dragging) {
+            const finalLeft = parseInt(resizeProxy.style.left, 10);
+            const columnWidth = finalLeft - this.dragState.startColumnLeft;
+            column.width = column.realWidth = columnWidth;
+
+            this.$nextTick(() => {
+              this.$parent.$calcColumns();
+            });
+
+            document.body.style.cursor = '';
+            this.dragging = false;
+            this.draggingColumn = null;
+            this.dragState = {};
+
+            this.$parent.resizeProxyVisible = false;
+          }
+
+          document.removeEventListener('mousemove', mousemove);
+          document.removeEventListener('mouseup', mouseup);
+          document.onselectstart = null;
+          document.ondragstart = null;
+
+          setTimeout(function() {
+            columnEl.classList.remove('noclick');
+          }, 0);
+        };
+
+        document.addEventListener('mousemove', mousemove);
+        document.addEventListener('mouseup', mouseup);
+      }
+    },
+
+    handleMouseMove(event, column) {
+      const target = event.target;
+
+      if (!column || !column.resizable) return;
+
+      if (!this.dragging && this.border) {
+        let rect = target.getBoundingClientRect();
+
+        if (rect.width > 12 && rect.right - event.pageX < 8) {
+          document.body.style.cursor = 'col-resize';
+          this.draggingColumn = column;
+        } else if (!this.dragging) {
+          document.body.style.cursor = '';
+          this.draggingColumn = null;
+          if (column.sortable) document.body.style.cursor = 'pointer';
+        }
+      }
+    },
+
+    handleMouseOut() {
+      document.body.style.cursor = '';
+    },
+
+    handleHeaderClick(event, column) {
+      let target = event.target;
+      while (target && target.tagName !== 'TH') {
+        target = target.parentNode;
+      }
+
+      if (target && target.tagName === 'TH') {
+        if (target.classList.contains('noclick')) {
+          target.classList.remove('noclick');
+          return;
+        }
+      }
+
+      if (!column.sortable) return;
+
+      const grid = this.$parent;
+
+      if (grid.sortingColumn !== column) {
+        if (grid.sortingColumn) {
+          grid.sortingColumn.direction = '';
+        }
+        grid.sortingColumn = column;
+        grid.sortingProperty = column.property;
+      }
+
+      if (!column.direction) {
+        column.direction = 'ascending';
+      } else if (column.direction === 'ascending') {
+        column.direction = 'descending';
+      } else {
+        column.direction = '';
+        grid.sortingColumn = null;
+        grid.sortingProperty = null;
+      }
+
+      grid.sortingDirection = column.direction === 'descending' ? -1 : 1;
+    },
+
+    $setVisibleFilter(property) {
+      if (this.visibleFilter) {
+        this.visibleFilter = null;
+      } else {
+        this.visibleFilter = property;
+      }
+    }
+  },
+
+  watch: {
+    visibleFilter(val) {
+      this.$parent.visibleFilter = val;
+    }
+  },
+
+  data() {
+    return {
+      draggingColumn: null,
+      dragging: false,
+      dragState: {},
+      columnsMap: null,
+      visibleFilter: null
+    };
+  }
+};

+ 0 - 198
packages/table/src/table-header.vue

@@ -1,198 +0,0 @@
-<template>
-  <table class="el-table__header" cellspacing="0" cellpadding="0" border="0">
-    <colgroup v-for="column in columns" :name="column.id" :width="column.realWidth || column.width"></colgroup>
-    <thead>
-      <tr>
-        <th v-for="column in columns"
-          @mousemove="handleMouseMove($event, column)"
-          @mouseout="handleMouseOut"
-          @mousedown="handleMouseDown($event, column)"
-          @click="handleHeaderClick($event, column)"
-          class="{{ column.id }} {{column.direction}}">
-          <partial v-if="column.headerTemplate" :name="'headerTemplate:' + column.id"></partial>
-          <partial v-else name="default"></partial><div class="caret-wrapper" v-if="column.sortable"><i class="sort-caret ascending"></i><i class="sort-caret descending"></i></div>
-        </th>
-        <th class="gutter" :style="{ width: ($parent.showVScrollBar ? $parent.gutterWidth : 0) + 'px' }">&nbsp;</th>
-      </tr>
-    </thead>
-  </table>
-</template>
-
-<script type="text/babel">
-  import Vue from 'vue';
-
-  export default {
-    name: 'el-table-header',
-
-    props: {
-      columns: {},
-      fixed: Boolean,
-      allSelected: {
-        default: Boolean
-      },
-      border: Boolean
-    },
-
-    partials: {
-      default: '<div>{{column.label}}</div>'
-    },
-
-    methods: {
-      toggleAllSelection($event) {
-        this.$parent.toggleAllSelection($event);
-      },
-
-      handleMouseDown(event, column) {
-        if (this.draggingColumn && this.border) {
-          this.dragging = true;
-
-          this.$parent.resizeProxyVisible = true;
-
-          const gridEl = this.$parent.$el;
-          const gridLeft = gridEl.getBoundingClientRect().left;
-          const columnEl = this.$el.querySelector(`th.${column.id}`);
-          const columnRect = columnEl.getBoundingClientRect();
-          const minLeft = columnRect.left - gridLeft + 30;
-
-          columnEl.classList.add('noclick');
-
-          this.dragState = {
-            startMouseLeft: event.clientX,
-            startLeft: columnRect.right - gridLeft,
-            startColumnLeft: columnRect.left - gridLeft,
-            gridLeft: gridLeft
-          };
-
-          const resizeProxy = this.$parent.$els.resizeProxy;
-          resizeProxy.style.left = this.dragState.startLeft + 'px';
-
-          document.onselectstart = function() { return false; };
-          document.ondragstart = function() { return false; };
-
-          const mousemove = (event) => {
-            const deltaLeft = event.clientX - this.dragState.startMouseLeft;
-            const proxyLeft = this.dragState.startLeft + deltaLeft;
-
-            resizeProxy.style.left = Math.max(minLeft, proxyLeft) + 'px';
-          };
-
-          const mouseup = () => {
-            if (this.dragging) {
-              const finalLeft = parseInt(resizeProxy.style.left, 10);
-              const columnWidth = finalLeft - this.dragState.startColumnLeft;
-              column.width = column.realWidth = columnWidth;
-
-              Vue.nextTick(() => {
-                this.$parent.$calcColumns();
-              });
-
-              document.body.style.cursor = '';
-              this.dragging = false;
-              this.draggingColumn = null;
-              this.dragState = {};
-
-              this.$parent.resizeProxyVisible = false;
-            }
-
-            document.removeEventListener('mousemove', mousemove);
-            document.removeEventListener('mouseup', mouseup);
-            document.onselectstart = null;
-            document.ondragstart = null;
-
-            setTimeout(function() {
-              columnEl.classList.remove('noclick');
-            }, 0);
-          };
-
-          document.addEventListener('mousemove', mousemove);
-          document.addEventListener('mouseup', mouseup);
-        }
-      },
-
-      handleMouseMove(event, column) {
-        const target = event.target;
-
-        if (!column || !column.resizable) return;
-
-        if (!this.dragging && this.border) {
-          let rect = target.getBoundingClientRect();
-
-          if (rect.width > 12 && rect.right - event.pageX < 8) {
-            document.body.style.cursor = 'col-resize';
-            this.draggingColumn = column;
-          } else if (!this.dragging) {
-            document.body.style.cursor = '';
-            this.draggingColumn = null;
-            if (column.sortable) document.body.style.cursor = 'pointer';
-          }
-        }
-      },
-
-      handleMouseOut() {
-        document.body.style.cursor = '';
-      },
-
-      handleHeaderClick(event, column) {
-        let target = event.target;
-        while (target && target.tagName !== 'TH') {
-          target = target.parentNode;
-        }
-
-        if (target && target.tagName === 'TH') {
-          if (target.classList.contains('noclick')) {
-            target.classList.remove('noclick');
-            return;
-          }
-        }
-
-        if (!column.sortable) return;
-
-        const grid = this.$parent;
-
-        if (grid.sortingColumn !== column) {
-          if (grid.sortingColumn) {
-            grid.sortingColumn.direction = '';
-          }
-          grid.sortingColumn = column;
-          grid.sortingProperty = column.property;
-        }
-
-        if (!column.direction) {
-          column.direction = 'ascending';
-        } else if (column.direction === 'ascending') {
-          column.direction = 'descending';
-        } else {
-          column.direction = '';
-          grid.sortingColumn = null;
-          grid.sortingProperty = null;
-        }
-
-        grid.sortingDirection = column.direction === 'descending' ? -1 : 1;
-      },
-
-      $setVisibleFilter(property) {
-        if (this.visibleFilter) {
-          this.visibleFilter = null;
-        } else {
-          this.visibleFilter = property;
-        }
-      }
-    },
-
-    watch: {
-      visibleFilter(val) {
-        this.$parent.visibleFilter = val;
-      }
-    },
-
-    data() {
-      return {
-        draggingColumn: null,
-        dragging: false,
-        dragState: {},
-        columnsMap: null,
-        visibleFilter: null
-      };
-    }
-  };
-</script>

+ 49 - 55
packages/table/src/table.vue

@@ -1,36 +1,36 @@
 <template>
   <div class="el-table" :class="{ 'el-table--fit': fit, 'el-table--striped': stripe, 'el-table--border': border }" @mouseleave="handleMouseLeave($event)">
-    <div class="hidden-columns" v-el:hidden-columns><slot></slot></div>
+    <div class="hidden-columns" ref="hiddenColumns"><slot></slot></div>
     <div class="el-table__header-wrapper">
-      <table-header :columns="columns" :all-selected.sync="allSelected" :selection.sync="selection" :style="{ width: bodyWidth ? bodyWidth + 'px' : '' }" :border="border"></table-header>
+      <table-header :columns="columns" :all-selected="allSelected" @allselectedchange="handleAllSelectedChange" :selection="selection" :style="{ width: bodyWidth ? bodyWidth + 'px' : '' }" :border="border"></table-header>
     </div>
     <div class="el-table__body-wrapper">
-      <table-body :columns="columns" :selection.sync="selection" :data="data | orderBy sortingProperty sortingDirection" :style="{ width: bodyWidth ? bodyWidth - (showVScrollBar ? gutterWidth : 0 ) + 'px' : '' }"></table-body>
+      <table-body :columns="columns" :selection="selection" :data="filterData" :style="{ width: bodyWidth ? bodyWidth - (showVScrollBar ? gutterWidth : 0 ) + 'px' : '' }"></table-body>
     </div>
-    <div class="el-table__fixed" :style="{ width: fixedBodyWidth ? fixedBodyWidth + 'px' : '' }" v-el:fixed>
+    <div class="el-table__fixed" :style="{ width: fixedBodyWidth ? fixedBodyWidth + 'px' : '' }" ref="fixed">
       <div class="el-table__fixed-header-wrapper" v-if="fixedColumnCount > 0">
-        <table-header :columns="fixedColumns" :all-selected.sync="allSelected" :selection.sync="selection" :style="{ width: fixedBodyWidth ? fixedBodyWidth + 'px' : '' }" :border="border"></table-header>
+        <table-header :columns="fixedColumns" :all-selected="allSelected" @allselectedchange="handleAllSelectedChange" :selection="selection" :style="{ width: fixedBodyWidth ? fixedBodyWidth + 'px' : '' }" :border="border"></table-header>
       </div>
       <div class="el-table__fixed-body-wrapper" v-if="fixedColumnCount > 0" :style="{ top: headerHeight + 'px' }">
-        <table-body :columns="fixedColumns" fixed :selection.sync="selection" :data="data | orderBy sortingProperty sortingDirection" :style="{ width: fixedBodyWidth ? fixedBodyWidth + 'px' : '' }"></table-body>
+        <table-body :columns="fixedColumns" fixed :selection="selection" :data="filterData" :style="{ width: fixedBodyWidth ? fixedBodyWidth + 'px' : '' }"></table-body>
       </div>
     </div>
-    <div class="el-table__column-resize-proxy" v-el:resize-proxy v-show="resizeProxyVisible"></div>
+    <div class="el-table__column-resize-proxy" ref="resizeProxy" v-show="resizeProxyVisible"></div>
     <slot name="bottom"></slot>
   </div>
 </template>
 
 <script type="text/babel">
-  import Vue from 'vue';
   import throttle from 'throttle-debounce/throttle';
   import debounce from 'throttle-debounce/debounce';
-  import { getScrollBarWidth } from './util';
+  import { getScrollBarWidth, orderBy } from './util';
+  import objectAssign from 'object-assign';
 
   let gridIdSeed = 1;
   let GUTTER_WIDTH;
 
-  import TableBody from './table-body.vue';
-  import TableHeader from './table-header.vue';
+  import TableBody from './table-body';
+  import TableHeader from './table-header';
 
   export default {
     name: 'el-table',
@@ -84,24 +84,16 @@
       }
     },
 
-    events: {
-      onresize() {
-        Vue.nextTick(() => {
-          this.$calcColumns();
-        });
-      }
-    },
-
-    partials: {
-      default: '<div>{{column.label}}</div>'
-    },
-
     components: {
       TableHeader,
       TableBody
     },
 
     methods: {
+      handleAllSelectedChange(val) {
+        this.allSelected = val;
+      },
+
       doOnDataChange(data) {
         data = data || [];
 
@@ -111,7 +103,7 @@
             if (!this.allowNoSelection) {
               this.selected = data[0];
               if (this.selected !== oldSelection) {
-                this.$emit('selection-change', this.selected);
+                this.$emit('selectionchange', this.selected);
               }
             }
           } else if (data.indexOf(oldSelection) === -1) {
@@ -121,7 +113,7 @@
               this.selected = null;
             }
             if (this.selected !== oldSelection) {
-              this.$emit('selection-change', this.selected);
+              this.$emit('selectionchange', this.selected);
             }
           }
         }
@@ -129,7 +121,7 @@
 
       toggleAllSelection() {
         setTimeout(() => {
-          this.data.forEach(item => {
+          this.tableData.forEach(item => {
             item.$selected = this.allSelected;
           });
         }, 0);
@@ -241,7 +233,7 @@
           this.fixedBodyWidth = fixedBodyWidth;
         }
 
-        Vue.nextTick(() => {
+        this.$nextTick(() => {
           this.headerHeight = this.$el.querySelector('.el-table__header-wrapper').offsetHeight;
         });
       },
@@ -258,7 +250,7 @@
           gridWrapper.style.height = bodyHeight + 'px';
 
           this.$el.style.height = height + 'px';
-          this.$els.fixed.style.height = height + 'px';
+          this.$refs.fixed.style.height = height + 'px';
 
           const fixedBodyWrapper = this.$el.querySelector('.el-table__fixed-body-wrapper');
           if (fixedBodyWrapper) {
@@ -276,7 +268,7 @@
       },
 
       updateScrollInfo() {
-        Vue.nextTick(() => {
+        this.$nextTick(() => {
           if (this.$el) {
             let gridBodyWrapper = this.$el.querySelector('.el-table__body-wrapper');
             let gridBody = this.$el.querySelector('.el-table__body-wrapper .el-table__body');
@@ -310,7 +302,7 @@
           window.addEventListener('resize', this.windowResizeListener);
         }
 
-        Vue.nextTick(() => {
+        this.$nextTick(() => {
           if (this.height) {
             this.$calcHeight(this.height);
           }
@@ -319,6 +311,7 @@
     },
 
     created() {
+      this.tableData = this.data;
       this.gridId = 'grid_' + gridIdSeed + '_';
 
       if (GUTTER_WIDTH === undefined) {
@@ -334,10 +327,8 @@
     computed: {
       selection() {
         if (this.selectionMode === 'multiple') {
-          const data = this.data || [];
-          return data.filter(function(item) {
-            return item.$selected === true;
-          });
+          const data = this.tableData || [];
+          return data.filter(item => item.$selected === true);
         } else if (this.selectionMode === 'single') {
           return this.selected;
         } else {
@@ -351,6 +342,10 @@
         return columns.filter(function(item, index) {
           return index < fixedColumnCount;
         });
+      },
+
+      filterData() {
+        return orderBy(this.tableData, this.sortingProperty, this.sortingDirection);
       }
     },
 
@@ -360,9 +355,9 @@
       },
 
       selection(val) {
-        this.$emit('selection-change', val);
+        this.$emit('selectionchange', val);
         if (this.selectionMode === 'multiple') {
-          this.allSelected = val.length === this.data.length;
+          this.allSelected = val.length === this.tableData.length;
         }
       },
 
@@ -374,26 +369,12 @@
         this.$calcHeight(value);
       },
 
-      data(newVal) {
+      tableData(newVal) {
         this.doOnDataChange(newVal);
         this.updateScrollInfo();
       }
     },
 
-    beforeCompile() {
-      const styleNode = document.createElement('style');
-      styleNode.type = 'text/css';
-      styleNode.rel = 'stylesheet';
-      styleNode.title = 'Grid Column Style';
-      document.getElementsByTagName('head')[0].appendChild(styleNode);
-
-      this.styleNode = styleNode;
-
-      if (this.data && this.selectionMode === 'multiple') {
-        this.data = this.data.map(item => Object.assign({ '$selected': false }, item));
-      }
-    },
-
     destroyed() {
       if (this.styleNode) {
         this.styleNode.parentNode.removeChild(this.styleNode);
@@ -404,23 +385,36 @@
       }
     },
 
-    ready() {
+    mounted() {
+      const styleNode = document.createElement('style');
+      styleNode.type = 'text/css';
+      styleNode.rel = 'stylesheet';
+      styleNode.title = 'Grid Column Style';
+      document.getElementsByTagName('head')[0].appendChild(styleNode);
+
+      this.styleNode = styleNode;
+
+      if (this.tableData && this.selectionMode === 'multiple') {
+        this.tableData = this.tableData.map(item => objectAssign({ '$selected': false }, item));
+      }
+
       this.doRender();
 
       this.$ready = true;
-      if (this.data) {
-        this.doOnDataChange(this.data);
+      if (this.tableData) {
+        this.doOnDataChange(this.tableData);
       }
       this.updateScrollInfo();
       if (this.fixedColumnCount > 0) {
         this.$nextTick(() => {
-          this.$els.fixed.style.height = this.$el.clientHeight + 'px';
+          this.$refs.fixed.style.height = this.$el.clientHeight + 'px';
         });
       }
     },
 
     data() {
       return {
+        tableData: [],
         showHScrollBar: false,
         showVScrollBar: false,
         hoverRowIndex: null,

+ 1 - 7
packages/table/src/util.js

@@ -77,11 +77,5 @@ export const orderBy = function(array, sortKey, reverse) {
 };
 
 export const getChild = function(event) {
-  let cell = event.target;
-
-  while (cell.children.length) {
-    cell = cell.children[0];
-  }
-
-  return cell;
+  return event.target.querySelector('.cell');
 };

+ 2 - 0
scripts/cooking.demo.js

@@ -86,4 +86,6 @@ cooking.add('externals', externals);
 
 // cooking.config.vue.loaders.html = 'html?minimize=true&conservativeCollapse=false';
 
+cooking.add('vue.loaders')
+
 module.exports = cooking.resolve();

+ 2 - 2
src/index.js

@@ -109,13 +109,13 @@ const install = function(Vue) {
   Vue.prototype.$notify = Notification;
 };
 
-auto install
+// auto install
 if (typeof window !== 'undefined' && window.Vue) {
   install(window.Vue);
 };
 
 module.exports = {
-  install
+  install,
   Group,
   SelectDropdown,
   Pagination,