Commit a3547c1b41b9f411fdc00d327ee093a0cd260dfe

Authored by 梁灏
1 parent abdec99d

update Table

update Table
src/components/table/cell.vue 0 → 100644
  1 +<template>
  2 + <div :class="[prefixCls + '-cell']">
  3 + <template v-if="renderType === 'index'">{{index + 1}}</template>
  4 + <template v-if="renderType === 'normal'">{{{ row[column.key] }}}</template>
  5 + </div>
  6 +</template>
  7 +<script>
  8 + export default {
  9 + props: {
  10 + prefixCls: String,
  11 + row: Object,
  12 + column: Object,
  13 + index: Number
  14 + },
  15 + data () {
  16 + return {
  17 + renderType: '',
  18 + uid: -1
  19 + }
  20 + },
  21 + methods: {
  22 + compile () {
  23 + if (this.column.render) {
  24 + const template = this.column.render(this.row, this.column, this.index);
  25 + const cell = document.createElement('div');
  26 + cell.innerHTML = template;
  27 + const _oldParentChildLen = this.$parent.$parent.$children.length;
  28 + this.$parent.$parent.$compile(cell);
  29 + const _newParentChildLen = this.$parent.$parent.$children.length;
  30 +
  31 + if (_oldParentChildLen !== _newParentChildLen) { // if render normal html node, do not tag
  32 + this.uid = this.$parent.$parent.$children[this.$parent.$parent.$children.length - 1]._uid; // tag it, and delete when data or columns update
  33 + }
  34 + this.$el.innerHTML = '';
  35 + this.$el.appendChild(cell);
  36 + }
  37 + },
  38 + destroy () {
  39 + for (let i = 0; i < this.$parent.$parent.$children.length; i++) {
  40 + if (this.$parent.$parent.$children[i]._uid === this.uid) {
  41 + this.$parent.$parent.$children[i].$destroy();
  42 + }
  43 + }
  44 + }
  45 + },
  46 + compiled () {
  47 + if (this.column.type === 'index') {
  48 + this.renderType = 'index';
  49 + } else if (this.column.render) {
  50 + this.renderType = 'render';
  51 + } else {
  52 + this.renderType = 'normal';
  53 + }
  54 + },
  55 + ready () {
  56 + this.compile();
  57 + },
  58 + beforeDestroy () {
  59 + this.destroy();
  60 + },
  61 + watch: {
  62 + index () {
  63 + this.destroy();
  64 + this.compile();
  65 + }
  66 + }
  67 + }
  68 +</script>
0 69 \ No newline at end of file
... ...
src/components/table/table.vue
... ... @@ -26,12 +26,19 @@
26 26 @mouseleave.stop="handleMouseOut(index)"
27 27 @click.stop="highlightCurrentRow(index)">
28 28 <td v-for="column in cloneColumns" :class="alignCls(column)">
29   - <div :class="[prefixCls + '-cell']">
30   - <template v-if="column.type === 'selection'">
31   - <Checkbox :checked="cloneData[index] && cloneData[index]._isChecked" @on-change="toggleSelect(index)"></Checkbox>
32   - </template>
33   - <template v-else>{{{ renderRow(row, column, index) }}}</template>
  29 + <div :class="[prefixCls + '-cell']" v-if="column.type === 'selection'">
  30 + <Checkbox :checked="cloneData[index] && cloneData[index]._isChecked" @on-change="toggleSelect(index)"></Checkbox>
34 31 </div>
  32 + <Cell v-else :prefix-cls="prefixCls" :row="row" :column="column" :index="index"></Cell>
  33 + <!--<div :class="[prefixCls + '-cell']" v-else>-->
  34 + <!--{{{ renderRow(row, column, index) }}}-->
  35 + <!--</div>-->
  36 + <!--<div :class="[prefixCls + '-cell']">-->
  37 + <!--<template v-if="column.type === 'selection'">-->
  38 + <!--<Checkbox :checked="cloneData[index] && cloneData[index]._isChecked" @on-change="toggleSelect(index)"></Checkbox>-->
  39 + <!--</template>-->
  40 + <!--<template v-else>{{{ renderRow(row, column, index) }}}</template>-->
  41 + <!--</div>-->
35 42 </td>
36 43 </tr>
37 44 </tbody>
... ... @@ -49,13 +56,14 @@
49 56 <script>
50 57 import TableHead from './table-head.vue';
51 58 import Checkbox from '../checkbox/checkbox.vue';
  59 + import Cell from './cell.vue';
