mirror of https://github.com/ElemeFE/element
commit
62e3e768c3
|
@ -23,7 +23,7 @@
|
|||
}
|
||||
},
|
||||
|
||||
ready() {
|
||||
mounted() {
|
||||
console.log('popup ready');
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<script>
|
||||
import Vue from 'vue';
|
||||
let popup = Vue.extend(require('examples/components/table-filter.vue'));
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
@ -81,6 +80,16 @@
|
|||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleSelectionChange(val) {
|
||||
this.singleSelection = val;
|
||||
},
|
||||
|
||||
handleMultipleSelectionChange(val) {
|
||||
this.multipleSelection = val;
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
singleSelection(val) {
|
||||
console.log('selection: ', val);
|
||||
|
@ -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" @selectionchange="handleMultipleSelectionChange">
|
||||
<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
|
||||
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|
||||
|
@ -604,3 +628,6 @@
|
|||
| sortable | 对应列是否可以排序 | boolean | | false |
|
||||
| type | 对应列的类型。如果设置了 `selection` 则显示多选按钮,如果设置了 `index` 则显示该行的索引(从 1 开始计算) | string | 'selection', 'index' | 0 |
|
||||
| formatter | 用来格式化内容,在 formatter 执行的时候,会传入 row 和 column | function | | |
|
||||
| show-tooltip-when-overflow | 当过长被隐藏时显示 tooltip | Boolean | | false |
|
||||
| inline-template | 指定该属性后可以自定义 column 模板,参考多选的时间列,通过 row 获取行信息。此时不需要配置 property 属性 | | |
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
"q": "^1.4.1",
|
||||
"uppercamelcase": "^1.1.0",
|
||||
"vue-loader": "^9.3.2",
|
||||
"vue": "^2.0.0-rc.1",
|
||||
"vue": "^2.0.0-rc.2",
|
||||
"vue-markdown-loader": "^0.4.0",
|
||||
"vue-popup": "^0.2.2",
|
||||
"vue-router": "^2.0.0-beta.2"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
};
|
|
@ -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>
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
|
@ -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>
|
|
@ -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'
|
||||
}}> </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
|
||||
};
|
||||
}
|
||||
};
|
|
@ -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' }"> </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>
|
|
@ -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,
|
||||
|
|
|
@ -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');
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue