mirror of https://github.com/ElemeFE/element
Table: add header group feature. (#1312)
parent
c3aba68ecc
commit
2f3f5eabc1
|
@ -683,6 +683,115 @@ When you have huge chunks of data to put in a table, you can fix the header and
|
||||||
```
|
```
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
### Grouping table head
|
||||||
|
|
||||||
|
When the data structure is complex, you can use group header to show the data hierarchy.
|
||||||
|
|
||||||
|
:::demo Only need to place el-table-column inside a el-table-column, you can achieve group header.
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<el-table
|
||||||
|
:data="tableData3"
|
||||||
|
border
|
||||||
|
style="width: 100%">
|
||||||
|
<el-table-column
|
||||||
|
prop="date"
|
||||||
|
label="Date"
|
||||||
|
width="150">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="Delivery Info">
|
||||||
|
<el-table-column
|
||||||
|
prop="name"
|
||||||
|
label="Name"
|
||||||
|
width="120">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="Address Info">
|
||||||
|
<el-table-column
|
||||||
|
prop="state"
|
||||||
|
label="State"
|
||||||
|
width="120">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="city"
|
||||||
|
label="City"
|
||||||
|
width="120">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="address"
|
||||||
|
label="Address"
|
||||||
|
width="300">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="zip"
|
||||||
|
label="Zip"
|
||||||
|
width="120">
|
||||||
|
</el-table-column>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
tableData3: [{
|
||||||
|
date: '2016-05-03',
|
||||||
|
name: 'Tom',
|
||||||
|
state: 'California',
|
||||||
|
city: 'Los Angeles',
|
||||||
|
address: 'No. 189, Grove St, Los Angeles',
|
||||||
|
zip: 'CA 90036'
|
||||||
|
}, {
|
||||||
|
date: '2016-05-02',
|
||||||
|
name: 'Tom',
|
||||||
|
state: 'California',
|
||||||
|
city: 'Los Angeles',
|
||||||
|
address: 'No. 189, Grove St, Los Angeles',
|
||||||
|
zip: 'CA 90036'
|
||||||
|
}, {
|
||||||
|
date: '2016-05-04',
|
||||||
|
name: 'Tom',
|
||||||
|
state: 'California',
|
||||||
|
city: 'Los Angeles',
|
||||||
|
address: 'No. 189, Grove St, Los Angeles',
|
||||||
|
zip: 'CA 90036'
|
||||||
|
}, {
|
||||||
|
date: '2016-05-01',
|
||||||
|
name: 'Tom',
|
||||||
|
state: 'California',
|
||||||
|
city: 'Los Angeles',
|
||||||
|
address: 'No. 189, Grove St, Los Angeles',
|
||||||
|
zip: 'CA 90036'
|
||||||
|
}, {
|
||||||
|
date: '2016-05-08',
|
||||||
|
name: 'Tom',
|
||||||
|
state: 'California',
|
||||||
|
city: 'Los Angeles',
|
||||||
|
address: 'No. 189, Grove St, Los Angeles',
|
||||||
|
zip: 'CA 90036'
|
||||||
|
}, {
|
||||||
|
date: '2016-05-06',
|
||||||
|
name: 'Tom',
|
||||||
|
state: 'California',
|
||||||
|
city: 'Los Angeles',
|
||||||
|
address: 'No. 189, Grove St, Los Angeles',
|
||||||
|
zip: 'CA 90036'
|
||||||
|
}, {
|
||||||
|
date: '2016-05-07',
|
||||||
|
name: 'Tom',
|
||||||
|
state: 'California',
|
||||||
|
city: 'Los Angeles',
|
||||||
|
address: 'No. 189, Grove St, Los Angeles',
|
||||||
|
zip: 'CA 90036'
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
### Single select
|
### Single select
|
||||||
|
|
||||||
Single row selection is supported.
|
Single row selection is supported.
|
||||||
|
|
|
@ -689,6 +689,115 @@
|
||||||
```
|
```
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
### 多级表头
|
||||||
|
|
||||||
|
数据结构比较复杂的时候,可使用多级表头来展现数据的层次关系。
|
||||||
|
|
||||||
|
:::demo 只需要在 el-table-column 里面嵌套 el-table-column,就可以实现多级表头。
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<el-table
|
||||||
|
:data="tableData3"
|
||||||
|
border
|
||||||
|
style="width: 100%">
|
||||||
|
<el-table-column
|
||||||
|
prop="date"
|
||||||
|
label="日期"
|
||||||
|
width="150">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="配送信息">
|
||||||
|
<el-table-column
|
||||||
|
prop="name"
|
||||||
|
label="姓名"
|
||||||
|
width="120">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="地址">
|
||||||
|
<el-table-column
|
||||||
|
prop="province"
|
||||||
|
label="省份"
|
||||||
|
width="120">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="city"
|
||||||
|
label="市区"
|
||||||
|
width="120">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="address"
|
||||||
|
label="地址"
|
||||||
|
width="300">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="zip"
|
||||||
|
label="邮编"
|
||||||
|
width="120">
|
||||||
|
</el-table-column>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
tableData3: [{
|
||||||
|
date: '2016-05-03',
|
||||||
|
name: '王小虎',
|
||||||
|
province: '上海',
|
||||||
|
city: '普陀区',
|
||||||
|
address: '上海市普陀区金沙江路 1518 弄',
|
||||||
|
zip: 200333
|
||||||
|
}, {
|
||||||
|
date: '2016-05-02',
|
||||||
|
name: '王小虎',
|
||||||
|
province: '上海',
|
||||||
|
city: '普陀区',
|
||||||
|
address: '上海市普陀区金沙江路 1518 弄',
|
||||||
|
zip: 200333
|
||||||
|
}, {
|
||||||
|
date: '2016-05-04',
|
||||||
|
name: '王小虎',
|
||||||
|
province: '上海',
|
||||||
|
city: '普陀区',
|
||||||
|
address: '上海市普陀区金沙江路 1518 弄',
|
||||||
|
zip: 200333
|
||||||
|
}, {
|
||||||
|
date: '2016-05-01',
|
||||||
|
name: '王小虎',
|
||||||
|
province: '上海',
|
||||||
|
city: '普陀区',
|
||||||
|
address: '上海市普陀区金沙江路 1518 弄',
|
||||||
|
zip: 200333
|
||||||
|
}, {
|
||||||
|
date: '2016-05-08',
|
||||||
|
name: '王小虎',
|
||||||
|
province: '上海',
|
||||||
|
city: '普陀区',
|
||||||
|
address: '上海市普陀区金沙江路 1518 弄',
|
||||||
|
zip: 200333
|
||||||
|
}, {
|
||||||
|
date: '2016-05-06',
|
||||||
|
name: '王小虎',
|
||||||
|
province: '上海',
|
||||||
|
city: '普陀区',
|
||||||
|
address: '上海市普陀区金沙江路 1518 弄',
|
||||||
|
zip: 200333
|
||||||
|
}, {
|
||||||
|
date: '2016-05-07',
|
||||||
|
name: '王小虎',
|
||||||
|
province: '上海',
|
||||||
|
city: '普陀区',
|
||||||
|
address: '上海市普陀区金沙江路 1518 弄',
|
||||||
|
zip: 200333
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
### 单选
|
### 单选
|
||||||
|
|
||||||
选择单行数据时使用色块表示。
|
选择单行数据时使用色块表示。
|
||||||
|
|
|
@ -126,11 +126,13 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {},
|
render() {
|
||||||
|
return (<div>{ this._t('default') }</div>);
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isChildColumn: false,
|
isSubColumn: false,
|
||||||
columns: []
|
columns: []
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -158,13 +160,15 @@ export default {
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
this.customRender = this.$options.render;
|
this.customRender = this.$options.render;
|
||||||
this.$options.render = (h) => h('div');
|
this.$options.render = (h) => {
|
||||||
|
return (<div>{ this._t('default') }</div>);
|
||||||
|
};
|
||||||
|
|
||||||
let columnId = this.columnId = (this.$parent.tableId || (this.$parent.columnId + '_')) + 'column_' + columnIdSeed++;
|
let columnId = this.columnId = (this.$parent.tableId || (this.$parent.columnId + '_')) + 'column_' + columnIdSeed++;
|
||||||
|
|
||||||
let parent = this.$parent;
|
let parent = this.$parent;
|
||||||
let owner = this.owner;
|
let owner = this.owner;
|
||||||
this.isChildColumn = owner !== parent;
|
this.isSubColumn = owner !== parent;
|
||||||
|
|
||||||
let type = this.type;
|
let type = this.type;
|
||||||
|
|
||||||
|
@ -326,12 +330,12 @@ export default {
|
||||||
const parent = this.$parent;
|
const parent = this.$parent;
|
||||||
let columnIndex;
|
let columnIndex;
|
||||||
|
|
||||||
if (!this.isChildColumn) {
|
if (!this.isSubColumn) {
|
||||||
columnIndex = [].indexOf.call(parent.$refs.hiddenColumns.children, this.$el);
|
columnIndex = [].indexOf.call(parent.$refs.hiddenColumns.children, this.$el);
|
||||||
} else {
|
} else {
|
||||||
columnIndex = [].indexOf.call(parent.$el.children, this.$el);
|
columnIndex = [].indexOf.call(parent.$el.children, this.$el);
|
||||||
}
|
}
|
||||||
|
|
||||||
owner.store.commit('insertColumn', this.columnConfig, columnIndex);
|
owner.store.commit('insertColumn', this.columnConfig, columnIndex, this.isSubColumn ? parent.columnConfig : null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,10 +3,75 @@ import ElTag from 'element-ui/packages/tag';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import FilterPanel from './filter-panel.vue';
|
import FilterPanel from './filter-panel.vue';
|
||||||
|
|
||||||
|
const getAllColumns = (columns) => {
|
||||||
|
const result = [];
|
||||||
|
columns.forEach((column) => {
|
||||||
|
if (column.children) {
|
||||||
|
result.push(column);
|
||||||
|
result.push.apply(result, getAllColumns(column.children));
|
||||||
|
} else {
|
||||||
|
result.push(column);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
const convertToRows = (originColumns) => {
|
||||||
|
let maxLevel = 1;
|
||||||
|
const traverse = (column, parent) => {
|
||||||
|
if (parent) {
|
||||||
|
column.level = parent.level + 1;
|
||||||
|
if (maxLevel < column.level) {
|
||||||
|
maxLevel = column.level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (column.children) {
|
||||||
|
let childrenMax = 1;
|
||||||
|
let colSpan = 0;
|
||||||
|
column.children.forEach((subColumn) => {
|
||||||
|
const temp = traverse(subColumn, column);
|
||||||
|
if (temp > childrenMax) {
|
||||||
|
childrenMax = temp;
|
||||||
|
}
|
||||||
|
colSpan += subColumn.colSpan;
|
||||||
|
});
|
||||||
|
column.colSpan = colSpan;
|
||||||
|
} else {
|
||||||
|
column.colSpan = 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
originColumns.forEach((column) => {
|
||||||
|
column.level = 1;
|
||||||
|
traverse(column);
|
||||||
|
});
|
||||||
|
|
||||||
|
const rows = [];
|
||||||
|
for (let i = 0; i < maxLevel; i++) {
|
||||||
|
rows.push([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const allColumns = getAllColumns(originColumns);
|
||||||
|
|
||||||
|
allColumns.forEach((column) => {
|
||||||
|
if (!column.children) {
|
||||||
|
column.rowSpan = maxLevel - column.level + 1;
|
||||||
|
} else {
|
||||||
|
column.rowSpan = 1;
|
||||||
|
}
|
||||||
|
rows[column.level - 1].push(column);
|
||||||
|
});
|
||||||
|
|
||||||
|
return rows;
|
||||||
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'el-table-header',
|
name: 'el-table-header',
|
||||||
|
|
||||||
render(h) {
|
render(h) {
|
||||||
|
const originColumns = this.store.states.originColumns;
|
||||||
|
const columnRows = convertToRows(originColumns, this.columns);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<table
|
<table
|
||||||
class="el-table__header"
|
class="el-table__header"
|
||||||
|
@ -26,44 +91,50 @@ export default {
|
||||||
: ''
|
: ''
|
||||||
}
|
}
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
{
|
||||||
{
|
this._l(columnRows, (columns) =>
|
||||||
this._l(this.columns, (column, cellIndex) =>
|
<tr>
|
||||||
<th
|
{
|
||||||
on-mousemove={ ($event) => this.handleMouseMove($event, column) }
|
this._l(columns, (column, cellIndex) =>
|
||||||
on-mouseout={ this.handleMouseOut }
|
<th
|
||||||
on-mousedown={ ($event) => this.handleMouseDown($event, column) }
|
colspan={ column.colSpan }
|
||||||
on-click={ ($event) => this.handleClick($event, column) }
|
rowspan={ column.rowSpan }
|
||||||
class={ [column.id, column.order, column.align, column.className || '', this.isCellHidden(cellIndex) ? 'is-hidden' : ''] }>
|
on-mousemove={ ($event) => this.handleMouseMove($event, column) }
|
||||||
<div class={ ['cell', column.filteredValue && column.filteredValue.length > 0 ? 'highlight' : ''] }>
|
on-mouseout={ this.handleMouseOut }
|
||||||
{
|
on-mousedown={ ($event) => this.handleMouseDown($event, column) }
|
||||||
column.renderHeader
|
on-click={ ($event) => this.handleClick($event, column) }
|
||||||
? column.renderHeader.call(this._renderProxy, h, { column, $index: cellIndex, store: this.store, _self: this.$parent.$vnode.context })
|
class={ [column.id, column.order, column.align, column.className || '', this.isCellHidden(cellIndex) ? 'is-hidden' : '', !column.children ? 'is-leaf' : ''] }>
|
||||||
: column.label
|
<div class={ ['cell', column.filteredValue && column.filteredValue.length > 0 ? 'highlight' : ''] }>
|
||||||
|
{
|
||||||
|
column.renderHeader
|
||||||
|
? column.renderHeader.call(this._renderProxy, h, { column, $index: cellIndex, store: this.store, _self: this.$parent.$vnode.context })
|
||||||
|
: column.label
|
||||||
|
}
|
||||||
|
{
|
||||||
|
column.sortable
|
||||||
|
? <span class="caret-wrapper" on-click={ ($event) => this.handleHeaderClick($event, column) }>
|
||||||
|
<i class="sort-caret ascending"></i>
|
||||||
|
<i class="sort-caret descending"></i>
|
||||||
|
</span>
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
{
|
||||||
|
column.filterable
|
||||||
|
? <span class="el-table__column-filter-trigger" on-click={ ($event) => this.handleFilterClick($event, column) }><i class={ ['el-icon-arrow-down', column.filterOpened ? 'el-icon-arrow-up' : ''] }></i></span>
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
column.sortable
|
!this.fixed && this.layout.gutterWidth
|
||||||
? <span class="caret-wrapper" on-click={ ($event) => this.handleHeaderClick($event, column) }>
|
? <th class="gutter" style={{ width: this.layout.scrollY ? this.layout.gutterWidth + 'px' : '0' }}></th>
|
||||||
<i class="sort-caret ascending"></i>
|
|
||||||
<i class="sort-caret descending"></i>
|
|
||||||
</span>
|
|
||||||
: ''
|
: ''
|
||||||
}
|
}
|
||||||
{
|
</tr>
|
||||||
column.filterable
|
)
|
||||||
? <span class="el-table__column-filter-trigger" on-click={ ($event) => this.handleFilterClick($event, column) }><i class={ ['el-icon-arrow-down', column.filterOpened ? 'el-icon-arrow-up' : ''] }></i></span>
|
}
|
||||||
: ''
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</th>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
!this.fixed && this.layout.gutterWidth
|
|
||||||
? <th class="gutter" style={{ width: this.layout.scrollY ? this.layout.gutterWidth + 'px' : '0' }}></th>
|
|
||||||
: ''
|
|
||||||
}
|
|
||||||
</tr>
|
|
||||||
</thead>
|
</thead>
|
||||||
</table>
|
</table>
|
||||||
);
|
);
|
||||||
|
@ -168,6 +239,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
handleMouseDown(event, column) {
|
handleMouseDown(event, column) {
|
||||||
|
if (column.children && column.children.length > 0) return;
|
||||||
/* istanbul ignore if */
|
/* istanbul ignore if */
|
||||||
if (this.draggingColumn && this.border) {
|
if (this.draggingColumn && this.border) {
|
||||||
this.dragging = true;
|
this.dragging = true;
|
||||||
|
@ -234,6 +306,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
handleMouseMove(event, column) {
|
handleMouseMove(event, column) {
|
||||||
|
if (column.children && column.children.length > 0) return;
|
||||||
let target = event.target;
|
let target = event.target;
|
||||||
while (target && target.tagName !== 'TH') {
|
while (target && target.tagName !== 'TH') {
|
||||||
target = target.parentNode;
|
target = target.parentNode;
|
||||||
|
|
|
@ -52,6 +52,7 @@ const TableStore = function(table, initialState = {}) {
|
||||||
this.states = {
|
this.states = {
|
||||||
rowKey: null,
|
rowKey: null,
|
||||||
_columns: [],
|
_columns: [],
|
||||||
|
originColumns: [],
|
||||||
columns: [],
|
columns: [],
|
||||||
fixedColumns: [],
|
fixedColumns: [],
|
||||||
rightFixedColumns: [],
|
rightFixedColumns: [],
|
||||||
|
@ -159,13 +160,19 @@ TableStore.prototype.mutations = {
|
||||||
Vue.nextTick(() => this.table.updateScrollY());
|
Vue.nextTick(() => this.table.updateScrollY());
|
||||||
},
|
},
|
||||||
|
|
||||||
insertColumn(states, column, index) {
|
insertColumn(states, column, index, parent) {
|
||||||
let _columns = states._columns;
|
let array = states._columns;
|
||||||
if (typeof index !== 'undefined') {
|
if (parent) {
|
||||||
_columns.splice(index, 0, column);
|
array = parent.children;
|
||||||
} else {
|
if (!array) array = parent.children = [];
|
||||||
_columns.push(column);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof index !== 'undefined') {
|
||||||
|
array.splice(index, 0, column);
|
||||||
|
} else {
|
||||||
|
array.push(column);
|
||||||
|
}
|
||||||
|
|
||||||
if (column.type === 'selection') {
|
if (column.type === 'selection') {
|
||||||
states.selectable = column.selectable;
|
states.selectable = column.selectable;
|
||||||
states.reserveSelection = column.reserveSelection;
|
states.reserveSelection = column.reserveSelection;
|
||||||
|
@ -236,6 +243,18 @@ TableStore.prototype.mutations = {
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const doFlattenColumns = (columns) => {
|
||||||
|
const result = [];
|
||||||
|
columns.forEach((column) => {
|
||||||
|
if (column.children) {
|
||||||
|
result.push.apply(result, doFlattenColumns(column.children));
|
||||||
|
} else {
|
||||||
|
result.push(column);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
TableStore.prototype.updateColumns = function() {
|
TableStore.prototype.updateColumns = function() {
|
||||||
const states = this.states;
|
const states = this.states;
|
||||||
const _columns = states._columns || [];
|
const _columns = states._columns || [];
|
||||||
|
@ -246,7 +265,8 @@ TableStore.prototype.updateColumns = function() {
|
||||||
_columns[0].fixed = true;
|
_columns[0].fixed = true;
|
||||||
states.fixedColumns.unshift(_columns[0]);
|
states.fixedColumns.unshift(_columns[0]);
|
||||||
}
|
}
|
||||||
states.columns = [].concat(states.fixedColumns).concat(_columns.filter((column) => !column.fixed)).concat(states.rightFixedColumns);
|
states.originColumns = [].concat(states.fixedColumns).concat(_columns.filter((column) => !column.fixed)).concat(states.rightFixedColumns);
|
||||||
|
states.columns = doFlattenColumns(states.originColumns);
|
||||||
states.isComplex = states.fixedColumns.length > 0 || states.rightFixedColumns.length > 0;
|
states.isComplex = states.fixedColumns.length > 0 || states.rightFixedColumns.length > 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,6 @@
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
position: relative;
|
position: relative;
|
||||||
border-bottom: 1px solid var(--table-border-color);
|
|
||||||
|
|
||||||
@when center {
|
@when center {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -101,10 +100,18 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& th.is-leaf, td {
|
||||||
|
border-bottom: 1px solid var(--table-border-color);
|
||||||
|
}
|
||||||
|
|
||||||
@modifier border {
|
@modifier border {
|
||||||
& th, td {
|
& th, td {
|
||||||
border-right: 1px solid var(--table-border-color);
|
border-right: 1px solid var(--table-border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& th {
|
||||||
|
border-bottom: 1px solid var(--table-border-color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
& th {
|
& th {
|
||||||
|
|
|
@ -985,6 +985,112 @@ describe('Table', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('multi level column', () => {
|
||||||
|
it('should works', done => {
|
||||||
|
const vm = createVue({
|
||||||
|
template: `
|
||||||
|
<el-table :data="testData">
|
||||||
|
<el-table-column prop="name" />
|
||||||
|
<el-table-column label="group">
|
||||||
|
<el-table-column prop="release"/>
|
||||||
|
<el-table-column prop="director"/>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="runtime"/>
|
||||||
|
</el-table>
|
||||||
|
`,
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.testData = null;
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
setTimeout(_ => {
|
||||||
|
const trs = vm.$el.querySelectorAll('.el-table__header tr');
|
||||||
|
expect(trs.length).equal(2);
|
||||||
|
const firstRowHeader = trs[0].querySelectorAll('th .cell').length;
|
||||||
|
const secondRowHeader = trs[1].querySelectorAll('th .cell').length;
|
||||||
|
expect(firstRowHeader).to.equal(3);
|
||||||
|
expect(secondRowHeader).to.equal(2);
|
||||||
|
|
||||||
|
expect(trs[0].querySelector('th:first-child').getAttribute('rowspan')).to.equal('2');
|
||||||
|
expect(trs[0].querySelector('th:nth-child(2)').getAttribute('colspan')).to.equal('2');
|
||||||
|
destroyVM(vm);
|
||||||
|
done();
|
||||||
|
}, DELAY);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should works', done => {
|
||||||
|
const vm = createVue({
|
||||||
|
template: `
|
||||||
|
<el-table :data="testData">
|
||||||
|
<el-table-column prop="name" />
|
||||||
|
<el-table-column label="group">
|
||||||
|
<el-table-column label="group's group">
|
||||||
|
<el-table-column prop="release" />
|
||||||
|
<el-table-column prop="runtime"/>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="director" />
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="runtime"/>
|
||||||
|
</el-table>
|
||||||
|
`,
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.testData = null;
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
setTimeout(_ => {
|
||||||
|
const trs = vm.$el.querySelectorAll('.el-table__header tr');
|
||||||
|
expect(trs.length).equal(3);
|
||||||
|
const firstRowHeader = trs[0].querySelectorAll('th .cell').length;
|
||||||
|
const secondRowHeader = trs[1].querySelectorAll('th .cell').length;
|
||||||
|
const thirdRowHeader = trs[2].querySelectorAll('th .cell').length;
|
||||||
|
expect(firstRowHeader).to.equal(3);
|
||||||
|
expect(secondRowHeader).to.equal(2);
|
||||||
|
expect(thirdRowHeader).to.equal(2);
|
||||||
|
|
||||||
|
expect(trs[0].querySelector('th:first-child').getAttribute('rowspan')).to.equal('3');
|
||||||
|
expect(trs[0].querySelector('th:nth-child(2)').getAttribute('colspan')).to.equal('3');
|
||||||
|
expect(trs[1].querySelector('th:first-child').getAttribute('colspan')).to.equal('2');
|
||||||
|
expect(trs[1].querySelector('th:nth-child(2)').getAttribute('rowspan')).to.equal('2');
|
||||||
|
|
||||||
|
destroyVM(vm);
|
||||||
|
done();
|
||||||
|
}, DELAY);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should work in one column', done => {
|
||||||
|
const vm = createVue({
|
||||||
|
template: `
|
||||||
|
<el-table :data="testData">
|
||||||
|
<el-table-column label="group">
|
||||||
|
<el-table-column prop="release"/>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
`,
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.testData = null;
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
setTimeout(_ => {
|
||||||
|
const trs = vm.$el.querySelectorAll('.el-table__header tr');
|
||||||
|
expect(trs.length).equal(2);
|
||||||
|
const firstRowLength = trs[0].querySelectorAll('th .cell').length;
|
||||||
|
const secondRowLength = trs[1].querySelectorAll('th .cell').length;
|
||||||
|
expect(firstRowLength).to.equal(1);
|
||||||
|
expect(secondRowLength).to.equal(1);
|
||||||
|
|
||||||
|
expect(trs[0].querySelector('th:first-child').getAttribute('rowspan')).to.equal('1');
|
||||||
|
expect(trs[0].querySelector('th:first-child').getAttribute('colspan')).to.equal('1');
|
||||||
|
destroyVM(vm);
|
||||||
|
done();
|
||||||
|
}, DELAY);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('methods', () => {
|
describe('methods', () => {
|
||||||
const createTable = function(prop = '', opts) {
|
const createTable = function(prop = '', opts) {
|
||||||
return createVue({
|
return createVue({
|
||||||
|
|
Loading…
Reference in New Issue