52 60 import Mixin from './mixin';
53 61 import { oneOf, getStyle, deepCopy } from '../../utils/assist';
54 62 const prefixCls = 'ivu-table';
55 63  
56 64 export default {
57 65 mixins: [ Mixin ],
58   - components: { TableHead, Checkbox },
  66 + components: { TableHead, Checkbox, Cell },
59 67 props: {
60 68 data: {
61 69 type: Array,
... ... @@ -108,6 +116,9 @@
108 116 compiledUids: [],
109 117 cloneData: deepCopy(this.data),
110 118 cloneColumns: deepCopy(this.columns),
  119 + leftFixedColumns: [],
  120 + rightFixedColumns: [],
  121 + centerColumns: [],
111 122 showSlotHeader: true,
112 123 showSlotFooter: true,
113 124 bodyHeight: 0
... ... @@ -147,53 +158,25 @@
147 158 rowClsName (index) {
148 159 return this.rowClassName(this.data[index], index);
149 160 },
150   - renderRow (row, column, index) {
151   - return column.type === 'index' ? index + 1 : column.render ? '' : row[column.key];
152   - },
153   - compileRender (update = false) {
  161 + handleResize () {
154 162 this.$nextTick(() => {
155   - if (update) {
156   - for (let i = 0; i < this.$parent.$children.length; i++) {
157   - const index = this.compiledUids.indexOf(this.$parent.$children[i]._uid);
158   - if (index > -1) {
159   - this.$parent.$children[i].$destroy();
160   - this.compiledUids.splice(index, 1);
161   - i--;
162   - }
163   - }
  163 + const allWidth = !this.columns.some(cell => !cell.width);
  164 + if (allWidth) {
  165 + this.tableWidth = this.columns.map(cell => cell.width).reduce((a, b) => a + b);
  166 + } else {
  167 + this.tableWidth = parseInt(getStyle(this.$el, 'width')) - 1;
164 168 }
165   -
166   - const $el = this.$els.render;
167   - for (let i = 0; i < this.cloneColumns.length; i++) {
168   - const column = this.cloneColumns[i];
169   - if (column.render) {
170   - for (let j = 0; j < this.data.length; j++) {
171   - // todo 做一个缓存,只在需要改render时再重新编译,data改变时不用再编译
172   - const row = this.data[j];
173   - const template = column.render(row, column, j);
174   - const cell = document.createElement('div');
175   - cell.innerHTML = template;
176   - const _oldParentChildLen = this.$parent.$children.length;
177   - this.$parent.$compile(cell);
178   - const _newParentChildLen = this.$parent.$children.length;
179   -
180   - if (_oldParentChildLen !== _newParentChildLen) { // if render normal html node, do not tag
181   - this.compiledUids.push(this.$parent.$children[this.$parent.$children.length - 1]._uid); // tag it, and delete when data or columns update
182   - }
183   - $el.children[j].children[i].children[0].innerHTML = '';
184   - $el.children[j].children[i].children[0].appendChild(cell);
  169 + this.$nextTick(() => {
  170 + this.columnsWidth = [];
  171 + let autoWidthIndex = -1
  172 + if (allWidth) autoWidthIndex = this.cloneColumns.findIndex(cell => !cell.width);
  173 + this.$els.tbody.querySelectorAll('tbody tr')[0].querySelectorAll('td').forEach((cell, index) => {
  174 + if (index === autoWidthIndex) {
  175 + this.columnsWidth.push(parseInt(getStyle(cell, 'width')) - 1);
  176 + } else {
  177 + this.columnsWidth.push(parseInt(getStyle(cell, 'width')));
185 178 }
186   - }
187   - }
188   - this.handleResize();
189   - });
190   - },
191   - handleResize () {
192   - this.tableWidth = parseInt(getStyle(this.$el, 'width'));
193   - this.$nextTick(() => {
194   - this.columnsWidth = [];
195   - this.$els.tbody.querySelectorAll('tbody tr')[0].querySelectorAll('td').forEach((cell) => {
196   - this.columnsWidth.push(parseInt(getStyle(cell, 'width')));
  179 + });
197 180 });
198 181 });
199 182 },
... ... @@ -282,6 +265,9 @@
282 265 center.push(col);
283 266 }
284 267 });
  268 + this.leftFixedColumns = left;
  269 + this.rightFixedColumns = right;
  270 + this.centerColumns = center;
285 271 this.cloneColumns = left.concat(center).concat(right);
286 272 }
287 273 },
... ... @@ -291,7 +277,7 @@
291 277 this.showSlotFooter = this.$els.footer.innerHTML.replace(/\n/g, '').replace(/<!--[\w\W\r\n]*?-->/gmi, '') !== '';
292 278 },
293 279 ready () {
294   - this.compileRender();
  280 + this.handleResize();
295 281 this.fixedHeader();
296 282 window.addEventListener('resize', this.handleResize, false);
297 283 },
... ... @@ -302,14 +288,14 @@
302 288 data: {
303 289 handler () {
304 290 this.cloneData = deepCopy(this.data);
305   - this.compileRender(true);
  291 + this.handleResize();
306 292 },
307 293 deep: true
308 294 },
309 295 columns: {
310 296 handler () {
311 297 this.parseColumns();
312   - this.compileRender(true);
  298 + this.handleResize();
313 299 },
314 300 deep: true
315 301 },
... ...
src/styles/components/table.less
... ... @@ -9,10 +9,33 @@
9 9 background-color: #fff;
10 10 border: 1px solid @border-color-base;
11 11 border-bottom: 0;
  12 + border-right: 0;
12 13 border-collapse: collapse;
13 14 box-sizing: border-box;
14 15 position: relative;
15 16  
  17 + &:before{
  18 + content: '';
  19 + width: 100%;
  20 + height: 1px;
  21 + position: absolute;
  22 + left: 0;
  23 + bottom: 0;
  24 + background-color: @border-color-base;
  25 + z-index: 1;
  26 + }
  27 +
  28 + &:after{
  29 + content: '';
  30 + width: 1px;
  31 + height: 100%;
  32 + position: absolute;
  33 + top: 0;
  34 + right: 0;
  35 + background-color: @border-color-base;
  36 + z-index: 1;
  37 + }
  38 +
16 39 &-with-header{
17 40 border-radius: @border-radius-base @border-radius-base 0 0;
18 41 }
... ... @@ -36,8 +59,9 @@
36 59 }
37 60  
38 61 &-body{
39   - overflow-x: hidden;
40   - overflow-y: auto;
  62 + //overflow-x: hidden;
  63 + //overflow-y: auto;
  64 + overflow: auto;
41 65 position: relative;
42 66 }
43 67  
... ... @@ -91,7 +115,8 @@
91 115 }
92 116  
93 117 & table{
94   - width: 100%;
  118 + //width: 100%;
  119 + table-layout: fixed;
95 120 }
96 121 &-border{
97 122 th,td{
... ...
test/routers/table.vue
... ... @@ -8,6 +8,7 @@
8 8 <!--<i-table size="large" border stripe :columns="columns" :data="data"></i-table>-->
9 9 <br>
10 10 <i-table
  11 + style="width:450px"
11 12 border
12 13 highlight-row
13 14 :columns="columns"
... ... @@ -57,7 +58,7 @@
57 58 title: '地址',
58 59 key: 'address',
59 60 align: 'center',
60   -// width: 100
  61 + width: 100,
61 62 // render (row, column, index) {
62 63 // if (row.edit) {
63 64 // return `<i-input :value.sync="data[${index}].name"></i-input>`;
... ... @@ -72,7 +73,8 @@
72 73 fixed: 'right',
73 74 width: 200,
74 75 render (row, column, index) {
75   - return `<i-button @click="edit(${index})">编辑</i-button>`
  76 + return `<i-button @click="edit(${index})">${row.name}</i-button>`
  77 +// return `<a>${row.name}</a>`
76 78 }
77 79 }
78 80 ],
... ... @@ -140,14 +142,16 @@
140 142 },
141 143 ready () {
142 144 setTimeout(() => {
  145 + return;
143 146 // this.height = 150;
144   - return
145   - this.data.push({
146   - name: '刘天娇2',
147   - age: 272,
148   - address: '北京市东城区2',
149   - edit: false
150   - });
  147 +// return
  148 +// this.data.push({
  149 +// name: '刘天娇2',
  150 +// age: 272,
  151 +// address: '北京市东城区2',
  152 +// edit: false
  153 +// });
  154 + this.data.splice(1, 1)
151 155 }, 1000);
152 156 }
153 157 }
... ...