Commit adaeca88ba2f6f39a43336901b6ec74e65741221

Authored by 梁灏
1 parent 7f1edb6a

update Table

update Table
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