Commit adaeca88ba2f6f39a43336901b6ec74e65741221
1 parent
7f1edb6a
update Table
update Table
Showing
4 changed files
with
65 additions
and
16 deletions
Show diff stats
src/components/table/table-head.vue
... | ... | @@ -14,25 +14,31 @@ |
14 | 14 | <i class="ivu-icon ivu-icon-arrow-up-b" :class="{on: column._sortType === 'asc'}" @click="handleSort($index, 'asc')"></i> |
15 | 15 | <i class="ivu-icon ivu-icon-arrow-down-b" :class="{on: column._sortType === 'desc'}" @click="handleSort($index, 'desc')"></i> |
16 | 16 | </span> |
17 | - <Poptip v-if="column.filters" :visible.sync="column._filterVisible" placement="bottom"> | |
17 | + <Poptip | |
18 | + v-if="column.filters && (fixed || (!fixed && !column.fixed))" | |
19 | + :visible.sync="column._filterVisible" | |
20 | + placement="bottom" | |
21 | + @on-popper-hide="handleFilterHide($index)"> | |
18 | 22 | <span :class="[prefixCls + '-filter']"> |
19 | 23 | <i class="ivu-icon ivu-icon-funnel" :class="{on: column._isFiltered}"></i> |
20 | 24 | </span> |
21 | - <div slot="content" :class="[prefixCls + '-filter-list']"> | |
25 | + <div slot="content" :class="[prefixCls + '-filter-list']" v-if="column._filterMultiple"> | |
22 | 26 | <div :class="[prefixCls + '-filter-list-item']"> |
23 | 27 | <checkbox-group :model.sync="column._filterChecked"> |
24 | 28 | <checkbox v-for="item in column.filters" :value="item.value">{{ item.label }}</checkbox> |
25 | 29 | </checkbox-group> |
26 | 30 | </div> |
27 | - <ul> | |
28 | - <!--<li v-for="(filterIndex, item) in column.filters"><Checkbox :checked="column._filterChecked.indexOf(item.value) > -1" @on-change="handleFilterChecked(index, filterIndex)">{{ item.label }}</Checkbox></li>--> | |
29 | - | |
30 | - </ul> | |
31 | 31 | <div :class="[prefixCls + '-filter-footer']"> |
32 | - <i-button type="text" size="small" @click="handleFilter($index)">筛选</i-button> | |
32 | + <i-button type="text" size="small" :disabled="!column._filterChecked.length" @click="handleFilter($index)">筛选</i-button> | |
33 | 33 | <i-button type="text" size="small" @click="handleReset($index)">重置</i-button> |
34 | 34 | </div> |
35 | 35 | </div> |
36 | + <div slot="content" :class="[prefixCls + '-filter-list']" v-else> | |
37 | + <ul> | |
38 | + <li :class="[prefixCls + '-filter-select-item', {[prefixCls + '-filter-select-item-selected']: !column._filterChecked.lengtg}]">全部</li> | |
39 | + <li :class="[prefixCls + '-filter-select-item', {[prefixCls + '-filter-select-item-selected']: column._filterChecked[0] === item.value}]" v-for="item in column.filters">{{ item.label }}</li> | |
40 | + </ul> | |
41 | + </div> | |
36 | 42 | </Poptip> |
37 | 43 | </template> |
38 | 44 | </div> |
... | ... | @@ -99,13 +105,13 @@ |
99 | 105 | this.$parent.handleSort(index, type); |
100 | 106 | }, |
101 | 107 | handleFilter (index) { |
102 | - | |
108 | + this.$parent.handleFilter(index); | |
103 | 109 | }, |
104 | 110 | handleReset (index) { |
105 | - | |
111 | + this.$parent.handleFilterReset(index); | |
106 | 112 | }, |
107 | - handleFilterChecked (index, filterIndex) { | |
108 | - | |
113 | + handleFilterHide (index) { | |
114 | + this.$parent.handleFilterHide(index); | |
109 | 115 | } |
110 | 116 | } |
111 | 117 | } | ... | ... |
src/components/table/table.vue
... | ... | @@ -115,6 +115,7 @@ |
115 | 115 | }, |
116 | 116 | data () { |
117 | 117 | return { |
118 | + ready: false, | |
118 | 119 | tableWidth: 0, |
119 | 120 | columnsWidth: [], |
120 | 121 | prefixCls: prefixCls, |
... | ... | @@ -132,6 +133,7 @@ |
132 | 133 | return [ |
133 | 134 | `${prefixCls}`, |
134 | 135 | { |
136 | + [`${prefixCls}-hide`]: !this.ready, | |
135 | 137 | [`${prefixCls}-${this.size}`]: !!this.size, |
136 | 138 | [`${prefixCls}-border`]: this.border, |
137 | 139 | [`${prefixCls}-stripe`]: this.stripe, |
... | ... | @@ -344,6 +346,27 @@ |
344 | 346 | order: type |
345 | 347 | }) |
346 | 348 | }, |
349 | + handleFilterHide (index) { // clear checked that not filter now | |
350 | + if (!this.cloneColumns[index]._isFiltered) this.cloneColumns[index]._filterChecked = []; | |
351 | + }, | |
352 | + handleFilter (index) { | |
353 | + const column = this.cloneColumns[index]; | |
354 | + const filterData = this.makeData(); | |
355 | + | |
356 | + this.rebuildData = filterData.filter((row) => { | |
357 | + let status = false; | |
358 | + for (let i = 0; i < column._filterChecked.length; i++) { | |
359 | + status = column.filterMethod(column._filterChecked[i], row); | |
360 | + if (status) break; | |
361 | + } | |
362 | + return status; | |
363 | + }); | |
364 | + this.cloneColumns[index]._isFiltered = true; | |
365 | + this.cloneColumns[index]._filterVisible = false; | |
366 | + }, | |
367 | + handleFilterReset (index) { | |
368 | + this.cloneColumns[index]._isFiltered = false; | |
369 | + }, | |
347 | 370 | makeData () { |
348 | 371 | let data = deepCopy(this.data); |
349 | 372 | data.forEach((row, index) => row._index = index); |
... | ... | @@ -373,6 +396,12 @@ |
373 | 396 | column._isFiltered = false; |
374 | 397 | column._filterChecked = []; |
375 | 398 | |
399 | + if ('filterMultiple' in column) { | |
400 | + column._filterMultiple = column.filterMultiple; | |
401 | + } else { | |
402 | + column._filterMultiple = true; | |
403 | + } | |
404 | + | |
376 | 405 | if (column.fixed && column.fixed === 'left') { |
377 | 406 | left.push(column); |
378 | 407 | } else if (column.fixed && column.fixed === 'right') { |
... | ... | @@ -391,6 +420,7 @@ |
391 | 420 | ready () { |
392 | 421 | this.handleResize(); |
393 | 422 | this.fixedHeader(); |
423 | + this.$nextTick(() => this.ready = true); | |
394 | 424 | window.addEventListener('resize', this.handleResize, false); |
395 | 425 | }, |
396 | 426 | beforeDestroy () { | ... | ... |
src/styles/components/table.less
1 | 1 | @table-prefix-cls: ~"@{css-prefix}table"; |
2 | +@table-select-item-prefix-cls: ~"@{table-prefix-cls}-filter-select-item"; | |
2 | 3 | |
3 | 4 | .@{table-prefix-cls} { |
4 | 5 | width: 100%; |
... | ... | @@ -13,6 +14,10 @@ |
13 | 14 | box-sizing: border-box; |
14 | 15 | position: relative; |
15 | 16 | |
17 | + &-hide{ | |
18 | + opacity: 0; | |
19 | + } | |
20 | + | |
16 | 21 | &:before{ |
17 | 22 | content: ''; |
18 | 23 | width: 100%; |
... | ... | @@ -262,6 +267,10 @@ |
262 | 267 | } |
263 | 268 | } |
264 | 269 | } |
270 | + ul{ | |
271 | + padding-bottom: 8px; | |
272 | + } | |
273 | + .select-item(@table-prefix-cls, @table-select-item-prefix-cls); | |
265 | 274 | } |
266 | 275 | &-footer{ |
267 | 276 | padding: 4px; | ... | ... |
test/routers/table.vue
... | ... | @@ -63,6 +63,7 @@ |
63 | 63 | value: 'company' |
64 | 64 | } |
65 | 65 | ], |
66 | + filterMultiple: false | |
66 | 67 | }, |
67 | 68 | { |
68 | 69 | title: '标签', |
... | ... | @@ -78,8 +79,11 @@ |
78 | 79 | value: 'company' |
79 | 80 | } |
80 | 81 | ], |
82 | + filterMethod (value, row) { | |
83 | + return row.tag === value; | |
84 | + }, | |
81 | 85 | render (row) { |
82 | - const type = `${row.tag}` === '家' ? 'green' : 'red'; | |
86 | + const type = `${row.tag}` === 'home' ? 'green' : 'red'; | |
83 | 87 | return `<tag color="${type}">${row.tag}</tag>`; |
84 | 88 | } |
85 | 89 | }, |
... | ... | @@ -135,28 +139,28 @@ |
135 | 139 | age: 25, |
136 | 140 | address: '北京市朝阳区', |
137 | 141 | edit: false, |
138 | - tag: '家' | |
142 | + tag: 'home' | |
139 | 143 | }, |
140 | 144 | { |
141 | 145 | name: '段模', |
142 | 146 | age: 21, |
143 | 147 | address: '北京市海淀区', |
144 | 148 | edit: false, |
145 | - tag: '公司' | |
149 | + tag: 'company' | |
146 | 150 | }, |
147 | 151 | { |
148 | 152 | name: '刘天娇', |
149 | 153 | age: 27, |
150 | 154 | address: '北京市东城区', |
151 | 155 | edit: false, |
152 | - tag: '公司' | |
156 | + tag: 'company' | |
153 | 157 | }, |
154 | 158 | { |
155 | 159 | name: '胡国伟', |
156 | 160 | age: 22, |
157 | 161 | address: '北京市西城区', |
158 | 162 | edit: false, |
159 | - tag: '家' | |
163 | + tag: 'home' | |
160 | 164 | } |
161 | 165 | ], |
162 | 166 | height: 200 | ... | ... |