Table support tree data
This commit is contained in:
parent
1e41ced797
commit
c591ddc9b7
5 changed files with 372 additions and 612 deletions
|
@ -4,6 +4,12 @@
|
|||
<template v-if="renderType === 'selection'">
|
||||
<Checkbox :value="checked" @click.native.stop="handleClick" @on-change="toggleSelect" :disabled="disabled"></Checkbox>
|
||||
</template>
|
||||
<div class="ivu-table-cell-tree-level" v-if="showLevel" :style="treeLevelStyle"></div>
|
||||
<div class="ivu-table-cell-tree" v-if="showChildren">
|
||||
<Icon type="ios-add" v-if="!row._isShowChildren" @click="handleOpenTree" />
|
||||
<Icon type="ios-remove" v-else @click="handleCloseTree" />
|
||||
</div>
|
||||
<div class="ivu-table-cell-tree ivu-table-cell-tree-empty" v-else-if="showTreeNode"></div>
|
||||
<template v-if="renderType === 'html'"><span v-html="row[column.key]"></span></template>
|
||||
<template v-if="renderType === 'normal'">
|
||||
<template v-if="column.tooltip">
|
||||
|
@ -54,6 +60,12 @@
|
|||
fixed: {
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
},
|
||||
// 是否为 tree 子节点
|
||||
treeNode: Boolean,
|
||||
treeLevel: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data () {
|
||||
|
@ -84,6 +96,35 @@
|
|||
[`${this.prefixCls}-cell-expand-expanded`]: this.expanded
|
||||
}
|
||||
];
|
||||
},
|
||||
showChildren () {
|
||||
let status = false;
|
||||
if (this.renderType === 'html' || this.renderType === 'normal' || this.renderType === 'render' || this.renderType === 'slot') {
|
||||
const data = this.row;
|
||||
if ((data.children && data.children.length) || ('_loading' in data && data._loading)) {
|
||||
if (this.column.tree) status = true;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
},
|
||||
showTreeNode () {
|
||||
let status = false;
|
||||
if (this.renderType === 'html' || this.renderType === 'normal' || this.renderType === 'render' || this.renderType === 'slot') {
|
||||
if (this.column.tree && this.treeNode) status = true;
|
||||
}
|
||||
return status;
|
||||
},
|
||||
showLevel () {
|
||||
let status = false;
|
||||
if (this.renderType === 'html' || this.renderType === 'normal' || this.renderType === 'render' || this.renderType === 'slot') {
|
||||
if (this.column.tree && this.treeNode) status = true;
|
||||
}
|
||||
return status;
|
||||
},
|
||||
treeLevelStyle () {
|
||||
return {
|
||||
'padding-left': this.treeLevel * this.tableRoot.indentSize + 'px'
|
||||
};
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -108,6 +149,12 @@
|
|||
},
|
||||
handleTooltipHide () {
|
||||
this.tooltipShow = false;
|
||||
},
|
||||
handleOpenTree () {
|
||||
|
||||
},
|
||||
handleCloseTree () {
|
||||
|
||||
}
|
||||
},
|
||||
created () {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
<!--
|
||||
<template>
|
||||
<table cellspacing="0" cellpadding="0" border="0" :style="styleObject">
|
||||
<colgroup>
|
||||
|
@ -38,6 +39,7 @@
|
|||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
-->
|
||||
<script>
|
||||
// todo :key="row"
|
||||
import TableTr from './table-tr.vue';
|
||||
|
@ -93,16 +95,19 @@
|
|||
rowExpanded(_index){
|
||||
return this.objData[_index] && this.objData[_index]._isExpanded;
|
||||
},
|
||||
handleMouseIn (_index) {
|
||||
handleMouseIn (_index, event) {
|
||||
event.stopPropagation();
|
||||
this.$parent.handleMouseIn(_index);
|
||||
},
|
||||
handleMouseOut (_index) {
|
||||
handleMouseOut (_index, event) {
|
||||
event.stopPropagation();
|
||||
this.$parent.handleMouseOut(_index);
|
||||
},
|
||||
clickCurrentRow (_index) {
|
||||
this.$parent.clickCurrentRow(_index);
|
||||
},
|
||||
dblclickCurrentRow (_index) {
|
||||
dblclickCurrentRow (_index, event) {
|
||||
event.stopPropagation();
|
||||
this.$parent.dblclickCurrentRow(_index);
|
||||
},
|
||||
getSpan (row, column, rowIndex, columnIndex) {
|
||||
|
@ -134,7 +139,169 @@
|
|||
showWithSpan (row, column, rowIndex, columnIndex) {
|
||||
const result = this.getSpan(row, column, rowIndex, columnIndex);
|
||||
return !(('rowspan' in result && result.rowspan === 0) || ('colspan' in result && result.colspan === 0));
|
||||
},
|
||||
getChildNode (h, data, nodes, level = 1) {
|
||||
if (data.children && data.children.length) {
|
||||
data.children.forEach((row, index) => {
|
||||
let $tds = [];
|
||||
|
||||
this.columns.forEach((column, colIndex) => {
|
||||
if (this.showWithSpan(row, column, index, colIndex)) {
|
||||
const $tableCell = h(TableCell, {
|
||||
props: {
|
||||
fixed: this.fixed,
|
||||
'prefix-cls': this.prefixCls,
|
||||
row: row,
|
||||
column: column,
|
||||
'natural-index': index,
|
||||
index: row._index,
|
||||
checked: this.rowChecked(row._index),
|
||||
disabled: this.rowDisabled(row._index),
|
||||
expanded: this.rowExpanded(row._index),
|
||||
treeNode: true,
|
||||
treeLevel: level
|
||||
},
|
||||
key: column._columnKey,
|
||||
});
|
||||
|
||||
const $td = h('td', {
|
||||
class: this.alignCls(column, row),
|
||||
attrs: this.getSpan(row, column, index, colIndex)
|
||||
}, [$tableCell]);
|
||||
$tds.push($td);
|
||||
}
|
||||
});
|
||||
|
||||
const $tableTr = h(TableTr, {
|
||||
props: {
|
||||
draggable: false,
|
||||
row: row,
|
||||
'prefix-cls': this.prefixCls
|
||||
},
|
||||
key: this.rowKey ? row._rowKey : index,
|
||||
nativeOn: {
|
||||
mouseenter: (e) => this.handleMouseIn(row._index, e),
|
||||
mouseleave: (e) => this.handleMouseOut(row._index, e),
|
||||
click: (e) => this.clickCurrentRow(row._index, e),
|
||||
dblclick: (e) => this.dblclickCurrentRow(row._index, e)
|
||||
}
|
||||
}, $tds);
|
||||
|
||||
nodes.push($tableTr);
|
||||
|
||||
if (row.children && row.children.length) {
|
||||
level++;
|
||||
this.getChildNode(h, row, nodes, level, level);
|
||||
}
|
||||
});
|
||||
return nodes;
|
||||
} else {
|
||||
return nodes;
|
||||
}
|
||||
}
|
||||
},
|
||||
render (h) {
|
||||
let $cols = [];
|
||||
this.columns.forEach((column, index) => {
|
||||
const $col = h('col', {
|
||||
attrs: {
|
||||
width: this.setCellWidth(column)
|
||||
}
|
||||
});
|
||||
$cols.push($col);
|
||||
});
|
||||
const $colgroup = h('colgroup', {}, $cols);
|
||||
|
||||
let $tableTrs = [];
|
||||
this.data.forEach((row, index) => {
|
||||
let $tds = [];
|
||||
|
||||
this.columns.forEach((column, colIndex) => {
|
||||
if (this.showWithSpan(row, column, index, colIndex)) {
|
||||
const $tableCell = h(TableCell, {
|
||||
props: {
|
||||
fixed: this.fixed,
|
||||
'prefix-cls': this.prefixCls,
|
||||
row: row,
|
||||
column: column,
|
||||
'natural-index': index,
|
||||
index: row._index,
|
||||
checked: this.rowChecked(row._index),
|
||||
disabled: this.rowDisabled(row._index),
|
||||
expanded: this.rowExpanded(row._index)
|
||||
},
|
||||
key: column._columnKey,
|
||||
});
|
||||
|
||||
const $td = h('td', {
|
||||
class: this.alignCls(column, row),
|
||||
attrs: this.getSpan(row, column, index, colIndex)
|
||||
}, [$tableCell]);
|
||||
$tds.push($td);
|
||||
}
|
||||
});
|
||||
|
||||
const $tableTr = h(TableTr, {
|
||||
props: {
|
||||
draggable: this.draggable,
|
||||
row: row,
|
||||
'prefix-cls': this.prefixCls
|
||||
},
|
||||
key: this.rowKey ? row._rowKey : index,
|
||||
nativeOn: {
|
||||
mouseenter: (e) => this.handleMouseIn(row._index, e),
|
||||
mouseleave: (e) => this.handleMouseOut(row._index, e),
|
||||
click: (e) => this.clickCurrentRow(row._index, e),
|
||||
dblclick: (e) => this.dblclickCurrentRow(row._index, e)
|
||||
}
|
||||
}, $tds);
|
||||
$tableTrs.push($tableTr);
|
||||
|
||||
// 可展开
|
||||
if (this.rowExpanded(row._index)) {
|
||||
const $Expand = h(Expand, {
|
||||
props: {
|
||||
row: row,
|
||||
render: this.expandRender,
|
||||
index: row._index
|
||||
},
|
||||
key: this.rowKey ? row._rowKey : index
|
||||
});
|
||||
const $td = h('td', {
|
||||
attrs: {
|
||||
colspan: this.columns.length
|
||||
},
|
||||
class: this.prefixCls + '-expanded-cell'
|
||||
}, [$Expand]);
|
||||
const $tr = h('tr', {
|
||||
class: {
|
||||
[this.prefixCls + '-expanded-hidden']: this.fixed
|
||||
}
|
||||
}, [$td]);
|
||||
$tableTrs.push($tr);
|
||||
}
|
||||
|
||||
// 子数据
|
||||
if (row.children && row.children.length) {
|
||||
const $childNodes = this.getChildNode(h, row, []);
|
||||
$childNodes.forEach(item => {
|
||||
$tableTrs.push(item);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const $tbody = h('tbody', {
|
||||
class: this.prefixCls + '-tbody'
|
||||
}, [$tableTrs]);
|
||||
|
||||
return h('table', {
|
||||
attrs: {
|
||||
cellspacing: '0',
|
||||
cellpadding: '0',
|
||||
border: '0'
|
||||
},
|
||||
style: this.styleObject
|
||||
}, [$colgroup, $tbody]);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -256,6 +256,11 @@
|
|||
// 4.0.0
|
||||
sumText: {
|
||||
type: String
|
||||
},
|
||||
// 4.1.0
|
||||
indentSize: {
|
||||
type: Number,
|
||||
default: 16
|
||||
}
|
||||
},
|
||||
data () {
|
||||
|
@ -925,9 +930,27 @@
|
|||
data.forEach((row, index) => {
|
||||
row._index = index;
|
||||
row._rowKey = rowKey++;
|
||||
if (row.child && row.children.length) {
|
||||
row.children = this.makeChildrenData(row);
|
||||
}
|
||||
});
|
||||
return data;
|
||||
},
|
||||
makeChildrenData (data) {
|
||||
if (data.children && data.children.length) {
|
||||
data.children.map((row, index) => {
|
||||
const newRow = deepCopy(row);
|
||||
newRow._index = index;
|
||||
newRow._rowKey = rowKey++;
|
||||
if (newRow.children && newRow.children.length) {
|
||||
newRow.children = this.makeChildrenData(newRow);
|
||||
}
|
||||
return newRow;
|
||||
});
|
||||
} else {
|
||||
return data;
|
||||
}
|
||||
},
|
||||
makeDataWithSort () {
|
||||
let data = this.makeData();
|
||||
let sortType = 'normal';
|
||||
|
@ -955,35 +978,60 @@
|
|||
this.cloneColumns.forEach(col => data = this.filterData(data, col));
|
||||
return data;
|
||||
},
|
||||
makeObjBaseData (row) {
|
||||
const newRow = deepCopy(row);
|
||||
newRow._isHover = false;
|
||||
if (newRow._disabled) {
|
||||
newRow._isDisabled = newRow._disabled;
|
||||
} else {
|
||||
newRow._isDisabled = false;
|
||||
}
|
||||
if (newRow._checked) {
|
||||
newRow._isChecked = newRow._checked;
|
||||
} else {
|
||||
newRow._isChecked = false;
|
||||
}
|
||||
if (newRow._expanded) {
|
||||
newRow._isExpanded = newRow._expanded;
|
||||
} else {
|
||||
newRow._isExpanded = false;
|
||||
}
|
||||
if (newRow._highlight) {
|
||||
newRow._isHighlight = newRow._highlight;
|
||||
} else {
|
||||
newRow._isHighlight = false;
|
||||
}
|
||||
return newRow;
|
||||
},
|
||||
makeObjData () {
|
||||
let data = {};
|
||||
this.data.forEach((row, index) => {
|
||||
const newRow = deepCopy(row);// todo 直接替换
|
||||
newRow._isHover = false;
|
||||
if (newRow._disabled) {
|
||||
newRow._isDisabled = newRow._disabled;
|
||||
} else {
|
||||
newRow._isDisabled = false;
|
||||
}
|
||||
if (newRow._checked) {
|
||||
newRow._isChecked = newRow._checked;
|
||||
} else {
|
||||
newRow._isChecked = false;
|
||||
}
|
||||
if (newRow._expanded) {
|
||||
newRow._isExpanded = newRow._expanded;
|
||||
} else {
|
||||
newRow._isExpanded = false;
|
||||
}
|
||||
if (newRow._highlight) {
|
||||
newRow._isHighlight = newRow._highlight;
|
||||
} else {
|
||||
newRow._isHighlight = false;
|
||||
const newRow = this.makeObjBaseData(row);
|
||||
if (newRow.children && newRow.children.length) {
|
||||
if (newRow._showChildren) {
|
||||
newRow._isShowChildren = newRow._showChildren;
|
||||
} else {
|
||||
newRow._isShowChildren = false;
|
||||
}
|
||||
newRow.children = this.makeChildrenObjData(newRow);
|
||||
}
|
||||
data[index] = newRow;
|
||||
});
|
||||
return data;
|
||||
},
|
||||
makeChildrenObjData (data) {
|
||||
if (data.children && data.children.length) {
|
||||
data.children.map(row => {
|
||||
const newRow = this.makeObjBaseData(row);
|
||||
if (newRow.children && newRow.children.length) {
|
||||
newRow.children = this.makeChildrenObjData(newRow);
|
||||
}
|
||||
return newRow;
|
||||
});
|
||||
} else {
|
||||
return data;
|
||||
}
|
||||
},
|
||||
// 修改列,设置一个隐藏的 id,便于后面的多级表头寻找对应的列,否则找不到
|
||||
makeColumnsId (columns) {
|
||||
return columns.map(item => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue