update Table
update Table
This commit is contained in:
parent
abdec99d22
commit
a3547c1b41
4 changed files with 149 additions and 66 deletions
68
src/components/table/cell.vue
Normal file
68
src/components/table/cell.vue
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
<template>
|
||||||
|
<div :class="[prefixCls + '-cell']">
|
||||||
|
<template v-if="renderType === 'index'">{{index + 1}}</template>
|
||||||
|
<template v-if="renderType === 'normal'">{{{ row[column.key] }}}</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
prefixCls: String,
|
||||||
|
row: Object,
|
||||||
|
column: Object,
|
||||||
|
index: Number
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
renderType: '',
|
||||||
|
uid: -1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
compile () {
|
||||||
|
if (this.column.render) {
|
||||||
|
const template = this.column.render(this.row, this.column, this.index);
|
||||||
|
const cell = document.createElement('div');
|
||||||
|
cell.innerHTML = template;
|
||||||
|
const _oldParentChildLen = this.$parent.$parent.$children.length;
|
||||||
|
this.$parent.$parent.$compile(cell);
|
||||||
|
const _newParentChildLen = this.$parent.$parent.$children.length;
|
||||||
|
|
||||||
|
if (_oldParentChildLen !== _newParentChildLen) { // if render normal html node, do not tag
|
||||||
|
this.uid = this.$parent.$parent.$children[this.$parent.$parent.$children.length - 1]._uid; // tag it, and delete when data or columns update
|
||||||
|
}
|
||||||
|
this.$el.innerHTML = '';
|
||||||
|
this.$el.appendChild(cell);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
destroy () {
|
||||||
|
for (let i = 0; i < this.$parent.$parent.$children.length; i++) {
|
||||||
|
if (this.$parent.$parent.$children[i]._uid === this.uid) {
|
||||||
|
this.$parent.$parent.$children[i].$destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
compiled () {
|
||||||
|
if (this.column.type === 'index') {
|
||||||
|
this.renderType = 'index';
|
||||||
|
} else if (this.column.render) {
|
||||||
|
this.renderType = 'render';
|
||||||
|
} else {
|
||||||
|
this.renderType = 'normal';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ready () {
|
||||||
|
this.compile();
|
||||||
|
},
|
||||||
|
beforeDestroy () {
|
||||||
|
this.destroy();
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
index () {
|
||||||
|
this.destroy();
|
||||||
|
this.compile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -26,12 +26,19 @@
|
||||||
@mouseleave.stop="handleMouseOut(index)"
|
@mouseleave.stop="handleMouseOut(index)"
|
||||||
@click.stop="highlightCurrentRow(index)">
|
@click.stop="highlightCurrentRow(index)">
|
||||||
<td v-for="column in cloneColumns" :class="alignCls(column)">
|
<td v-for="column in cloneColumns" :class="alignCls(column)">
|
||||||
<div :class="[prefixCls + '-cell']">
|
<div :class="[prefixCls + '-cell']" v-if="column.type === 'selection'">
|
||||||
<template v-if="column.type === 'selection'">
|
<Checkbox :checked="cloneData[index] && cloneData[index]._isChecked" @on-change="toggleSelect(index)"></Checkbox>
|
||||||
<Checkbox :checked="cloneData[index] && cloneData[index]._isChecked" @on-change="toggleSelect(index)"></Checkbox>
|
|
||||||
</template>
|
|
||||||
<template v-else>{{{ renderRow(row, column, index) }}}</template>
|
|
||||||
</div>
|
</div>
|
||||||
|
<Cell v-else :prefix-cls="prefixCls" :row="row" :column="column" :index="index"></Cell>
|
||||||
|
<!--<div :class="[prefixCls + '-cell']" v-else>-->
|
||||||
|
<!--{{{ renderRow(row, column, index) }}}-->
|
||||||
|
<!--</div>-->
|
||||||
|
<!--<div :class="[prefixCls + '-cell']">-->
|
||||||
|
<!--<template v-if="column.type === 'selection'">-->
|
||||||
|
<!--<Checkbox :checked="cloneData[index] && cloneData[index]._isChecked" @on-change="toggleSelect(index)"></Checkbox>-->
|
||||||
|
<!--</template>-->
|
||||||
|
<!--<template v-else>{{{ renderRow(row, column, index) }}}</template>-->
|
||||||
|
<!--</div>-->
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -49,13 +56,14 @@
|
||||||
<script>
|
<script>
|
||||||
import TableHead from './table-head.vue';
|
import TableHead from './table-head.vue';
|
||||||
import Checkbox from '../checkbox/checkbox.vue';
|
import Checkbox from '../checkbox/checkbox.vue';
|
||||||
|
import Cell from './cell.vue';
|
||||||
import Mixin from './mixin';
|
import Mixin from './mixin';
|
||||||
import { oneOf, getStyle, deepCopy } from '../../utils/assist';
|
import { oneOf, getStyle, deepCopy } from '../../utils/assist';
|
||||||
const prefixCls = 'ivu-table';
|
const prefixCls = 'ivu-table';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [ Mixin ],
|
mixins: [ Mixin ],
|
||||||
components: { TableHead, Checkbox },
|
components: { TableHead, Checkbox, Cell },
|
||||||
props: {
|
props: {
|
||||||
data: {
|
data: {
|
||||||
type: Array,
|
type: Array,
|
||||||
|
@ -108,6 +116,9 @@
|
||||||
compiledUids: [],
|
compiledUids: [],
|
||||||
cloneData: deepCopy(this.data),
|
cloneData: deepCopy(this.data),
|
||||||
cloneColumns: deepCopy(this.columns),
|
cloneColumns: deepCopy(this.columns),
|
||||||
|
leftFixedColumns: [],
|
||||||
|
rightFixedColumns: [],
|
||||||
|
centerColumns: [],
|
||||||
showSlotHeader: true,
|
showSlotHeader: true,
|
||||||
showSlotFooter: true,
|
showSlotFooter: true,
|
||||||
bodyHeight: 0
|
bodyHeight: 0
|
||||||
|
@ -147,53 +158,25 @@
|
||||||
rowClsName (index) {
|
rowClsName (index) {
|
||||||
return this.rowClassName(this.data[index], index);
|
return this.rowClassName(this.data[index], index);
|
||||||
},
|
},
|
||||||
renderRow (row, column, index) {
|
|
||||||
return column.type === 'index' ? index + 1 : column.render ? '' : row[column.key];
|
|
||||||
},
|
|
||||||
compileRender (update = false) {
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if (update) {
|
|
||||||
for (let i = 0; i < this.$parent.$children.length; i++) {
|
|
||||||
const index = this.compiledUids.indexOf(this.$parent.$children[i]._uid);
|
|
||||||
if (index > -1) {
|
|
||||||
this.$parent.$children[i].$destroy();
|
|
||||||
this.compiledUids.splice(index, 1);
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const $el = this.$els.render;
|
|
||||||
for (let i = 0; i < this.cloneColumns.length; i++) {
|
|
||||||
const column = this.cloneColumns[i];
|
|
||||||
if (column.render) {
|
|
||||||
for (let j = 0; j < this.data.length; j++) {
|
|
||||||
// todo 做一个缓存,只在需要改render时再重新编译,data改变时不用再编译
|
|
||||||
const row = this.data[j];
|
|
||||||
const template = column.render(row, column, j);
|
|
||||||
const cell = document.createElement('div');
|
|
||||||
cell.innerHTML = template;
|
|
||||||
const _oldParentChildLen = this.$parent.$children.length;
|
|
||||||
this.$parent.$compile(cell);
|
|
||||||
const _newParentChildLen = this.$parent.$children.length;
|
|
||||||
|
|
||||||
if (_oldParentChildLen !== _newParentChildLen) { // if render normal html node, do not tag
|
|
||||||
this.compiledUids.push(this.$parent.$children[this.$parent.$children.length - 1]._uid); // tag it, and delete when data or columns update
|
|
||||||
}
|
|
||||||
$el.children[j].children[i].children[0].innerHTML = '';
|
|
||||||
$el.children[j].children[i].children[0].appendChild(cell);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.handleResize();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleResize () {
|
handleResize () {
|
||||||
this.tableWidth = parseInt(getStyle(this.$el, 'width'));
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.columnsWidth = [];
|
const allWidth = !this.columns.some(cell => !cell.width);
|
||||||
this.$els.tbody.querySelectorAll('tbody tr')[0].querySelectorAll('td').forEach((cell) => {
|
if (allWidth) {
|
||||||
this.columnsWidth.push(parseInt(getStyle(cell, 'width')));
|
this.tableWidth = this.columns.map(cell => cell.width).reduce((a, b) => a + b);
|
||||||
|
} else {
|
||||||
|
this.tableWidth = parseInt(getStyle(this.$el, 'width')) - 1;
|
||||||
|
}
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.columnsWidth = [];
|
||||||
|
let autoWidthIndex = -1
|
||||||
|
if (allWidth) autoWidthIndex = this.cloneColumns.findIndex(cell => !cell.width);
|
||||||
|
this.$els.tbody.querySelectorAll('tbody tr')[0].querySelectorAll('td').forEach((cell, index) => {
|
||||||
|
if (index === autoWidthIndex) {
|
||||||
|
this.columnsWidth.push(parseInt(getStyle(cell, 'width')) - 1);
|
||||||
|
} else {
|
||||||
|
this.columnsWidth.push(parseInt(getStyle(cell, 'width')));
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -282,6 +265,9 @@
|
||||||
center.push(col);
|
center.push(col);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.leftFixedColumns = left;
|
||||||
|
this.rightFixedColumns = right;
|
||||||
|
this.centerColumns = center;
|
||||||
this.cloneColumns = left.concat(center).concat(right);
|
this.cloneColumns = left.concat(center).concat(right);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -291,7 +277,7 @@
|
||||||
this.showSlotFooter = this.$els.footer.innerHTML.replace(/\n/g, '').replace(/<!--[\w\W\r\n]*?-->/gmi, '') !== '';
|
this.showSlotFooter = this.$els.footer.innerHTML.replace(/\n/g, '').replace(/<!--[\w\W\r\n]*?-->/gmi, '') !== '';
|
||||||
},
|
},
|
||||||
ready () {
|
ready () {
|
||||||
this.compileRender();
|
this.handleResize();
|
||||||
this.fixedHeader();
|
this.fixedHeader();
|
||||||
window.addEventListener('resize', this.handleResize, false);
|
window.addEventListener('resize', this.handleResize, false);
|
||||||
},
|
},
|
||||||
|
@ -302,14 +288,14 @@
|
||||||
data: {
|
data: {
|
||||||
handler () {
|
handler () {
|
||||||
this.cloneData = deepCopy(this.data);
|
this.cloneData = deepCopy(this.data);
|
||||||
this.compileRender(true);
|
this.handleResize();
|
||||||
},
|
},
|
||||||
deep: true
|
deep: true
|
||||||
},
|
},
|
||||||
columns: {
|
columns: {
|
||||||
handler () {
|
handler () {
|
||||||
this.parseColumns();
|
this.parseColumns();
|
||||||
this.compileRender(true);
|
this.handleResize();
|
||||||
},
|
},
|
||||||
deep: true
|
deep: true
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,10 +9,33 @@
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border: 1px solid @border-color-base;
|
border: 1px solid @border-color-base;
|
||||||
border-bottom: 0;
|
border-bottom: 0;
|
||||||
|
border-right: 0;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
&:before{
|
||||||
|
content: '';
|
||||||
|
width: 100%;
|
||||||
|
height: 1px;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: @border-color-base;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after{
|
||||||
|
content: '';
|
||||||
|
width: 1px;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: @border-color-base;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
&-with-header{
|
&-with-header{
|
||||||
border-radius: @border-radius-base @border-radius-base 0 0;
|
border-radius: @border-radius-base @border-radius-base 0 0;
|
||||||
}
|
}
|
||||||
|
@ -36,8 +59,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&-body{
|
&-body{
|
||||||
overflow-x: hidden;
|
//overflow-x: hidden;
|
||||||
overflow-y: auto;
|
//overflow-y: auto;
|
||||||
|
overflow: auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +115,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
& table{
|
& table{
|
||||||
width: 100%;
|
//width: 100%;
|
||||||
|
table-layout: fixed;
|
||||||
}
|
}
|
||||||
&-border{
|
&-border{
|
||||||
th,td{
|
th,td{
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
<!--<i-table size="large" border stripe :columns="columns" :data="data"></i-table>-->
|
<!--<i-table size="large" border stripe :columns="columns" :data="data"></i-table>-->
|
||||||
<br>
|
<br>
|
||||||
<i-table
|
<i-table
|
||||||
|
style="width:450px"
|
||||||
border
|
border
|
||||||
highlight-row
|
highlight-row
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
|
@ -57,7 +58,7 @@
|
||||||
title: '地址',
|
title: '地址',
|
||||||
key: 'address',
|
key: 'address',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
// width: 100
|
width: 100,
|
||||||
// render (row, column, index) {
|
// render (row, column, index) {
|
||||||
// if (row.edit) {
|
// if (row.edit) {
|
||||||
// return `<i-input :value.sync="data[${index}].name"></i-input>`;
|
// return `<i-input :value.sync="data[${index}].name"></i-input>`;
|
||||||
|
@ -72,7 +73,8 @@
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
width: 200,
|
width: 200,
|
||||||
render (row, column, index) {
|
render (row, column, index) {
|
||||||
return `<i-button @click="edit(${index})">编辑</i-button>`
|
return `<i-button @click="edit(${index})">${row.name}</i-button>`
|
||||||
|
// return `<a>${row.name}</a>`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -140,14 +142,16 @@
|
||||||
},
|
},
|
||||||
ready () {
|
ready () {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
return;
|
||||||
// this.height = 150;
|
// this.height = 150;
|
||||||
return
|
// return
|
||||||
this.data.push({
|
// this.data.push({
|
||||||
name: '刘天娇2',
|
// name: '刘天娇2',
|
||||||
age: 272,
|
// age: 272,
|
||||||
address: '北京市东城区2',
|
// address: '北京市东城区2',
|
||||||
edit: false
|
// edit: false
|
||||||
});
|
// });
|
||||||
|
this.data.splice(1, 1)
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue