Commit abdec99d22ed47f208e22faac9125ef1f5258e96
1 parent
e7e8c8ff
update Table
update Table
Showing
3 changed files
with
59 additions
and
15 deletions
Show diff stats
src/components/table/table.vue
| ... | ... | @@ -4,26 +4,28 @@ |
| 4 | 4 | <div :class="[prefixCls + '-header']" v-if="showHeader" v-el:header> |
| 5 | 5 | <table cellspacing="0" cellpadding="0" border="0" :style="tableStyle"> |
| 6 | 6 | <colgroup> |
| 7 | - <col v-for="column in columns" :width="setCellWidth(column, $index)"> | |
| 7 | + <col v-for="column in cloneColumns" :width="setCellWidth(column, $index)"> | |
| 8 | 8 | </colgroup> |
| 9 | 9 | <thead |
| 10 | 10 | is="table-head" |
| 11 | 11 | :prefix-cls="prefixCls" |
| 12 | 12 | :clone-data.sync="cloneData" |
| 13 | - :columns="columns"></thead> | |
| 13 | + :columns="cloneColumns"></thead> | |
| 14 | 14 | </table> |
| 15 | 15 | </div> |
| 16 | 16 | <div :class="[prefixCls + '-body']" :style="bodyStyle"> |
| 17 | 17 | <table cellspacing="0" cellpadding="0" border="0" :style="tableStyle" v-el:tbody> |
| 18 | 18 | <colgroup> |
| 19 | - <col v-for="column in columns" :width="setCellWidth(column, $index)"> | |
| 19 | + <col v-for="column in cloneColumns" :width="setCellWidth(column, $index)"> | |
| 20 | 20 | </colgroup> |
| 21 | 21 | <tbody :class="[prefixCls + '-tbody']" v-el:render> |
| 22 | 22 | <tr |
| 23 | 23 | v-for="(index, row) in data" |
| 24 | - :class="[prefixCls + '-row', rowClsName(index), {[prefixCls + '-row-highlight']: cloneData[index] && cloneData[index]._isHighlight}]" | |
| 24 | + :class="[prefixCls + '-row', rowClsName(index), {[prefixCls + '-row-highlight']: cloneData[index] && cloneData[index]._isHighlight, [prefixCls + '-row-hover']: cloneData[index] && cloneData[index]._isHover}]" | |
| 25 | + @mouseenter.stop="handleMouseIn(index)" | |
| 26 | + @mouseleave.stop="handleMouseOut(index)" | |
| 25 | 27 | @click.stop="highlightCurrentRow(index)"> |
| 26 | - <td v-for="column in columns" :class="alignCls(column)"> | |
| 28 | + <td v-for="column in cloneColumns" :class="alignCls(column)"> | |
| 27 | 29 | <div :class="[prefixCls + '-cell']"> |
| 28 | 30 | <template v-if="column.type === 'selection'"> |
| 29 | 31 | <Checkbox :checked="cloneData[index] && cloneData[index]._isChecked" @on-change="toggleSelect(index)"></Checkbox> |
| ... | ... | @@ -35,6 +37,12 @@ |
| 35 | 37 | </tbody> |
| 36 | 38 | </table> |
| 37 | 39 | </div> |
| 40 | + <div :class="[prefixCls + '-fixed']"> | |
| 41 | + | |
| 42 | + </div> | |
| 43 | + <div :class="[prefixCls + '-fixed-right']"> | |
| 44 | + | |
| 45 | + </div> | |
| 38 | 46 | <div :class="[prefixCls + '-footer']" v-if="showSlotFooter" v-el:footer><slot name="footer"></slot></div> |
| 39 | 47 | </div> |
| 40 | 48 | </template> |
| ... | ... | @@ -99,6 +107,7 @@ |
| 99 | 107 | prefixCls: prefixCls, |
| 100 | 108 | compiledUids: [], |
| 101 | 109 | cloneData: deepCopy(this.data), |
| 110 | + cloneColumns: deepCopy(this.columns), | |
| 102 | 111 | showSlotHeader: true, |
| 103 | 112 | showSlotFooter: true, |
| 104 | 113 | bodyHeight: 0 |
| ... | ... | @@ -155,8 +164,8 @@ |
| 155 | 164 | } |
| 156 | 165 | |
| 157 | 166 | const $el = this.$els.render; |
| 158 | - for (let i = 0; i < this.columns.length; i++) { | |
| 159 | - const column = this.columns[i]; | |
| 167 | + for (let i = 0; i < this.cloneColumns.length; i++) { | |
| 168 | + const column = this.cloneColumns[i]; | |
| 160 | 169 | if (column.render) { |
| 161 | 170 | for (let j = 0; j < this.data.length; j++) { |
| 162 | 171 | // todo 做一个缓存,只在需要改render时再重新编译,data改变时不用再编译 |
| ... | ... | @@ -191,6 +200,22 @@ |
| 191 | 200 | setCellWidth (column, index) { |
| 192 | 201 | return column.width ? column.width : this.columnsWidth[index]; |
| 193 | 202 | }, |
| 203 | + assignRow (index, obj) { | |
| 204 | + return Object.assign({}, this.cloneData[index], obj); | |
| 205 | + }, | |
| 206 | + handleMouseIn (index) { | |
| 207 | + if (this.cloneData[index]._isHover) return; | |
| 208 | + const row = this.assignRow(index, { | |
| 209 | + _isHover: true | |
| 210 | + }); | |
| 211 | + this.cloneData.$set(index, row); | |
| 212 | + }, | |
| 213 | + handleMouseOut (index) { | |
| 214 | + const row = this.assignRow(index, { | |
| 215 | + _isHover: false | |
| 216 | + }); | |
| 217 | + this.cloneData.$set(index, row); | |
| 218 | + }, | |
| 194 | 219 | highlightCurrentRow (index) { |
| 195 | 220 | if (!this.highlightRow || this.cloneData[index]._isHighlight) return; |
| 196 | 221 | |
| ... | ... | @@ -202,7 +227,7 @@ |
| 202 | 227 | return true; |
| 203 | 228 | } |
| 204 | 229 | }); |
| 205 | - const row = Object.assign({}, this.cloneData[index], { | |
| 230 | + const row = this.assignRow(index, { | |
| 206 | 231 | _isHighlight: true |
| 207 | 232 | }); |
| 208 | 233 | this.cloneData.$set(index, row); |
| ... | ... | @@ -220,7 +245,7 @@ |
| 220 | 245 | }, |
| 221 | 246 | toggleSelect (index) { |
| 222 | 247 | const status = !this.cloneData[index]._isChecked; |
| 223 | - const row = Object.assign({}, this.cloneData[index], { | |
| 248 | + const row = this.assignRow(index, { | |
| 224 | 249 | _isChecked: status |
| 225 | 250 | }); |
| 226 | 251 | this.cloneData.$set(index, row); |
| ... | ... | @@ -243,9 +268,25 @@ |
| 243 | 268 | this.bodyHeight = this.height - titleHeight - headerHeight - footerHeight; |
| 244 | 269 | }) |
| 245 | 270 | } |
| 271 | + }, | |
| 272 | + parseColumns () { | |
| 273 | + let left = []; | |
| 274 | + let right = []; | |
| 275 | + let center = []; | |
| 276 | + this.cloneColumns.forEach((col) => { | |
| 277 | + if (col.fixed && col.fixed === 'left') { | |
| 278 | + left.push(col); | |
| 279 | + } else if (col.fixed && col.fixed === 'right') { | |
| 280 | + right.push(col); | |
| 281 | + } else { | |
| 282 | + center.push(col); | |
| 283 | + } | |
| 284 | + }); | |
| 285 | + this.cloneColumns = left.concat(center).concat(right); | |
| 246 | 286 | } |
| 247 | 287 | }, |
| 248 | 288 | compiled () { |
| 289 | + this.parseColumns(); | |
| 249 | 290 | this.showSlotHeader = this.$els.title.innerHTML.replace(/\n/g, '').replace(/<!--[\w\W\r\n]*?-->/gmi, '') !== ''; |
| 250 | 291 | this.showSlotFooter = this.$els.footer.innerHTML.replace(/\n/g, '').replace(/<!--[\w\W\r\n]*?-->/gmi, '') !== ''; |
| 251 | 292 | }, |
| ... | ... | @@ -267,6 +308,7 @@ |
| 267 | 308 | }, |
| 268 | 309 | columns: { |
| 269 | 310 | handler () { |
| 311 | + this.parseColumns(); | |
| 270 | 312 | this.compileRender(true); |
| 271 | 313 | }, |
| 272 | 314 | deep: true | ... | ... |
src/styles/components/table.less
| ... | ... | @@ -122,7 +122,7 @@ |
| 122 | 122 | } |
| 123 | 123 | } |
| 124 | 124 | |
| 125 | - tr:hover{ | |
| 125 | + tr&-row-hover{ | |
| 126 | 126 | td{ |
| 127 | 127 | background-color: @table-td-hover-bg; |
| 128 | 128 | } |
| ... | ... | @@ -156,7 +156,7 @@ |
| 156 | 156 | } |
| 157 | 157 | |
| 158 | 158 | &-row-highlight, |
| 159 | - tr&-row-highlight:hover, | |
| 159 | + tr&-row-highlight&-row-hover, | |
| 160 | 160 | &-stripe &-body tr&-row-highlight:nth-child(2n) |
| 161 | 161 | { |
| 162 | 162 | td{ | ... | ... |
test/routers/table.vue
| ... | ... | @@ -9,7 +9,6 @@ |
| 9 | 9 | <br> |
| 10 | 10 | <i-table |
| 11 | 11 | border |
| 12 | - :height="height" | |
| 13 | 12 | highlight-row |
| 14 | 13 | :columns="columns" |
| 15 | 14 | :data="data" |
| ... | ... | @@ -41,13 +40,15 @@ |
| 41 | 40 | title: '姓名', |
| 42 | 41 | key: 'name', |
| 43 | 42 | align: 'left', |
| 44 | -// width: 100 | |
| 43 | + fixed: 'left', | |
| 44 | + width: 100 | |
| 45 | 45 | }, |
| 46 | 46 | { |
| 47 | 47 | title: '年龄', |
| 48 | 48 | key: 'age', |
| 49 | 49 | align: 'right', |
| 50 | -// width: 100 | |
| 50 | + fixed: 'left', | |
| 51 | + width: 100 | |
| 51 | 52 | // render (row) { |
| 52 | 53 | // return `<i-button>${row.age}</i-button>` |
| 53 | 54 | // } |
| ... | ... | @@ -68,7 +69,8 @@ |
| 68 | 69 | { |
| 69 | 70 | title: '操作', |
| 70 | 71 | key: 'action', |
| 71 | -// width: 200, | |
| 72 | + fixed: 'right', | |
| 73 | + width: 200, | |
| 72 | 74 | render (row, column, index) { |
| 73 | 75 | return `<i-button @click="edit(${index})">编辑</i-button>` |
| 74 | 76 | } | ... | ... |