Commit 741b987a33e7637ab90ffffd5367a854f734d0d8
1 parent
52874e27
update Table
update Table
Showing
6 changed files
with
100 additions
and
38 deletions
Show diff stats
src/components/table/cell.vue
| 1 | <template> | 1 | <template> |
| 2 | <div :class="classes"> | 2 | <div :class="classes"> |
| 3 | - <template v-if="renderType === 'index'">{{index + 1}}</template> | 3 | + <template v-if="renderType === 'index'">{{naturalIndex + 1}}</template> |
| 4 | <template v-if="renderType === 'selection'"> | 4 | <template v-if="renderType === 'selection'"> |
| 5 | - <Checkbox :checked="checked" @on-change="toggleSelect(index)"></Checkbox> | 5 | + <Checkbox :checked="checked" @on-change="toggleSelect">{{checked}}</Checkbox> |
| 6 | </template> | 6 | </template> |
| 7 | <template v-if="renderType === 'normal'">{{{ row[column.key] }}}</template> | 7 | <template v-if="renderType === 'normal'">{{{ row[column.key] }}}</template> |
| 8 | </div> | 8 | </div> |
| @@ -16,7 +16,8 @@ | @@ -16,7 +16,8 @@ | ||
| 16 | prefixCls: String, | 16 | prefixCls: String, |
| 17 | row: Object, | 17 | row: Object, |
| 18 | column: Object, | 18 | column: Object, |
| 19 | - index: Number, | 19 | + naturalIndex: Number, // index of rebuildData |
| 20 | + index: Number, // _index of data | ||
| 20 | checked: Boolean, | 21 | checked: Boolean, |
| 21 | fixed: Boolean | 22 | fixed: Boolean |
| 22 | }, | 23 | }, |
| @@ -62,8 +63,8 @@ | @@ -62,8 +63,8 @@ | ||
| 62 | } | 63 | } |
| 63 | } | 64 | } |
| 64 | }, | 65 | }, |
| 65 | - toggleSelect (index) { | ||
| 66 | - this.$parent.$parent.toggleSelect(index); | 66 | + toggleSelect () { |
| 67 | + this.$parent.$parent.toggleSelect(this.index); | ||
| 67 | } | 68 | } |
| 68 | }, | 69 | }, |
| 69 | compiled () { | 70 | compiled () { |
| @@ -84,7 +85,7 @@ | @@ -84,7 +85,7 @@ | ||
| 84 | this.destroy(); | 85 | this.destroy(); |
| 85 | }, | 86 | }, |
| 86 | watch: { | 87 | watch: { |
| 87 | - index () { | 88 | + naturalIndex () { |
| 88 | this.destroy(); | 89 | this.destroy(); |
| 89 | this.compile(); | 90 | this.compile(); |
| 90 | } | 91 | } |
src/components/table/table-body.vue
| @@ -5,8 +5,8 @@ | @@ -5,8 +5,8 @@ | ||
| 5 | </colgroup> | 5 | </colgroup> |
| 6 | <tbody :class="[prefixCls + '-tbody']"> | 6 | <tbody :class="[prefixCls + '-tbody']"> |
| 7 | <tr | 7 | <tr |
| 8 | - v-for="(index, row) in cloneData" | ||
| 9 | - :class="rowClasses(row, index)" | 8 | + v-for="(index, row) in data" |
| 9 | + :class="rowClasses(index, row._index)" | ||
| 10 | @mouseenter.stop="handleMouseIn(index)" | 10 | @mouseenter.stop="handleMouseIn(index)" |
| 11 | @mouseleave.stop="handleMouseOut(index)" | 11 | @mouseleave.stop="handleMouseOut(index)" |
| 12 | @click.stop="highlightCurrentRow(index)"> | 12 | @click.stop="highlightCurrentRow(index)"> |
| @@ -16,8 +16,9 @@ | @@ -16,8 +16,9 @@ | ||
| 16 | :prefix-cls="prefixCls" | 16 | :prefix-cls="prefixCls" |
| 17 | :row="row" | 17 | :row="row" |
| 18 | :column="column" | 18 | :column="column" |
| 19 | - :index="index" | ||
| 20 | - :checked="cloneData[index] && cloneData[index]._isChecked"></Cell> | 19 | + :natural-index="index" |
| 20 | + :index="row._index" | ||
| 21 | + :checked="rowChecked(index, row._index)"></Cell> | ||
| 21 | </td> | 22 | </td> |
| 22 | </tr> | 23 | </tr> |
| 23 | </tbody> | 24 | </tbody> |
| @@ -34,20 +35,27 @@ | @@ -34,20 +35,27 @@ | ||
| 34 | prefixCls: String, | 35 | prefixCls: String, |
| 35 | style: Object, | 36 | style: Object, |
| 36 | columns: Array, | 37 | columns: Array, |
| 38 | + data: Array, // rebuildData | ||
| 37 | cloneData: Array, | 39 | cloneData: Array, |
| 40 | + objData: Object, | ||
| 38 | fixed: Boolean | 41 | fixed: Boolean |
| 39 | }, | 42 | }, |
| 40 | methods: { | 43 | methods: { |
| 41 | - rowClasses (row, index) { | 44 | + rowClasses (index, _index) { |
| 42 | return [ | 45 | return [ |
| 43 | `${this.prefixCls}-row`, | 46 | `${this.prefixCls}-row`, |
| 44 | - this.rowClsName(index), | 47 | + this.rowClsName(_index), |
| 45 | { | 48 | { |
| 46 | [`${this.prefixCls}-row-highlight`]: this.cloneData[index] && this.cloneData[index]._isHighlight, | 49 | [`${this.prefixCls}-row-highlight`]: this.cloneData[index] && this.cloneData[index]._isHighlight, |
| 47 | [`${this.prefixCls}-row-hover`]: this.cloneData[index] && this.cloneData[index]._isHover | 50 | [`${this.prefixCls}-row-hover`]: this.cloneData[index] && this.cloneData[index]._isHover |
| 48 | } | 51 | } |
| 49 | ] | 52 | ] |
| 50 | }, | 53 | }, |
| 54 | + rowChecked (index, _index) { | ||
| 55 | +// const data = this.cloneData.filter(row => row._index === _index); | ||
| 56 | +// return data && data._isChecked; | ||
| 57 | + return this.objData[_index]._isChecked; | ||
| 58 | + }, | ||
| 51 | setCellWidth (column, index) { | 59 | setCellWidth (column, index) { |
| 52 | return this.$parent.setCellWidth(column, index); | 60 | return this.$parent.setCellWidth(column, index); |
| 53 | }, | 61 | }, |
src/components/table/table-head.vue
| @@ -11,8 +11,8 @@ | @@ -11,8 +11,8 @@ | ||
| 11 | <template v-else> | 11 | <template v-else> |
| 12 | {{{ renderHeader(column, $index) }}} | 12 | {{{ renderHeader(column, $index) }}} |
| 13 | <span :class="[prefixCls + '-sort']" v-if="column.sortable"> | 13 | <span :class="[prefixCls + '-sort']" v-if="column.sortable"> |
| 14 | - <i class="ivu-icon ivu-icon-arrow-up-b" @click="handleSortAsc($index)"></i> | ||
| 15 | - <i class="ivu-icon ivu-icon-arrow-down-b" @click="handleSortDesc($index)"></i> | 14 | + <i class="ivu-icon ivu-icon-arrow-up-b" :class="{on: sortType === 'asc'}" @click="handleSortAsc($index)"></i> |
| 15 | + <i class="ivu-icon ivu-icon-arrow-down-b" :class="{on: sortType === 'desc'}" @click="handleSortDesc($index)"></i> | ||
| 16 | </span> | 16 | </span> |
| 17 | </template> | 17 | </template> |
| 18 | </div> | 18 | </div> |
| @@ -36,6 +36,11 @@ | @@ -36,6 +36,11 @@ | ||
| 36 | cloneData: Array, | 36 | cloneData: Array, |
| 37 | fixed: Boolean | 37 | fixed: Boolean |
| 38 | }, | 38 | }, |
| 39 | + data () { | ||
| 40 | + return { | ||
| 41 | + sortType: 'normal' | ||
| 42 | + } | ||
| 43 | + }, | ||
| 39 | computed: { | 44 | computed: { |
| 40 | isSelectAll () { | 45 | isSelectAll () { |
| 41 | return !this.cloneData.some(data => !data._isChecked); | 46 | return !this.cloneData.some(data => !data._isChecked); |
| @@ -65,10 +70,22 @@ | @@ -65,10 +70,22 @@ | ||
| 65 | this.$parent.selectAll(status); | 70 | this.$parent.selectAll(status); |
| 66 | }, | 71 | }, |
| 67 | handleSortAsc (index) { | 72 | handleSortAsc (index) { |
| 68 | - this.$parent.handleSort(index, 'asc'); | 73 | + if (this.sortType === 'asc') { |
| 74 | + this.sortType = 'normal'; | ||
| 75 | + this.$parent.handleSort(index, 'normal'); | ||
| 76 | + } else { | ||
| 77 | + this.sortType = 'asc'; | ||
| 78 | + this.$parent.handleSort(index, 'asc'); | ||
| 79 | + } | ||
| 69 | }, | 80 | }, |
| 70 | handleSortDesc (index) { | 81 | handleSortDesc (index) { |
| 71 | - this.$parent.handleSort(index, 'desc'); | 82 | + if (this.sortType === 'desc') { |
| 83 | + this.sortType = 'normal'; | ||
| 84 | + this.$parent.handleSort(index, 'normal'); | ||
| 85 | + } else { | ||
| 86 | + this.sortType = 'desc'; | ||
| 87 | + this.$parent.handleSort(index, 'desc'); | ||
| 88 | + } | ||
| 72 | } | 89 | } |
| 73 | } | 90 | } |
| 74 | } | 91 | } |
src/components/table/table.vue
| 1 | <template> | 1 | <template> |
| 2 | + {{cloneData|json}} | ||
| 2 | <div :class="classes" :style="styles"> | 3 | <div :class="classes" :style="styles"> |
| 3 | <div :class="[prefixCls + '-title']" v-if="showSlotHeader" v-el:title><slot name="header"></slot></div> | 4 | <div :class="[prefixCls + '-title']" v-if="showSlotHeader" v-el:title><slot name="header"></slot></div> |
| 4 | <div :class="[prefixCls + '-header']" v-if="showHeader" v-el:header @mousewheel="handleMouseWheel"> | 5 | <div :class="[prefixCls + '-header']" v-if="showHeader" v-el:header @mousewheel="handleMouseWheel"> |
| @@ -14,6 +15,8 @@ | @@ -14,6 +15,8 @@ | ||
| 14 | :prefix-cls="prefixCls" | 15 | :prefix-cls="prefixCls" |
| 15 | :style="tableStyle" | 16 | :style="tableStyle" |
| 16 | :columns="cloneColumns" | 17 | :columns="cloneColumns" |
| 18 | + :data="rebuildData" | ||
| 19 | + :obj-data="objData" | ||
| 17 | :clone-data="cloneData"></table-body> | 20 | :clone-data="cloneData"></table-body> |
| 18 | </div> | 21 | </div> |
| 19 | <div :class="[prefixCls + '-fixed']"> | 22 | <div :class="[prefixCls + '-fixed']"> |
| @@ -31,6 +34,8 @@ | @@ -31,6 +34,8 @@ | ||
| 31 | :prefix-cls="prefixCls" | 34 | :prefix-cls="prefixCls" |
| 32 | :style="fixedTableStyle" | 35 | :style="fixedTableStyle" |
| 33 | :columns="leftFixedColumns" | 36 | :columns="leftFixedColumns" |
| 37 | + :data="rebuildData" | ||
| 38 | + :obj-data="objData" | ||
| 34 | :clone-data="cloneData"></table-body> | 39 | :clone-data="cloneData"></table-body> |
| 35 | </div> | 40 | </div> |
| 36 | </div> | 41 | </div> |
| @@ -49,6 +54,8 @@ | @@ -49,6 +54,8 @@ | ||
| 49 | :prefix-cls="prefixCls" | 54 | :prefix-cls="prefixCls" |
| 50 | :style="fixedRightTableStyle" | 55 | :style="fixedRightTableStyle" |
| 51 | :columns="rightFixedColumns" | 56 | :columns="rightFixedColumns" |
| 57 | + :data="rebuildData" | ||
| 58 | + :obj-data="objData" | ||
| 52 | :clone-data="cloneData"></table-body> | 59 | :clone-data="cloneData"></table-body> |
| 53 | </div> | 60 | </div> |
| 54 | </div> | 61 | </div> |
| @@ -116,7 +123,8 @@ | @@ -116,7 +123,8 @@ | ||
| 116 | columnsWidth: [], | 123 | columnsWidth: [], |
| 117 | prefixCls: prefixCls, | 124 | prefixCls: prefixCls, |
| 118 | compiledUids: [], | 125 | compiledUids: [], |
| 119 | - cloneData: deepCopy(this.data), | 126 | + cloneData: this.makeData(), |
| 127 | + rebuildData: this.makeData(), // for sort or filter | ||
| 120 | cloneColumns: deepCopy(this.columns), | 128 | cloneColumns: deepCopy(this.columns), |
| 121 | leftFixedColumns: [], | 129 | leftFixedColumns: [], |
| 122 | rightFixedColumns: [], | 130 | rightFixedColumns: [], |
| @@ -170,6 +178,13 @@ | @@ -170,6 +178,13 @@ | ||
| 170 | let style = {}; | 178 | let style = {}; |
| 171 | if (this.bodyHeight !== 0) style.height = `${this.bodyHeight - 1}px`; | 179 | if (this.bodyHeight !== 0) style.height = `${this.bodyHeight - 1}px`; |
| 172 | return style; | 180 | return style; |
| 181 | + }, | ||
| 182 | + objData () { | ||
| 183 | + let objData = {}; | ||
| 184 | + this.cloneData.forEach((data) => { | ||
| 185 | + objData[data._index] = data; | ||
| 186 | + }); | ||
| 187 | + return objData; | ||
| 173 | } | 188 | } |
| 174 | }, | 189 | }, |
| 175 | methods: { | 190 | methods: { |
| @@ -235,19 +250,27 @@ | @@ -235,19 +250,27 @@ | ||
| 235 | }); | 250 | }); |
| 236 | this.cloneData.$set(index, row); | 251 | this.cloneData.$set(index, row); |
| 237 | 252 | ||
| 238 | - const oldData = oldIndex < 0 ? null : JSON.parse(JSON.stringify(this.data[oldIndex])); | ||
| 239 | - this.$emit('on-current-change', JSON.parse(JSON.stringify(this.data[index])), oldData); | 253 | + const oldData = oldIndex < 0 ? null : JSON.parse(JSON.stringify(this.data[this.rebuildData[oldIndex]._index])); |
| 254 | + this.$emit('on-current-change', JSON.parse(JSON.stringify(this.data[this.rebuildData[index]._index])), oldData); | ||
| 240 | }, | 255 | }, |
| 241 | getSelection () { | 256 | getSelection () { |
| 242 | let selectionIndexes = []; | 257 | let selectionIndexes = []; |
| 243 | - this.cloneData.forEach((data, index) => { | ||
| 244 | - if (data._isChecked) selectionIndexes.push(index); | 258 | + this.cloneData.forEach((data) => { |
| 259 | + if (data._isChecked) selectionIndexes.push(data._index); | ||
| 245 | }); | 260 | }); |
| 246 | - | ||
| 247 | return JSON.parse(JSON.stringify(this.data.filter((data, index) => selectionIndexes.indexOf(index) > -1))); | 261 | return JSON.parse(JSON.stringify(this.data.filter((data, index) => selectionIndexes.indexOf(index) > -1))); |
| 248 | }, | 262 | }, |
| 249 | - toggleSelect (index) { | ||
| 250 | - const status = !this.cloneData[index]._isChecked; | 263 | + toggleSelect (_index) { // _index |
| 264 | + let data = {}; | ||
| 265 | + let index = -1; | ||
| 266 | + for (let i = 0; i < this.cloneData.length; i++) { | ||
| 267 | + if (this.cloneData[i]._index === _index) { | ||
| 268 | + data = this.cloneData[i]; | ||
| 269 | + index = i; | ||
| 270 | + break; | ||
| 271 | + } | ||
| 272 | + } | ||
| 273 | + const status = !data._isChecked; | ||
| 251 | const row = this.assignRow(index, { | 274 | const row = this.assignRow(index, { |
| 252 | _isChecked: status | 275 | _isChecked: status |
| 253 | }); | 276 | }); |
| @@ -255,7 +278,7 @@ | @@ -255,7 +278,7 @@ | ||
| 255 | 278 | ||
| 256 | const selection = this.getSelection(); | 279 | const selection = this.getSelection(); |
| 257 | if (status) { | 280 | if (status) { |
| 258 | - this.$emit('on-select', selection, JSON.parse(JSON.stringify(this.data[index]))); | 281 | + this.$emit('on-select', selection, JSON.parse(JSON.stringify(this.data[_index]))); |
| 259 | } | 282 | } |
| 260 | this.$emit('on-selection-change', selection); | 283 | this.$emit('on-selection-change', selection); |
| 261 | }, | 284 | }, |
| @@ -317,10 +340,19 @@ | @@ -317,10 +340,19 @@ | ||
| 317 | }, | 340 | }, |
| 318 | handleSort (index, type) { | 341 | handleSort (index, type) { |
| 319 | if (type === 'asc') { | 342 | if (type === 'asc') { |
| 320 | - | 343 | + this.rebuildData.sort((a, b) => { |
| 344 | + return a.age > b.age; | ||
| 345 | + }) | ||
| 321 | } else if (type === 'desc') { | 346 | } else if (type === 'desc') { |
| 322 | 347 | ||
| 348 | + } else if (type === 'normal') { | ||
| 349 | + this.rebuildData = this.makeData(); | ||
| 323 | } | 350 | } |
| 351 | + }, | ||
| 352 | + makeData () { | ||
| 353 | + let data = deepCopy(this.data); | ||
| 354 | + data.forEach((row, index) => row._index = index); | ||
| 355 | + return data; | ||
| 324 | } | 356 | } |
| 325 | }, | 357 | }, |
| 326 | compiled () { | 358 | compiled () { |
| @@ -339,7 +371,8 @@ | @@ -339,7 +371,8 @@ | ||
| 339 | watch: { | 371 | watch: { |
| 340 | data: { | 372 | data: { |
| 341 | handler () { | 373 | handler () { |
| 342 | - this.cloneData = deepCopy(this.data); | 374 | + this.cloneData = this.makeData(); |
| 375 | + this.rebuildData = this.makeData(); | ||
| 343 | this.handleResize(); | 376 | this.handleResize(); |
| 344 | }, | 377 | }, |
| 345 | deep: true | 378 | deep: true |
src/styles/mixins/caret.less
test/routers/table.vue
| @@ -8,8 +8,7 @@ | @@ -8,8 +8,7 @@ | ||
| 8 | <!--<i-table size="large" border stripe :columns="columns" :data="data"></i-table>--> | 8 | <!--<i-table size="large" border stripe :columns="columns" :data="data"></i-table>--> |
| 9 | <br> | 9 | <br> |
| 10 | <i-table | 10 | <i-table |
| 11 | - width="450" | ||
| 12 | - :height="height" | 11 | + width="550" |
| 13 | stripe | 12 | stripe |
| 14 | border | 13 | border |
| 15 | highlight-row | 14 | highlight-row |
| @@ -38,7 +37,7 @@ | @@ -38,7 +37,7 @@ | ||
| 38 | columns: [ | 37 | columns: [ |
| 39 | { | 38 | { |
| 40 | type: 'selection', | 39 | type: 'selection', |
| 41 | - width: 50 | 40 | + width: 150 |
| 42 | }, | 41 | }, |
| 43 | { | 42 | { |
| 44 | type: 'index', | 43 | type: 'index', |
| @@ -96,7 +95,7 @@ | @@ -96,7 +95,7 @@ | ||
| 96 | }, | 95 | }, |
| 97 | { | 96 | { |
| 98 | name: '段模', | 97 | name: '段模', |
| 99 | - age: 26, | 98 | + age: 21, |
| 100 | address: '北京市海淀区', | 99 | address: '北京市海淀区', |
| 101 | edit: false | 100 | edit: false |
| 102 | }, | 101 | }, |
| @@ -108,7 +107,7 @@ | @@ -108,7 +107,7 @@ | ||
| 108 | }, | 107 | }, |
| 109 | { | 108 | { |
| 110 | name: '胡国伟', | 109 | name: '胡国伟', |
| 111 | - age: 28, | 110 | + age: 22, |
| 112 | address: '北京市西城区', | 111 | address: '北京市西城区', |
| 113 | edit: false | 112 | edit: false |
| 114 | } | 113 | } |
| @@ -128,15 +127,15 @@ | @@ -128,15 +127,15 @@ | ||
| 128 | this.$Message.info(this.data[index].name); | 127 | this.$Message.info(this.data[index].name); |
| 129 | }, | 128 | }, |
| 130 | current (newData, oldData) { | 129 | current (newData, oldData) { |
| 131 | - console.log(newData); | ||
| 132 | - console.log(oldData); | 130 | +// console.log(newData); |
| 131 | +// console.log(oldData); | ||
| 133 | }, | 132 | }, |
| 134 | select (a,b){ | 133 | select (a,b){ |
| 135 | - console.log(a); | ||
| 136 | - console.log(b); | 134 | + console.log(JSON.stringify(b)); |
| 135 | +// console.log(b); | ||
| 137 | }, | 136 | }, |
| 138 | schange (a) { | 137 | schange (a) { |
| 139 | - console.log(a) | 138 | +// console.log(a) |
| 140 | }, | 139 | }, |
| 141 | sall (a) { | 140 | sall (a) { |
| 142 | console.log(a) | 141 | console.log(a) |
| @@ -161,7 +160,7 @@ | @@ -161,7 +160,7 @@ | ||
| 161 | // address: '北京市东城区2', | 160 | // address: '北京市东城区2', |
| 162 | // edit: false | 161 | // edit: false |
| 163 | // }); | 162 | // }); |
| 164 | -// this.data.splice(1, 1) | 163 | +// this.data.splice(0, 1) |
| 165 | // this.columns.splice(2,1) | 164 | // this.columns.splice(2,1) |
| 166 | }, 2000); | 165 | }, 2000); |
| 167 | } | 166 | } |