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,25 +14,31 @@ | ||
| 14 | <i class="ivu-icon ivu-icon-arrow-up-b" :class="{on: column._sortType === 'asc'}" @click="handleSort($index, 'asc')"></i> | 14 | <i class="ivu-icon ivu-icon-arrow-up-b" :class="{on: column._sortType === 'asc'}" @click="handleSort($index, 'asc')"></i> |
| 15 | <i class="ivu-icon ivu-icon-arrow-down-b" :class="{on: column._sortType === 'desc'}" @click="handleSort($index, 'desc')"></i> | 15 | <i class="ivu-icon ivu-icon-arrow-down-b" :class="{on: column._sortType === 'desc'}" @click="handleSort($index, 'desc')"></i> |
| 16 | </span> | 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 | <span :class="[prefixCls + '-filter']"> | 22 | <span :class="[prefixCls + '-filter']"> |
| 19 | <i class="ivu-icon ivu-icon-funnel" :class="{on: column._isFiltered}"></i> | 23 | <i class="ivu-icon ivu-icon-funnel" :class="{on: column._isFiltered}"></i> |
| 20 | </span> | 24 | </span> |
| 21 | - <div slot="content" :class="[prefixCls + '-filter-list']"> | 25 | + <div slot="content" :class="[prefixCls + '-filter-list']" v-if="column._filterMultiple"> |
| 22 | <div :class="[prefixCls + '-filter-list-item']"> | 26 | <div :class="[prefixCls + '-filter-list-item']"> |
| 23 | <checkbox-group :model.sync="column._filterChecked"> | 27 | <checkbox-group :model.sync="column._filterChecked"> |
| 24 | <checkbox v-for="item in column.filters" :value="item.value">{{ item.label }}</checkbox> | 28 | <checkbox v-for="item in column.filters" :value="item.value">{{ item.label }}</checkbox> |
| 25 | </checkbox-group> | 29 | </checkbox-group> |
| 26 | </div> | 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 | <div :class="[prefixCls + '-filter-footer']"> | 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 | <i-button type="text" size="small" @click="handleReset($index)">重置</i-button> | 33 | <i-button type="text" size="small" @click="handleReset($index)">重置</i-button> |
| 34 | </div> | 34 | </div> |
| 35 | </div> | 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 | </Poptip> | 42 | </Poptip> |
| 37 | </template> | 43 | </template> |
| 38 | </div> | 44 | </div> |
| @@ -99,13 +105,13 @@ | @@ -99,13 +105,13 @@ | ||
| 99 | this.$parent.handleSort(index, type); | 105 | this.$parent.handleSort(index, type); |
| 100 | }, | 106 | }, |
| 101 | handleFilter (index) { | 107 | handleFilter (index) { |
| 102 | - | 108 | + this.$parent.handleFilter(index); |
| 103 | }, | 109 | }, |
| 104 | handleReset (index) { | 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,6 +115,7 @@ | ||
| 115 | }, | 115 | }, |
| 116 | data () { | 116 | data () { |
| 117 | return { | 117 | return { |
| 118 | + ready: false, | ||
| 118 | tableWidth: 0, | 119 | tableWidth: 0, |
| 119 | columnsWidth: [], | 120 | columnsWidth: [], |
| 120 | prefixCls: prefixCls, | 121 | prefixCls: prefixCls, |
| @@ -132,6 +133,7 @@ | @@ -132,6 +133,7 @@ | ||
| 132 | return [ | 133 | return [ |
| 133 | `${prefixCls}`, | 134 | `${prefixCls}`, |
| 134 | { | 135 | { |
| 136 | + [`${prefixCls}-hide`]: !this.ready, | ||
| 135 | [`${prefixCls}-${this.size}`]: !!this.size, | 137 | [`${prefixCls}-${this.size}`]: !!this.size, |
| 136 | [`${prefixCls}-border`]: this.border, | 138 | [`${prefixCls}-border`]: this.border, |
| 137 | [`${prefixCls}-stripe`]: this.stripe, | 139 | [`${prefixCls}-stripe`]: this.stripe, |
| @@ -344,6 +346,27 @@ | @@ -344,6 +346,27 @@ | ||
| 344 | order: type | 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 | makeData () { | 370 | makeData () { |
| 348 | let data = deepCopy(this.data); | 371 | let data = deepCopy(this.data); |
| 349 | data.forEach((row, index) => row._index = index); | 372 | data.forEach((row, index) => row._index = index); |
| @@ -373,6 +396,12 @@ | @@ -373,6 +396,12 @@ | ||
| 373 | column._isFiltered = false; | 396 | column._isFiltered = false; |
| 374 | column._filterChecked = []; | 397 | column._filterChecked = []; |
| 375 | 398 | ||
| 399 | + if ('filterMultiple' in column) { | ||
| 400 | + column._filterMultiple = column.filterMultiple; | ||
| 401 | + } else { | ||
| 402 | + column._filterMultiple = true; | ||
| 403 | + } | ||
| 404 | + | ||
| 376 | if (column.fixed && column.fixed === 'left') { | 405 | if (column.fixed && column.fixed === 'left') { |
| 377 | left.push(column); | 406 | left.push(column); |
| 378 | } else if (column.fixed && column.fixed === 'right') { | 407 | } else if (column.fixed && column.fixed === 'right') { |
| @@ -391,6 +420,7 @@ | @@ -391,6 +420,7 @@ | ||
| 391 | ready () { | 420 | ready () { |
| 392 | this.handleResize(); | 421 | this.handleResize(); |
| 393 | this.fixedHeader(); | 422 | this.fixedHeader(); |
| 423 | + this.$nextTick(() => this.ready = true); | ||
| 394 | window.addEventListener('resize', this.handleResize, false); | 424 | window.addEventListener('resize', this.handleResize, false); |
| 395 | }, | 425 | }, |
| 396 | beforeDestroy () { | 426 | beforeDestroy () { |
src/styles/components/table.less
| 1 | @table-prefix-cls: ~"@{css-prefix}table"; | 1 | @table-prefix-cls: ~"@{css-prefix}table"; |
| 2 | +@table-select-item-prefix-cls: ~"@{table-prefix-cls}-filter-select-item"; | ||
| 2 | 3 | ||
| 3 | .@{table-prefix-cls} { | 4 | .@{table-prefix-cls} { |
| 4 | width: 100%; | 5 | width: 100%; |
| @@ -13,6 +14,10 @@ | @@ -13,6 +14,10 @@ | ||
| 13 | box-sizing: border-box; | 14 | box-sizing: border-box; |
| 14 | position: relative; | 15 | position: relative; |
| 15 | 16 | ||
| 17 | + &-hide{ | ||
| 18 | + opacity: 0; | ||
| 19 | + } | ||
| 20 | + | ||
| 16 | &:before{ | 21 | &:before{ |
| 17 | content: ''; | 22 | content: ''; |
| 18 | width: 100%; | 23 | width: 100%; |
| @@ -262,6 +267,10 @@ | @@ -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 | &-footer{ | 275 | &-footer{ |
| 267 | padding: 4px; | 276 | padding: 4px; |
test/routers/table.vue
| @@ -63,6 +63,7 @@ | @@ -63,6 +63,7 @@ | ||
| 63 | value: 'company' | 63 | value: 'company' |
| 64 | } | 64 | } |
| 65 | ], | 65 | ], |
| 66 | + filterMultiple: false | ||
| 66 | }, | 67 | }, |
| 67 | { | 68 | { |
| 68 | title: '标签', | 69 | title: '标签', |
| @@ -78,8 +79,11 @@ | @@ -78,8 +79,11 @@ | ||
| 78 | value: 'company' | 79 | value: 'company' |
| 79 | } | 80 | } |
| 80 | ], | 81 | ], |
| 82 | + filterMethod (value, row) { | ||
| 83 | + return row.tag === value; | ||
| 84 | + }, | ||
| 81 | render (row) { | 85 | render (row) { |
| 82 | - const type = `${row.tag}` === '家' ? 'green' : 'red'; | 86 | + const type = `${row.tag}` === 'home' ? 'green' : 'red'; |
| 83 | return `<tag color="${type}">${row.tag}</tag>`; | 87 | return `<tag color="${type}">${row.tag}</tag>`; |
| 84 | } | 88 | } |
| 85 | }, | 89 | }, |
| @@ -135,28 +139,28 @@ | @@ -135,28 +139,28 @@ | ||
| 135 | age: 25, | 139 | age: 25, |
| 136 | address: '北京市朝阳区', | 140 | address: '北京市朝阳区', |
| 137 | edit: false, | 141 | edit: false, |
| 138 | - tag: '家' | 142 | + tag: 'home' |
| 139 | }, | 143 | }, |
| 140 | { | 144 | { |
| 141 | name: '段模', | 145 | name: '段模', |
| 142 | age: 21, | 146 | age: 21, |
| 143 | address: '北京市海淀区', | 147 | address: '北京市海淀区', |
| 144 | edit: false, | 148 | edit: false, |
| 145 | - tag: '公司' | 149 | + tag: 'company' |
| 146 | }, | 150 | }, |
| 147 | { | 151 | { |
| 148 | name: '刘天娇', | 152 | name: '刘天娇', |
| 149 | age: 27, | 153 | age: 27, |
| 150 | address: '北京市东城区', | 154 | address: '北京市东城区', |
| 151 | edit: false, | 155 | edit: false, |
| 152 | - tag: '公司' | 156 | + tag: 'company' |
| 153 | }, | 157 | }, |
| 154 | { | 158 | { |
| 155 | name: '胡国伟', | 159 | name: '胡国伟', |
| 156 | age: 22, | 160 | age: 22, |
| 157 | address: '北京市西城区', | 161 | address: '北京市西城区', |
| 158 | edit: false, | 162 | edit: false, |
| 159 | - tag: '家' | 163 | + tag: 'home' |
| 160 | } | 164 | } |
| 161 | ], | 165 | ], |
| 162 | height: 200 | 166 | height: 200 |