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 | } | ... | ... |