Table support multiple table-head
This commit is contained in:
parent
12739c33fa
commit
1acabf7912
5 changed files with 222 additions and 245 deletions
|
@ -1,66 +1,91 @@
|
|||
<template>
|
||||
<div>
|
||||
<Table border ref="selection" :columns="columns4" :data="data1" :height='258'></Table>
|
||||
<Button @click="handleSetData">Set Data</Button>
|
||||
<Button @click="handleClearData">Clear Data</Button>
|
||||
<Button @click="handleSelectAll(true)">Set all selected</Button>
|
||||
<Button @click="handleSelectAll(false)">Cancel all selected</Button>
|
||||
<div style='margin:20px 0px'>
|
||||
<Table border :columns="columns2" :data="data3"></Table>
|
||||
</div>
|
||||
<div style='margin:20px 0px'>
|
||||
<Table :height='200' border :columns="columns2" :data="data3"></Table>
|
||||
</div>
|
||||
<div style='margin:20px 0px'>
|
||||
<Table :width='600' border :columns="columns2" :data="data3"></Table>
|
||||
</div>
|
||||
<div style='margin:20px 0px'>
|
||||
<Table :width='600' :height='200' border :columns="columns2" :data="data31"></Table>
|
||||
</div>
|
||||
<div style='margin:20px 0px;'>
|
||||
Table scrolling <i-switch v-model="fixedHeader" style="margin-right: 5px"></i-switch>
|
||||
<Table :data="tableData1" :columns="tableColumns1" :height="fixedHeader ? 250 : ''" stripe size='small'></Table>
|
||||
<div style="margin: 10px;overflow: hidden">
|
||||
<div style="float: right;">
|
||||
<Page :total="100" show-sizer :current="1" @on-change="changePage"></Page>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br><br><br><br><br>
|
||||
<Table border :columns="columns1" height="500" :data="data1"></Table>
|
||||
<br><br><br><br><br>
|
||||
<!--<Table width="550" height="200" border :columns="columns2" :data="data4"></Table>-->
|
||||
<br><br><br><br><br>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
columns4: [
|
||||
{
|
||||
type: 'selection',
|
||||
width: 60,
|
||||
align: 'center'
|
||||
},
|
||||
columns1: [
|
||||
{
|
||||
title: 'Name',
|
||||
key: 'name',
|
||||
width: 260
|
||||
align: 'center',
|
||||
width: 200,
|
||||
fixed: 'left'
|
||||
},
|
||||
{
|
||||
title: 'Age',
|
||||
key: 'age'
|
||||
title: 'Other',
|
||||
align: 'center',
|
||||
children: [
|
||||
{
|
||||
title: 'Age',
|
||||
key: 'age',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: 'Address',
|
||||
align: 'center',
|
||||
children: [
|
||||
{
|
||||
title: 'Street',
|
||||
key: 'street',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: 'Block',
|
||||
align: 'center',
|
||||
children: [
|
||||
{
|
||||
title: 'Building',
|
||||
key: 'building',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: 'Door No.',
|
||||
key: 'door',
|
||||
align: 'center',
|
||||
width: 200
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Address',
|
||||
key: 'address',
|
||||
width: 260
|
||||
title: 'Company',
|
||||
align: 'center',
|
||||
children: [
|
||||
{
|
||||
title: 'Company Address',
|
||||
key: 'caddress',
|
||||
align: 'center',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
title: 'Company Name',
|
||||
key: 'cname',
|
||||
align: 'center',
|
||||
width: 200
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Address',
|
||||
key: 'address',
|
||||
width: 260
|
||||
title: 'Gender',
|
||||
key: 'gender',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
fixed: 'right'
|
||||
}
|
||||
],
|
||||
data1: [
|
||||
|
||||
],
|
||||
columns2: [
|
||||
{
|
||||
|
@ -72,7 +97,9 @@
|
|||
{
|
||||
title: 'Age',
|
||||
key: 'age',
|
||||
width: 100
|
||||
width: 100,
|
||||
fixed: 'right',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
title: 'Province',
|
||||
|
@ -92,8 +119,7 @@
|
|||
{
|
||||
title: 'Postcode',
|
||||
key: 'zip',
|
||||
width: 100,
|
||||
fixed: 'right',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: 'Action',
|
||||
|
@ -118,7 +144,8 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
data3: [
|
||||
data1: [],
|
||||
data4: [
|
||||
{
|
||||
name: 'John Brown',
|
||||
age: 18,
|
||||
|
@ -151,16 +178,6 @@
|
|||
city: 'Ottawa',
|
||||
zip: 100000
|
||||
},
|
||||
{
|
||||
name: 'Jon Snow',
|
||||
age: 26,
|
||||
address: 'Ottawa No. 2 Lake Park',
|
||||
province: 'Canada',
|
||||
city: 'Ottawa',
|
||||
zip: 100000
|
||||
}
|
||||
],
|
||||
data31: [
|
||||
{
|
||||
name: 'John Brown',
|
||||
age: 18,
|
||||
|
@ -185,78 +202,6 @@
|
|||
city: 'Sydney',
|
||||
zip: 100000
|
||||
},
|
||||
{
|
||||
name: 'Jon Snow',
|
||||
age: 26,
|
||||
address: 'Ottawa No. 2 Lake Park',
|
||||
province: 'Canada',
|
||||
city: 'Ottawa',
|
||||
zip: 100000
|
||||
},
|
||||
{
|
||||
name: 'Jon Snow',
|
||||
age: 26,
|
||||
address: 'Ottawa No. 2 Lake Park',
|
||||
province: 'Canada',
|
||||
city: 'Ottawa',
|
||||
zip: 100000
|
||||
},
|
||||
{
|
||||
name: 'Jim Green',
|
||||
age: 24,
|
||||
address: 'Washington, D.C. No. 1 Lake Park',
|
||||
province: 'America',
|
||||
city: 'Washington, D.C.',
|
||||
zip: 100000
|
||||
},
|
||||
{
|
||||
name: 'Joe Black',
|
||||
age: 30,
|
||||
address: 'Sydney No. 1 Lake Park',
|
||||
province: 'Australian',
|
||||
city: 'Sydney',
|
||||
zip: 100000
|
||||
},
|
||||
{
|
||||
name: 'Jon Snow',
|
||||
age: 26,
|
||||
address: 'Ottawa No. 2 Lake Park',
|
||||
province: 'Canada',
|
||||
city: 'Ottawa',
|
||||
zip: 100000
|
||||
},
|
||||
{
|
||||
name: 'Jon Snow',
|
||||
age: 26,
|
||||
address: 'Ottawa No. 2 Lake Park',
|
||||
province: 'Canada',
|
||||
city: 'Ottawa',
|
||||
zip: 100000
|
||||
},
|
||||
{
|
||||
name: 'Jim Green',
|
||||
age: 24,
|
||||
address: 'Washington, D.C. No. 1 Lake Park',
|
||||
province: 'America',
|
||||
city: 'Washington, D.C.',
|
||||
zip: 100000
|
||||
},
|
||||
{
|
||||
name: 'Joe Black',
|
||||
age: 30,
|
||||
address: 'Sydney No. 1 Lake Park',
|
||||
province: 'Australian',
|
||||
city: 'Sydney',
|
||||
zip: 100000
|
||||
},
|
||||
{
|
||||
name: 'Jon Snow',
|
||||
age: 26,
|
||||
address: 'Ottawa No. 2 Lake Park',
|
||||
province: 'Canada',
|
||||
city: 'Ottawa',
|
||||
zip: 100000
|
||||
},
|
||||
{
|
||||
name: 'Jon Snow',
|
||||
age: 26,
|
||||
|
@ -265,94 +210,25 @@
|
|||
city: 'Ottawa',
|
||||
zip: 100000
|
||||
}
|
||||
],
|
||||
|
||||
|
||||
fixedHeader: false,
|
||||
tableData1: [],
|
||||
tableColumns1: [
|
||||
{
|
||||
title: 'Data1',
|
||||
key: 'data1'
|
||||
},
|
||||
{
|
||||
title: 'Data2',
|
||||
key: 'data2'
|
||||
},
|
||||
{
|
||||
title: 'Data3',
|
||||
key: 'data3'
|
||||
},
|
||||
{
|
||||
title: 'Data4',
|
||||
key: 'data4'
|
||||
},
|
||||
{
|
||||
title: 'Data5',
|
||||
key: 'data5'
|
||||
},
|
||||
{
|
||||
title: 'Data6Data6Data6Data6Data6Data6Data6Data6Data6Data6Data6',
|
||||
key: 'data6'
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
this.refreshData();
|
||||
},
|
||||
methods: {
|
||||
handleSelectAll (status) {
|
||||
this.$refs.selection.selectAll(status);
|
||||
},
|
||||
handleSetData () {
|
||||
this.data1 = [
|
||||
{
|
||||
name: 'John Brown',
|
||||
age: 18,
|
||||
address: 'New York No. 1 Lake Park',
|
||||
date: '2016-10-03'
|
||||
},
|
||||
{
|
||||
name: 'Jim Green',
|
||||
age: 24,
|
||||
address: 'London No. 1 Lake Park',
|
||||
date: '2016-10-01'
|
||||
},
|
||||
{
|
||||
name: 'Joe Black',
|
||||
age: 30,
|
||||
address: 'Sydney No. 1 Lake Park',
|
||||
date: '2016-10-02'
|
||||
},
|
||||
{
|
||||
name: 'Jon Snow',
|
||||
age: 26,
|
||||
address: 'Ottawa No. 2 Lake Park',
|
||||
date: '2016-10-04'
|
||||
}
|
||||
];
|
||||
},
|
||||
handleClearData () {
|
||||
this.data1 = [];
|
||||
},
|
||||
refreshData(){
|
||||
let data = [];
|
||||
for (let i = 0; i < 10; i++) {
|
||||
data.push({
|
||||
data1: Math.floor(Math.random () * 10000),
|
||||
data2: Math.floor(Math.random () * 1000000),
|
||||
data3: Math.floor(Math.random () * 100000000),
|
||||
data4: Math.floor(Math.random () * Math.random () * 10000),
|
||||
data5: Math.floor(Math.random () * Math.random () * 1000000),
|
||||
data6: ''+Math.floor(Math.random () * Math.random () * 100000000)+Math.floor(Math.random () * 100000000)+Math.floor(Math.random () * 100000000),
|
||||
});
|
||||
}
|
||||
this.tableData1 = data;
|
||||
},
|
||||
changePage(){
|
||||
this.refreshData();
|
||||
mounted () {
|
||||
const data = [];
|
||||
for (let i = 0; i < 100; i++) {
|
||||
data.push({
|
||||
key: i,
|
||||
name: 'John Brown',
|
||||
age: i + 1,
|
||||
street: 'Lake Park',
|
||||
building: 'C',
|
||||
door: 2035,
|
||||
caddress: 'Lake Street 42',
|
||||
cname: 'SoftLake Co',
|
||||
gender: 'M',
|
||||
});
|
||||
}
|
||||
this.data1 = data;
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -4,8 +4,12 @@
|
|||
<col v-for="(column, index) in columns" :width="setCellWidth(column, index, true)">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th v-for="(column, index) in columns" :class="alignCls(column)">
|
||||
<tr v-for="(cols, rowIndex) in headRows">
|
||||
<th
|
||||
v-for="(column, index) in cols"
|
||||
:colspan="column.colSpan"
|
||||
:rowspan="column.rowSpan"
|
||||
:class="alignCls(column)">
|
||||
<div :class="cellClasses(column)">
|
||||
<template v-if="column.type === 'expand'">
|
||||
<span v-if="!column.renderHeader">{{ column.title || '' }}</span>
|
||||
|
@ -67,6 +71,7 @@
|
|||
import renderHeader from './header';
|
||||
import Mixin from './mixin';
|
||||
import Locale from '../../mixins/locale';
|
||||
import { convertColumnOrder } from './util';
|
||||
|
||||
export default {
|
||||
name: 'TableHead',
|
||||
|
@ -82,7 +87,8 @@
|
|||
fixed: {
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
}
|
||||
},
|
||||
columnRows: Array
|
||||
},
|
||||
computed: {
|
||||
styles () {
|
||||
|
@ -108,6 +114,25 @@
|
|||
}
|
||||
|
||||
return isSelectAll;
|
||||
},
|
||||
headRows () {
|
||||
const isGroup = this.columnRows.length > 1;
|
||||
return isGroup ? this.columnRows : [this.columns];
|
||||
|
||||
// if (isGroup) {
|
||||
// const fixedType = this.fixed;
|
||||
// if (fixedType) {
|
||||
// if (fixedType === 'left') {
|
||||
// return convertColumnOrder(this.columnRows, 'left');
|
||||
// } else if (fixedType === 'right') {
|
||||
// return convertColumnOrder(this.columnRows, 'right');
|
||||
// }
|
||||
// } else {
|
||||
// return this.columnRows;
|
||||
// }
|
||||
// } else {
|
||||
// return [this.columns];
|
||||
// }
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
:prefix-cls="prefixCls"
|
||||
:styleObject="tableStyle"
|
||||
:columns="cloneColumns"
|
||||
:column-rows="columnRows"
|
||||
:obj-data="objData"
|
||||
:columns-width="columnsWidth"
|
||||
:data="rebuildData"></table-head>
|
||||
|
@ -43,6 +44,7 @@
|
|||
:prefix-cls="prefixCls"
|
||||
:styleObject="fixedTableStyle"
|
||||
:columns="leftFixedColumns"
|
||||
:column-rows="columnRows"
|
||||
:obj-data="objData"
|
||||
:columns-width="columnsWidth"
|
||||
:data="rebuildData"></table-head>
|
||||
|
@ -65,6 +67,7 @@
|
|||
:prefix-cls="prefixCls"
|
||||
:styleObject="fixedRightTableStyle"
|
||||
:columns="rightFixedColumns"
|
||||
:column-rows="columnRows"
|
||||
:obj-data="objData"
|
||||
:columns-width="columnsWidth"
|
||||
:data="rebuildData"></table-head>
|
||||
|
@ -97,6 +100,7 @@
|
|||
import ExportCsv from './export-csv';
|
||||
import Locale from '../../mixins/locale';
|
||||
import elementResizeDetectorMaker from 'element-resize-detector';
|
||||
import { getAllColumns, convertToRows, convertColumnOrder } from './util';
|
||||
|
||||
const prefixCls = 'ivu-table';
|
||||
|
||||
|
@ -180,6 +184,8 @@
|
|||
objData: this.makeObjData(), // checkbox or highlight-row
|
||||
rebuildData: [], // for sort or filter
|
||||
cloneColumns: this.makeColumns(),
|
||||
columnRows: this.makeColumnRows(),
|
||||
allColumns: getAllColumns(this.columns), // for multiple table-head, get columns that have no children
|
||||
showSlotHeader: true,
|
||||
showSlotFooter: true,
|
||||
bodyHeight: 0,
|
||||
|
@ -308,28 +314,10 @@
|
|||
return style;
|
||||
},
|
||||
leftFixedColumns () {
|
||||
let left = [];
|
||||
let other = [];
|
||||
this.cloneColumns.forEach((col) => {
|
||||
if (col.fixed && col.fixed === 'left') {
|
||||
left.push(col);
|
||||
} else {
|
||||
//other.push(col);
|
||||
}
|
||||
});
|
||||
return left.concat(other);
|
||||
return convertColumnOrder(this.cloneColumns, 'left');
|
||||
},
|
||||
rightFixedColumns () {
|
||||
let right = [];
|
||||
let other = [];
|
||||
this.cloneColumns.forEach((col) => {
|
||||
if (col.fixed && col.fixed === 'right') {
|
||||
right.push(col);
|
||||
} else {
|
||||
//other.push(col);
|
||||
}
|
||||
});
|
||||
return right.concat(other);
|
||||
return convertColumnOrder(this.cloneColumns, 'right');
|
||||
},
|
||||
isLeftFixed () {
|
||||
return this.columns.some(col => col.fixed && col.fixed === 'left');
|
||||
|
@ -344,9 +332,9 @@
|
|||
},
|
||||
handleResize () {
|
||||
this.$nextTick(() => {
|
||||
const allWidth = !this.columns.some(cell => !cell.width); // each column set a width
|
||||
const allWidth = !this.allColumns.some(cell => !cell.width); // each column set a width
|
||||
if (allWidth) {
|
||||
this.tableWidth = this.columns.map(cell => cell.width).reduce((a, b) => a + b, 0);
|
||||
this.tableWidth = this.allColumns.map(cell => cell.width).reduce((a, b) => a + b, 0);
|
||||
} else {
|
||||
this.tableWidth = parseInt(getStyle(this.$el, 'width')) - 1;
|
||||
}
|
||||
|
@ -614,7 +602,7 @@
|
|||
this.cloneColumns[index]._sortType = type;
|
||||
|
||||
this.$emit('on-sort-change', {
|
||||
column: JSON.parse(JSON.stringify(this.columns[this.cloneColumns[index]._index])),
|
||||
column: JSON.parse(JSON.stringify(this.allColumns[this.cloneColumns[index]._index])),
|
||||
key: key,
|
||||
order: type
|
||||
});
|
||||
|
@ -751,7 +739,8 @@
|
|||
return data;
|
||||
},
|
||||
makeColumns () {
|
||||
let columns = deepCopy(this.columns);
|
||||
// 在 data 时,this.allColumns 暂时为 undefined
|
||||
let columns = deepCopy(getAllColumns(this.columns));
|
||||
let left = [];
|
||||
let right = [];
|
||||
let center = [];
|
||||
|
@ -789,6 +778,10 @@
|
|||
});
|
||||
return left.concat(center).concat(right);
|
||||
},
|
||||
// create a multiple table-head
|
||||
makeColumnRows () {
|
||||
return convertToRows(this.columns);
|
||||
},
|
||||
exportCsv (params) {
|
||||
if (params.filename) {
|
||||
if (params.filename.indexOf('.csv') === -1) {
|
||||
|
@ -804,7 +797,7 @@
|
|||
columns = params.columns;
|
||||
datas = params.data;
|
||||
} else {
|
||||
columns = this.columns;
|
||||
columns = this.allColumns;
|
||||
if (!('original' in params)) params.original = true;
|
||||
datas = params.original ? this.data : this.rebuildData;
|
||||
}
|
||||
|
@ -863,7 +856,9 @@
|
|||
columns: {
|
||||
handler () {
|
||||
// todo 这里有性能问题,可能是左右固定计算属性影响的
|
||||
this.allColumns = getAllColumns(this.columns);
|
||||
this.cloneColumns = this.makeColumns();
|
||||
this.columnRows = this.makeColumnRows();
|
||||
this.rebuildData = this.makeDataWithSortAndFilter();
|
||||
this.handleResize();
|
||||
},
|
||||
|
|
81
src/components/table/util.js
Normal file
81
src/components/table/util.js
Normal file
|
@ -0,0 +1,81 @@
|
|||
import { deepCopy } from '../../utils/assist';
|
||||
|
||||
// set forTableHead to true when convertToRows, false in normal cases like table.vue
|
||||
const getAllColumns = (cols, forTableHead = false) => {
|
||||
const columns = deepCopy(cols);
|
||||
const result = [];
|
||||
columns.forEach((column) => {
|
||||
if (column.children) {
|
||||
if (forTableHead) result.push(column);
|
||||
result.push.apply(result, getAllColumns(column.children, forTableHead));
|
||||
} else {
|
||||
result.push(column);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
export {getAllColumns};
|
||||
|
||||
const convertToRows = (columns) => {
|
||||
const originColumns = deepCopy(columns);
|
||||
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 colSpan = 0;
|
||||
column.children.forEach((subColumn) => {
|
||||
traverse(subColumn, column);
|
||||
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, true);
|
||||
|
||||
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 {convertToRows};
|
||||
|
||||
const convertColumnOrder = (columns, FixedType) => {
|
||||
let list = [];
|
||||
let other = [];
|
||||
columns.forEach((col) => {
|
||||
if (col.fixed && col.fixed === FixedType) {
|
||||
list.push(col);
|
||||
} else {
|
||||
other.push(col);
|
||||
}
|
||||
});
|
||||
return list.concat(other);
|
||||
};
|
||||
|
||||
export {convertColumnOrder};
|
|
@ -71,7 +71,7 @@
|
|||
overflow: hidden;
|
||||
}
|
||||
&-body{
|
||||
//overflow: auto;
|
||||
overflow: auto;
|
||||
//position: relative;
|
||||
|
||||
}
|
||||
|
@ -285,7 +285,7 @@
|
|||
box-shadow: -2px 0 6px -2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
&-fixed-header{
|
||||
overflow: visible;
|
||||
overflow: hidden;
|
||||
&-with-empty{
|
||||
.@{table-prefix-cls}-hidden{
|
||||
.@{table-prefix-cls}-sort{
|
||||
|
|
Loading…
Add table
Reference in a new issue