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 | 1 | <template> |
| 2 | 2 | <div :class="classes"> |
| 3 | - <template v-if="renderType === 'index'">{{index + 1}}</template> | |
| 3 | + <template v-if="renderType === 'index'">{{naturalIndex + 1}}</template> | |
| 4 | 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 | 6 | </template> |
| 7 | 7 | <template v-if="renderType === 'normal'">{{{ row[column.key] }}}</template> |
| 8 | 8 | </div> |
| ... | ... | @@ -16,7 +16,8 @@ |
| 16 | 16 | prefixCls: String, |
| 17 | 17 | row: Object, |
| 18 | 18 | column: Object, |
| 19 | - index: Number, | |
| 19 | + naturalIndex: Number, // index of rebuildData | |
| 20 | + index: Number, // _index of data | |
| 20 | 21 | checked: Boolean, |
| 21 | 22 | fixed: Boolean |
| 22 | 23 | }, |
| ... | ... | @@ -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 | 70 | compiled () { |
| ... | ... | @@ -84,7 +85,7 @@ |
| 84 | 85 | this.destroy(); |
| 85 | 86 | }, |
| 86 | 87 | watch: { |
| 87 | - index () { | |
| 88 | + naturalIndex () { | |
| 88 | 89 | this.destroy(); |
| 89 | 90 | this.compile(); |
| 90 | 91 | } | ... | ... |
src/components/table/table-body.vue
| ... | ... | @@ -5,8 +5,8 @@ |
| 5 | 5 | </colgroup> |
| 6 | 6 | <tbody :class="[prefixCls + '-tbody']"> |
| 7 | 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 | 10 | @mouseenter.stop="handleMouseIn(index)" |
| 11 | 11 | @mouseleave.stop="handleMouseOut(index)" |
| 12 | 12 | @click.stop="highlightCurrentRow(index)"> |
| ... | ... | @@ -16,8 +16,9 @@ |
| 16 | 16 | :prefix-cls="prefixCls" |
| 17 | 17 | :row="row" |
| 18 | 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 | 22 | </td> |
| 22 | 23 | </tr> |
| 23 | 24 | </tbody> |
| ... | ... | @@ -34,20 +35,27 @@ |
| 34 | 35 | prefixCls: String, |
| 35 | 36 | style: Object, |
| 36 | 37 | columns: Array, |
| 38 | + data: Array, // rebuildData | |
| 37 | 39 | cloneData: Array, |
| 40 | + objData: Object, | |
| 38 | 41 | fixed: Boolean |
| 39 | 42 | }, |
| 40 | 43 | methods: { |
| 41 | - rowClasses (row, index) { | |
| 44 | + rowClasses (index, _index) { | |
| 42 | 45 | return [ |
| 43 | 46 | `${this.prefixCls}-row`, |
| 44 | - this.rowClsName(index), | |
| 47 | + this.rowClsName(_index), | |
| 45 | 48 | { |
| 46 | 49 | [`${this.prefixCls}-row-highlight`]: this.cloneData[index] && this.cloneData[index]._isHighlight, |
| 47 | 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 | 59 | setCellWidth (column, index) { |
| 52 | 60 | return this.$parent.setCellWidth(column, index); |
| 53 | 61 | }, | ... | ... |
src/components/table/table-head.vue
| ... | ... | @@ -11,8 +11,8 @@ |
| 11 | 11 | <template v-else> |
| 12 | 12 | {{{ renderHeader(column, $index) }}} |
| 13 | 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 | 16 | </span> |
| 17 | 17 | </template> |
| 18 | 18 | </div> |
| ... | ... | @@ -36,6 +36,11 @@ |
| 36 | 36 | cloneData: Array, |
| 37 | 37 | fixed: Boolean |
| 38 | 38 | }, |
| 39 | + data () { | |
| 40 | + return { | |
| 41 | + sortType: 'normal' | |
| 42 | + } | |
| 43 | + }, | |
| 39 | 44 | computed: { |
| 40 | 45 | isSelectAll () { |
| 41 | 46 | return !this.cloneData.some(data => !data._isChecked); |
| ... | ... | @@ -65,10 +70,22 @@ |
| 65 | 70 | this.$parent.selectAll(status); |
| 66 | 71 | }, |
| 67 | 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 | 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 | 1 | <template> |
| 2 | + {{cloneData|json}} | |
| 2 | 3 | <div :class="classes" :style="styles"> |
| 3 | 4 | <div :class="[prefixCls + '-title']" v-if="showSlotHeader" v-el:title><slot name="header"></slot></div> |
| 4 | 5 | <div :class="[prefixCls + '-header']" v-if="showHeader" v-el:header @mousewheel="handleMouseWheel"> |
| ... | ... | @@ -14,6 +15,8 @@ |
| 14 | 15 | :prefix-cls="prefixCls" |
| 15 | 16 | :style="tableStyle" |
| 16 | 17 | :columns="cloneColumns" |
| 18 | + :data="rebuildData" | |
| 19 | + :obj-data="objData" | |
| 17 | 20 | :clone-data="cloneData"></table-body> |
| 18 | 21 | </div> |
| 19 | 22 | <div :class="[prefixCls + '-fixed']"> |
| ... | ... | @@ -31,6 +34,8 @@ |
| 31 | 34 | :prefix-cls="prefixCls" |
| 32 | 35 | :style="fixedTableStyle" |
| 33 | 36 | :columns="leftFixedColumns" |
| 37 | + :data="rebuildData" | |
| 38 | + :obj-data="objData" | |
| 34 | 39 | :clone-data="cloneData"></table-body> |
| 35 | 40 | </div> |
| 36 | 41 | </div> |
| ... | ... | @@ -49,6 +54,8 @@ |
| 49 | 54 | :prefix-cls="prefixCls" |
| 50 | 55 | :style="fixedRightTableStyle" |
| 51 | 56 | :columns="rightFixedColumns" |
| 57 | + :data="rebuildData" | |
| 58 | + :obj-data="objData" | |
| 52 | 59 | :clone-data="cloneData"></table-body> |
| 53 | 60 | </div> |
| 54 | 61 | </div> |
| ... | ... | @@ -116,7 +123,8 @@ |
| 116 | 123 | columnsWidth: [], |
| 117 | 124 | prefixCls: prefixCls, |
| 118 | 125 | compiledUids: [], |
| 119 | - cloneData: deepCopy(this.data), | |
| 126 | + cloneData: this.makeData(), | |
| 127 | + rebuildData: this.makeData(), // for sort or filter | |
| 120 | 128 | cloneColumns: deepCopy(this.columns), |
| 121 | 129 | leftFixedColumns: [], |
| 122 | 130 | rightFixedColumns: [], |
| ... | ... | @@ -170,6 +178,13 @@ |
| 170 | 178 | let style = {}; |
| 171 | 179 | if (this.bodyHeight !== 0) style.height = `${this.bodyHeight - 1}px`; |
| 172 | 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 | 190 | methods: { |
| ... | ... | @@ -235,19 +250,27 @@ |
| 235 | 250 | }); |
| 236 | 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 | 256 | getSelection () { |
| 242 | 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 | 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 | 274 | const row = this.assignRow(index, { |
| 252 | 275 | _isChecked: status |
| 253 | 276 | }); |
| ... | ... | @@ -255,7 +278,7 @@ |
| 255 | 278 | |
| 256 | 279 | const selection = this.getSelection(); |
| 257 | 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 | 283 | this.$emit('on-selection-change', selection); |
| 261 | 284 | }, |
| ... | ... | @@ -317,10 +340,19 @@ |
| 317 | 340 | }, |
| 318 | 341 | handleSort (index, type) { |
| 319 | 342 | if (type === 'asc') { |
| 320 | - | |
| 343 | + this.rebuildData.sort((a, b) => { | |
| 344 | + return a.age > b.age; | |
| 345 | + }) | |
| 321 | 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 | 358 | compiled () { |
| ... | ... | @@ -339,7 +371,8 @@ |
| 339 | 371 | watch: { |
| 340 | 372 | data: { |
| 341 | 373 | handler () { |
| 342 | - this.cloneData = deepCopy(this.data); | |
| 374 | + this.cloneData = this.makeData(); | |
| 375 | + this.rebuildData = this.makeData(); | |
| 343 | 376 | this.handleResize(); |
| 344 | 377 | }, |
| 345 | 378 | deep: true | ... | ... |
src/styles/mixins/caret.less
test/routers/table.vue
| ... | ... | @@ -8,8 +8,7 @@ |
| 8 | 8 | <!--<i-table size="large" border stripe :columns="columns" :data="data"></i-table>--> |
| 9 | 9 | <br> |
| 10 | 10 | <i-table |
| 11 | - width="450" | |
| 12 | - :height="height" | |
| 11 | + width="550" | |
| 13 | 12 | stripe |
| 14 | 13 | border |
| 15 | 14 | highlight-row |
| ... | ... | @@ -38,7 +37,7 @@ |
| 38 | 37 | columns: [ |
| 39 | 38 | { |
| 40 | 39 | type: 'selection', |
| 41 | - width: 50 | |
| 40 | + width: 150 | |
| 42 | 41 | }, |
| 43 | 42 | { |
| 44 | 43 | type: 'index', |
| ... | ... | @@ -96,7 +95,7 @@ |
| 96 | 95 | }, |
| 97 | 96 | { |
| 98 | 97 | name: '段模', |
| 99 | - age: 26, | |
| 98 | + age: 21, | |
| 100 | 99 | address: '北京市海淀区', |
| 101 | 100 | edit: false |
| 102 | 101 | }, |
| ... | ... | @@ -108,7 +107,7 @@ |
| 108 | 107 | }, |
| 109 | 108 | { |
| 110 | 109 | name: '胡国伟', |
| 111 | - age: 28, | |
| 110 | + age: 22, | |
| 112 | 111 | address: '北京市西城区', |
| 113 | 112 | edit: false |
| 114 | 113 | } |
| ... | ... | @@ -128,15 +127,15 @@ |
| 128 | 127 | this.$Message.info(this.data[index].name); |
| 129 | 128 | }, |
| 130 | 129 | current (newData, oldData) { |
| 131 | - console.log(newData); | |
| 132 | - console.log(oldData); | |
| 130 | +// console.log(newData); | |
| 131 | +// console.log(oldData); | |
| 133 | 132 | }, |
| 134 | 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 | 137 | schange (a) { |
| 139 | - console.log(a) | |
| 138 | +// console.log(a) | |
| 140 | 139 | }, |
| 141 | 140 | sall (a) { |
| 142 | 141 | console.log(a) |
| ... | ... | @@ -161,7 +160,7 @@ |
| 161 | 160 | // address: '北京市东城区2', |
| 162 | 161 | // edit: false |
| 163 | 162 | // }); |
| 164 | -// this.data.splice(1, 1) | |
| 163 | +// this.data.splice(0, 1) | |
| 165 | 164 | // this.columns.splice(2,1) |
| 166 | 165 | }, 2000); |
| 167 | 166 | } | ... | ... |