update Table

update Table
This commit is contained in:
梁灏 2016-11-25 15:47:28 +08:00
parent abdec99d22
commit a3547c1b41
4 changed files with 149 additions and 66 deletions

View 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>

View file

@ -26,12 +26,19 @@
@mouseleave.stop="handleMouseOut(index)"
@click.stop="highlightCurrentRow(index)">
<td v-for="column in cloneColumns" :class="alignCls(column)">
<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 :class="[prefixCls + '-cell']" v-if="column.type === 'selection'">
<Checkbox :checked="cloneData[index] && cloneData[index]._isChecked" @on-change="toggleSelect(index)"></Checkbox>
</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>
</tr>
</tbody>
@ -49,13 +56,14 @@
<script>
import TableHead from './table-head.vue';
import Checkbox from '../checkbox/checkbox.vue';
import Cell from './cell.vue';
import Mixin from './mixin';
import { oneOf, getStyle, deepCopy } from '../../utils/assist';
const prefixCls = 'ivu-table';
export default {
mixins: [ Mixin ],
components: { TableHead, Checkbox },
components: { TableHead, Checkbox, Cell },
props: {
data: {
type: Array,
@ -108,6 +116,9 @@
compiledUids: [],
cloneData: deepCopy(this.data),
cloneColumns: deepCopy(this.columns),
leftFixedColumns: [],
rightFixedColumns: [],
centerColumns: [],
showSlotHeader: true,
showSlotFooter: true,
bodyHeight: 0
@ -147,53 +158,25 @@
rowClsName (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 renderdata
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 () {
this.tableWidth = parseInt(getStyle(this.$el, 'width'));
this.$nextTick(() => {
this.columnsWidth = [];
this.$els.tbody.querySelectorAll('tbody tr')[0].querySelectorAll('td').forEach((cell) => {
this.columnsWidth.push(parseInt(getStyle(cell, 'width')));
const allWidth = !this.columns.some(cell => !cell.width);
if (allWidth) {
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);
}
});
this.leftFixedColumns = left;
this.rightFixedColumns = right;
this.centerColumns = center;
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, '') !== '';
},
ready () {
this.compileRender();
this.handleResize();
this.fixedHeader();
window.addEventListener('resize', this.handleResize, false);
},
@ -302,14 +288,14 @@
data: {
handler () {
this.cloneData = deepCopy(this.data);
this.compileRender(true);
this.handleResize();
},
deep: true
},
columns: {
handler () {
this.parseColumns();
this.compileRender(true);
this.handleResize();
},
deep: true
},

View file

@ -9,10 +9,33 @@
background-color: #fff;
border: 1px solid @border-color-base;
border-bottom: 0;
border-right: 0;
border-collapse: collapse;
box-sizing: border-box;
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{
border-radius: @border-radius-base @border-radius-base 0 0;
}
@ -36,8 +59,9 @@
}
&-body{
overflow-x: hidden;
overflow-y: auto;
//overflow-x: hidden;
//overflow-y: auto;
overflow: auto;
position: relative;
}
@ -91,7 +115,8 @@
}
& table{
width: 100%;
//width: 100%;
table-layout: fixed;
}
&-border{
th,td{

View file

@ -8,6 +8,7 @@
<!--<i-table size="large" border stripe :columns="columns" :data="data"></i-table>-->
<br>
<i-table
style="width:450px"
border
highlight-row
:columns="columns"
@ -57,7 +58,7 @@
title: '地址',
key: 'address',
align: 'center',
// width: 100
width: 100,
// render (row, column, index) {
// if (row.edit) {
// return `<i-input :value.sync="data[${index}].name"></i-input>`;
@ -72,7 +73,8 @@
fixed: 'right',
width: 200,
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 () {
setTimeout(() => {
return;
// this.height = 150;
return
this.data.push({
name: '刘天娇2',
age: 272,
address: '北京市东城区2',
edit: false
});
// return
// this.data.push({
// name: '2',
// age: 272,
// address: '2',
// edit: false
// });
this.data.splice(1, 1)
}, 1000);
}
}