Commit 1acabf7912bcec067425a9236b09becf6704d175
1 parent
12739c33
Table support multiple table-head
Showing
5 changed files
with
226 additions
and
249 deletions
Show diff stats
examples/routers/table.vue
1 | <template> | 1 | <template> |
2 | <div> | 2 | <div> |
3 | - <Table border ref="selection" :columns="columns4" :data="data1" :height='258'></Table> | ||
4 | - <Button @click="handleSetData">Set Data</Button> | ||
5 | - <Button @click="handleClearData">Clear Data</Button> | ||
6 | - <Button @click="handleSelectAll(true)">Set all selected</Button> | ||
7 | - <Button @click="handleSelectAll(false)">Cancel all selected</Button> | ||
8 | - <div style='margin:20px 0px'> | ||
9 | - <Table border :columns="columns2" :data="data3"></Table> | ||
10 | - </div> | ||
11 | - <div style='margin:20px 0px'> | ||
12 | - <Table :height='200' border :columns="columns2" :data="data3"></Table> | ||
13 | - </div> | ||
14 | - <div style='margin:20px 0px'> | ||
15 | - <Table :width='600' border :columns="columns2" :data="data3"></Table> | ||
16 | - </div> | ||
17 | - <div style='margin:20px 0px'> | ||
18 | - <Table :width='600' :height='200' border :columns="columns2" :data="data31"></Table> | ||
19 | - </div> | ||
20 | - <div style='margin:20px 0px;'> | ||
21 | - Table scrolling <i-switch v-model="fixedHeader" style="margin-right: 5px"></i-switch> | ||
22 | - <Table :data="tableData1" :columns="tableColumns1" :height="fixedHeader ? 250 : ''" stripe size='small'></Table> | ||
23 | - <div style="margin: 10px;overflow: hidden"> | ||
24 | - <div style="float: right;"> | ||
25 | - <Page :total="100" show-sizer :current="1" @on-change="changePage"></Page> | ||
26 | - </div> | ||
27 | - </div> | ||
28 | - </div> | ||
29 | - | 3 | + <br><br><br><br><br> |
4 | + <Table border :columns="columns1" height="500" :data="data1"></Table> | ||
5 | + <br><br><br><br><br> | ||
6 | + <!--<Table width="550" height="200" border :columns="columns2" :data="data4"></Table>--> | ||
7 | + <br><br><br><br><br> | ||
30 | </div> | 8 | </div> |
31 | </template> | 9 | </template> |
32 | <script> | 10 | <script> |
33 | export default { | 11 | export default { |
34 | data () { | 12 | data () { |
35 | return { | 13 | return { |
36 | - columns4: [ | ||
37 | - { | ||
38 | - type: 'selection', | ||
39 | - width: 60, | ||
40 | - align: 'center' | ||
41 | - }, | 14 | + columns1: [ |
42 | { | 15 | { |
43 | title: 'Name', | 16 | title: 'Name', |
44 | key: 'name', | 17 | key: 'name', |
45 | - width: 260 | ||
46 | - }, | ||
47 | - { | ||
48 | - title: 'Age', | ||
49 | - key: 'age' | ||
50 | - }, | ||
51 | - { | ||
52 | - title: 'Address', | ||
53 | - key: 'address', | ||
54 | - width: 260 | 18 | + align: 'center', |
19 | + width: 200, | ||
20 | + fixed: 'left' | ||
55 | }, | 21 | }, |
56 | { | 22 | { |
57 | - title: 'Address', | ||
58 | - key: 'address', | ||
59 | - width: 260 | 23 | + title: 'Other', |
24 | + align: 'center', | ||
25 | + children: [ | ||
26 | + { | ||
27 | + title: 'Age', | ||
28 | + key: 'age', | ||
29 | + align: 'center', | ||
30 | + width: 200 | ||
31 | + }, | ||
32 | + { | ||
33 | + title: 'Address', | ||
34 | + align: 'center', | ||
35 | + children: [ | ||
36 | + { | ||
37 | + title: 'Street', | ||
38 | + key: 'street', | ||
39 | + align: 'center', | ||
40 | + width: 200 | ||
41 | + }, | ||
42 | + { | ||
43 | + title: 'Block', | ||
44 | + align: 'center', | ||
45 | + children: [ | ||
46 | + { | ||
47 | + title: 'Building', | ||
48 | + key: 'building', | ||
49 | + align: 'center', | ||
50 | + width: 200 | ||
51 | + }, | ||
52 | + { | ||
53 | + title: 'Door No.', | ||
54 | + key: 'door', | ||
55 | + align: 'center', | ||
56 | + width: 200 | ||
57 | + } | ||
58 | + ] | ||
59 | + } | ||
60 | + ] | ||
61 | + } | ||
62 | + ] | ||
63 | + }, | ||
64 | + { | ||
65 | + title: 'Company', | ||
66 | + align: 'center', | ||
67 | + children: [ | ||
68 | + { | ||
69 | + title: 'Company Address', | ||
70 | + key: 'caddress', | ||
71 | + align: 'center', | ||
72 | + width: 200 | ||
73 | + }, | ||
74 | + { | ||
75 | + title: 'Company Name', | ||
76 | + key: 'cname', | ||
77 | + align: 'center', | ||
78 | + width: 200 | ||
79 | + } | ||
80 | + ] | ||
81 | + }, | ||
82 | + { | ||
83 | + title: 'Gender', | ||
84 | + key: 'gender', | ||
85 | + align: 'center', | ||
86 | + width: 200, | ||
87 | + fixed: 'right' | ||
60 | } | 88 | } |
61 | ], | 89 | ], |
62 | - data1: [ | ||
63 | - | ||
64 | - ], | ||
65 | columns2: [ | 90 | columns2: [ |
66 | { | 91 | { |
67 | title: 'Name', | 92 | title: 'Name', |
@@ -72,7 +97,9 @@ | @@ -72,7 +97,9 @@ | ||
72 | { | 97 | { |
73 | title: 'Age', | 98 | title: 'Age', |
74 | key: 'age', | 99 | key: 'age', |
75 | - width: 100 | 100 | + width: 100, |
101 | + fixed: 'right', | ||
102 | + sortable: true | ||
76 | }, | 103 | }, |
77 | { | 104 | { |
78 | title: 'Province', | 105 | title: 'Province', |
@@ -92,8 +119,7 @@ | @@ -92,8 +119,7 @@ | ||
92 | { | 119 | { |
93 | title: 'Postcode', | 120 | title: 'Postcode', |
94 | key: 'zip', | 121 | key: 'zip', |
95 | - width: 100, | ||
96 | - fixed: 'right', | 122 | + width: 100 |
97 | }, | 123 | }, |
98 | { | 124 | { |
99 | title: 'Action', | 125 | title: 'Action', |
@@ -118,7 +144,8 @@ | @@ -118,7 +144,8 @@ | ||
118 | } | 144 | } |
119 | } | 145 | } |
120 | ], | 146 | ], |
121 | - data3: [ | 147 | + data1: [], |
148 | + data4: [ | ||
122 | { | 149 | { |
123 | name: 'John Brown', | 150 | name: 'John Brown', |
124 | age: 18, | 151 | age: 18, |
@@ -152,16 +179,6 @@ | @@ -152,16 +179,6 @@ | ||
152 | zip: 100000 | 179 | zip: 100000 |
153 | }, | 180 | }, |
154 | { | 181 | { |
155 | - name: 'Jon Snow', | ||
156 | - age: 26, | ||
157 | - address: 'Ottawa No. 2 Lake Park', | ||
158 | - province: 'Canada', | ||
159 | - city: 'Ottawa', | ||
160 | - zip: 100000 | ||
161 | - } | ||
162 | - ], | ||
163 | - data31: [ | ||
164 | - { | ||
165 | name: 'John Brown', | 182 | name: 'John Brown', |
166 | age: 18, | 183 | age: 18, |
167 | address: 'New York No. 1 Lake Park', | 184 | address: 'New York No. 1 Lake Park', |
@@ -192,167 +209,26 @@ | @@ -192,167 +209,26 @@ | ||
192 | province: 'Canada', | 209 | province: 'Canada', |
193 | city: 'Ottawa', | 210 | city: 'Ottawa', |
194 | zip: 100000 | 211 | zip: 100000 |
195 | - }, | ||
196 | - { | ||
197 | - name: 'Jon Snow', | ||
198 | - age: 26, | ||
199 | - address: 'Ottawa No. 2 Lake Park', | ||
200 | - province: 'Canada', | ||
201 | - city: 'Ottawa', | ||
202 | - zip: 100000 | ||
203 | - }, | ||
204 | - { | ||
205 | - name: 'Jim Green', | ||
206 | - age: 24, | ||
207 | - address: 'Washington, D.C. No. 1 Lake Park', | ||
208 | - province: 'America', | ||
209 | - city: 'Washington, D.C.', | ||
210 | - zip: 100000 | ||
211 | - }, | ||
212 | - { | ||
213 | - name: 'Joe Black', | ||
214 | - age: 30, | ||
215 | - address: 'Sydney No. 1 Lake Park', | ||
216 | - province: 'Australian', | ||
217 | - city: 'Sydney', | ||
218 | - zip: 100000 | ||
219 | - }, | ||
220 | - { | ||
221 | - name: 'Jon Snow', | ||
222 | - age: 26, | ||
223 | - address: 'Ottawa No. 2 Lake Park', | ||
224 | - province: 'Canada', | ||
225 | - city: 'Ottawa', | ||
226 | - zip: 100000 | ||
227 | - }, | ||
228 | - { | ||
229 | - name: 'Jon Snow', | ||
230 | - age: 26, | ||
231 | - address: 'Ottawa No. 2 Lake Park', | ||
232 | - province: 'Canada', | ||
233 | - city: 'Ottawa', | ||
234 | - zip: 100000 | ||
235 | - }, | ||
236 | - { | ||
237 | - name: 'Jim Green', | ||
238 | - age: 24, | ||
239 | - address: 'Washington, D.C. No. 1 Lake Park', | ||
240 | - province: 'America', | ||
241 | - city: 'Washington, D.C.', | ||
242 | - zip: 100000 | ||
243 | - }, | ||
244 | - { | ||
245 | - name: 'Joe Black', | ||
246 | - age: 30, | ||
247 | - address: 'Sydney No. 1 Lake Park', | ||
248 | - province: 'Australian', | ||
249 | - city: 'Sydney', | ||
250 | - zip: 100000 | ||
251 | - }, | ||
252 | - { | ||
253 | - name: 'Jon Snow', | ||
254 | - age: 26, | ||
255 | - address: 'Ottawa No. 2 Lake Park', | ||
256 | - province: 'Canada', | ||
257 | - city: 'Ottawa', | ||
258 | - zip: 100000 | ||
259 | - }, | ||
260 | - { | ||
261 | - name: 'Jon Snow', | ||
262 | - age: 26, | ||
263 | - address: 'Ottawa No. 2 Lake Park', | ||
264 | - province: 'Canada', | ||
265 | - city: 'Ottawa', | ||
266 | - zip: 100000 | ||
267 | } | 212 | } |
268 | - ], | ||
269 | - | ||
270 | - | ||
271 | - fixedHeader: false, | ||
272 | - tableData1: [], | ||
273 | - tableColumns1: [ | ||
274 | - { | ||
275 | - title: 'Data1', | ||
276 | - key: 'data1' | ||
277 | - }, | ||
278 | - { | ||
279 | - title: 'Data2', | ||
280 | - key: 'data2' | ||
281 | - }, | ||
282 | - { | ||
283 | - title: 'Data3', | ||
284 | - key: 'data3' | ||
285 | - }, | ||
286 | - { | ||
287 | - title: 'Data4', | ||
288 | - key: 'data4' | ||
289 | - }, | ||
290 | - { | ||
291 | - title: 'Data5', | ||
292 | - key: 'data5' | ||
293 | - }, | ||
294 | - { | ||
295 | - title: 'Data6Data6Data6Data6Data6Data6Data6Data6Data6Data6Data6', | ||
296 | - key: 'data6' | ||
297 | - }, | ||
298 | ] | 213 | ] |
299 | } | 214 | } |
300 | }, | 215 | }, |
301 | - mounted(){ | ||
302 | - this.refreshData(); | ||
303 | - }, | ||
304 | - methods: { | ||
305 | - handleSelectAll (status) { | ||
306 | - this.$refs.selection.selectAll(status); | ||
307 | - }, | ||
308 | - handleSetData () { | ||
309 | - this.data1 = [ | ||
310 | - { | ||
311 | - name: 'John Brown', | ||
312 | - age: 18, | ||
313 | - address: 'New York No. 1 Lake Park', | ||
314 | - date: '2016-10-03' | ||
315 | - }, | ||
316 | - { | ||
317 | - name: 'Jim Green', | ||
318 | - age: 24, | ||
319 | - address: 'London No. 1 Lake Park', | ||
320 | - date: '2016-10-01' | ||
321 | - }, | ||
322 | - { | ||
323 | - name: 'Joe Black', | ||
324 | - age: 30, | ||
325 | - address: 'Sydney No. 1 Lake Park', | ||
326 | - date: '2016-10-02' | ||
327 | - }, | ||
328 | - { | ||
329 | - name: 'Jon Snow', | ||
330 | - age: 26, | ||
331 | - address: 'Ottawa No. 2 Lake Park', | ||
332 | - date: '2016-10-04' | ||
333 | - } | ||
334 | - ]; | ||
335 | - }, | ||
336 | - handleClearData () { | ||
337 | - this.data1 = []; | ||
338 | - }, | ||
339 | - refreshData(){ | ||
340 | - let data = []; | ||
341 | - for (let i = 0; i < 10; i++) { | ||
342 | - data.push({ | ||
343 | - data1: Math.floor(Math.random () * 10000), | ||
344 | - data2: Math.floor(Math.random () * 1000000), | ||
345 | - data3: Math.floor(Math.random () * 100000000), | ||
346 | - data4: Math.floor(Math.random () * Math.random () * 10000), | ||
347 | - data5: Math.floor(Math.random () * Math.random () * 1000000), | ||
348 | - data6: ''+Math.floor(Math.random () * Math.random () * 100000000)+Math.floor(Math.random () * 100000000)+Math.floor(Math.random () * 100000000), | ||
349 | - }); | ||
350 | - } | ||
351 | - this.tableData1 = data; | ||
352 | - }, | ||
353 | - changePage(){ | ||
354 | - this.refreshData(); | 216 | + mounted () { |
217 | + const data = []; | ||
218 | + for (let i = 0; i < 100; i++) { | ||
219 | + data.push({ | ||
220 | + key: i, | ||
221 | + name: 'John Brown', | ||
222 | + age: i + 1, | ||
223 | + street: 'Lake Park', | ||
224 | + building: 'C', | ||
225 | + door: 2035, | ||
226 | + caddress: 'Lake Street 42', | ||
227 | + cname: 'SoftLake Co', | ||
228 | + gender: 'M', | ||
229 | + }); | ||
355 | } | 230 | } |
231 | + this.data1 = data; | ||
356 | } | 232 | } |
357 | } | 233 | } |
358 | </script> | 234 | </script> |
359 | \ No newline at end of file | 235 | \ No newline at end of file |
src/components/table/table-head.vue
@@ -4,8 +4,12 @@ | @@ -4,8 +4,12 @@ | ||
4 | <col v-for="(column, index) in columns" :width="setCellWidth(column, index, true)"> | 4 | <col v-for="(column, index) in columns" :width="setCellWidth(column, index, true)"> |
5 | </colgroup> | 5 | </colgroup> |
6 | <thead> | 6 | <thead> |
7 | - <tr> | ||
8 | - <th v-for="(column, index) in columns" :class="alignCls(column)"> | 7 | + <tr v-for="(cols, rowIndex) in headRows"> |
8 | + <th | ||
9 | + v-for="(column, index) in cols" | ||
10 | + :colspan="column.colSpan" | ||
11 | + :rowspan="column.rowSpan" | ||
12 | + :class="alignCls(column)"> | ||
9 | <div :class="cellClasses(column)"> | 13 | <div :class="cellClasses(column)"> |
10 | <template v-if="column.type === 'expand'"> | 14 | <template v-if="column.type === 'expand'"> |
11 | <span v-if="!column.renderHeader">{{ column.title || '' }}</span> | 15 | <span v-if="!column.renderHeader">{{ column.title || '' }}</span> |
@@ -67,6 +71,7 @@ | @@ -67,6 +71,7 @@ | ||
67 | import renderHeader from './header'; | 71 | import renderHeader from './header'; |
68 | import Mixin from './mixin'; | 72 | import Mixin from './mixin'; |
69 | import Locale from '../../mixins/locale'; | 73 | import Locale from '../../mixins/locale'; |
74 | + import { convertColumnOrder } from './util'; | ||
70 | 75 | ||
71 | export default { | 76 | export default { |
72 | name: 'TableHead', | 77 | name: 'TableHead', |
@@ -82,7 +87,8 @@ | @@ -82,7 +87,8 @@ | ||
82 | fixed: { | 87 | fixed: { |
83 | type: [Boolean, String], | 88 | type: [Boolean, String], |
84 | default: false | 89 | default: false |
85 | - } | 90 | + }, |
91 | + columnRows: Array | ||
86 | }, | 92 | }, |
87 | computed: { | 93 | computed: { |
88 | styles () { | 94 | styles () { |
@@ -108,6 +114,25 @@ | @@ -108,6 +114,25 @@ | ||
108 | } | 114 | } |
109 | 115 | ||
110 | return isSelectAll; | 116 | return isSelectAll; |
117 | + }, | ||
118 | + headRows () { | ||
119 | + const isGroup = this.columnRows.length > 1; | ||
120 | + return isGroup ? this.columnRows : [this.columns]; | ||
121 | + | ||
122 | +// if (isGroup) { | ||
123 | +// const fixedType = this.fixed; | ||
124 | +// if (fixedType) { | ||
125 | +// if (fixedType === 'left') { | ||
126 | +// return convertColumnOrder(this.columnRows, 'left'); | ||
127 | +// } else if (fixedType === 'right') { | ||
128 | +// return convertColumnOrder(this.columnRows, 'right'); | ||
129 | +// } | ||
130 | +// } else { | ||
131 | +// return this.columnRows; | ||
132 | +// } | ||
133 | +// } else { | ||
134 | +// return [this.columns]; | ||
135 | +// } | ||
111 | } | 136 | } |
112 | }, | 137 | }, |
113 | methods: { | 138 | methods: { |
src/components/table/table.vue
@@ -7,6 +7,7 @@ | @@ -7,6 +7,7 @@ | ||
7 | :prefix-cls="prefixCls" | 7 | :prefix-cls="prefixCls" |
8 | :styleObject="tableStyle" | 8 | :styleObject="tableStyle" |
9 | :columns="cloneColumns" | 9 | :columns="cloneColumns" |
10 | + :column-rows="columnRows" | ||
10 | :obj-data="objData" | 11 | :obj-data="objData" |
11 | :columns-width="columnsWidth" | 12 | :columns-width="columnsWidth" |
12 | :data="rebuildData"></table-head> | 13 | :data="rebuildData"></table-head> |
@@ -43,6 +44,7 @@ | @@ -43,6 +44,7 @@ | ||
43 | :prefix-cls="prefixCls" | 44 | :prefix-cls="prefixCls" |
44 | :styleObject="fixedTableStyle" | 45 | :styleObject="fixedTableStyle" |
45 | :columns="leftFixedColumns" | 46 | :columns="leftFixedColumns" |
47 | + :column-rows="columnRows" | ||
46 | :obj-data="objData" | 48 | :obj-data="objData" |
47 | :columns-width="columnsWidth" | 49 | :columns-width="columnsWidth" |
48 | :data="rebuildData"></table-head> | 50 | :data="rebuildData"></table-head> |
@@ -65,6 +67,7 @@ | @@ -65,6 +67,7 @@ | ||
65 | :prefix-cls="prefixCls" | 67 | :prefix-cls="prefixCls" |
66 | :styleObject="fixedRightTableStyle" | 68 | :styleObject="fixedRightTableStyle" |
67 | :columns="rightFixedColumns" | 69 | :columns="rightFixedColumns" |
70 | + :column-rows="columnRows" | ||
68 | :obj-data="objData" | 71 | :obj-data="objData" |
69 | :columns-width="columnsWidth" | 72 | :columns-width="columnsWidth" |
70 | :data="rebuildData"></table-head> | 73 | :data="rebuildData"></table-head> |
@@ -97,6 +100,7 @@ | @@ -97,6 +100,7 @@ | ||
97 | import ExportCsv from './export-csv'; | 100 | import ExportCsv from './export-csv'; |
98 | import Locale from '../../mixins/locale'; | 101 | import Locale from '../../mixins/locale'; |
99 | import elementResizeDetectorMaker from 'element-resize-detector'; | 102 | import elementResizeDetectorMaker from 'element-resize-detector'; |
103 | + import { getAllColumns, convertToRows, convertColumnOrder } from './util'; | ||
100 | 104 | ||
101 | const prefixCls = 'ivu-table'; | 105 | const prefixCls = 'ivu-table'; |
102 | 106 | ||
@@ -180,6 +184,8 @@ | @@ -180,6 +184,8 @@ | ||
180 | objData: this.makeObjData(), // checkbox or highlight-row | 184 | objData: this.makeObjData(), // checkbox or highlight-row |
181 | rebuildData: [], // for sort or filter | 185 | rebuildData: [], // for sort or filter |
182 | cloneColumns: this.makeColumns(), | 186 | cloneColumns: this.makeColumns(), |
187 | + columnRows: this.makeColumnRows(), | ||
188 | + allColumns: getAllColumns(this.columns), // for multiple table-head, get columns that have no children | ||
183 | showSlotHeader: true, | 189 | showSlotHeader: true, |
184 | showSlotFooter: true, | 190 | showSlotFooter: true, |
185 | bodyHeight: 0, | 191 | bodyHeight: 0, |
@@ -308,28 +314,10 @@ | @@ -308,28 +314,10 @@ | ||
308 | return style; | 314 | return style; |
309 | }, | 315 | }, |
310 | leftFixedColumns () { | 316 | leftFixedColumns () { |
311 | - let left = []; | ||
312 | - let other = []; | ||
313 | - this.cloneColumns.forEach((col) => { | ||
314 | - if (col.fixed && col.fixed === 'left') { | ||
315 | - left.push(col); | ||
316 | - } else { | ||
317 | - //other.push(col); | ||
318 | - } | ||
319 | - }); | ||
320 | - return left.concat(other); | 317 | + return convertColumnOrder(this.cloneColumns, 'left'); |
321 | }, | 318 | }, |
322 | rightFixedColumns () { | 319 | rightFixedColumns () { |
323 | - let right = []; | ||
324 | - let other = []; | ||
325 | - this.cloneColumns.forEach((col) => { | ||
326 | - if (col.fixed && col.fixed === 'right') { | ||
327 | - right.push(col); | ||
328 | - } else { | ||
329 | - //other.push(col); | ||
330 | - } | ||
331 | - }); | ||
332 | - return right.concat(other); | 320 | + return convertColumnOrder(this.cloneColumns, 'right'); |
333 | }, | 321 | }, |
334 | isLeftFixed () { | 322 | isLeftFixed () { |
335 | return this.columns.some(col => col.fixed && col.fixed === 'left'); | 323 | return this.columns.some(col => col.fixed && col.fixed === 'left'); |
@@ -344,9 +332,9 @@ | @@ -344,9 +332,9 @@ | ||
344 | }, | 332 | }, |
345 | handleResize () { | 333 | handleResize () { |
346 | this.$nextTick(() => { | 334 | this.$nextTick(() => { |
347 | - const allWidth = !this.columns.some(cell => !cell.width); // each column set a width | 335 | + const allWidth = !this.allColumns.some(cell => !cell.width); // each column set a width |
348 | if (allWidth) { | 336 | if (allWidth) { |
349 | - this.tableWidth = this.columns.map(cell => cell.width).reduce((a, b) => a + b, 0); | 337 | + this.tableWidth = this.allColumns.map(cell => cell.width).reduce((a, b) => a + b, 0); |
350 | } else { | 338 | } else { |
351 | this.tableWidth = parseInt(getStyle(this.$el, 'width')) - 1; | 339 | this.tableWidth = parseInt(getStyle(this.$el, 'width')) - 1; |
352 | } | 340 | } |
@@ -614,7 +602,7 @@ | @@ -614,7 +602,7 @@ | ||
614 | this.cloneColumns[index]._sortType = type; | 602 | this.cloneColumns[index]._sortType = type; |
615 | 603 | ||
616 | this.$emit('on-sort-change', { | 604 | this.$emit('on-sort-change', { |
617 | - column: JSON.parse(JSON.stringify(this.columns[this.cloneColumns[index]._index])), | 605 | + column: JSON.parse(JSON.stringify(this.allColumns[this.cloneColumns[index]._index])), |
618 | key: key, | 606 | key: key, |
619 | order: type | 607 | order: type |
620 | }); | 608 | }); |
@@ -751,7 +739,8 @@ | @@ -751,7 +739,8 @@ | ||
751 | return data; | 739 | return data; |
752 | }, | 740 | }, |
753 | makeColumns () { | 741 | makeColumns () { |
754 | - let columns = deepCopy(this.columns); | 742 | + // 在 data 时,this.allColumns 暂时为 undefined |
743 | + let columns = deepCopy(getAllColumns(this.columns)); | ||
755 | let left = []; | 744 | let left = []; |
756 | let right = []; | 745 | let right = []; |
757 | let center = []; | 746 | let center = []; |
@@ -789,6 +778,10 @@ | @@ -789,6 +778,10 @@ | ||
789 | }); | 778 | }); |
790 | return left.concat(center).concat(right); | 779 | return left.concat(center).concat(right); |
791 | }, | 780 | }, |
781 | + // create a multiple table-head | ||
782 | + makeColumnRows () { | ||
783 | + return convertToRows(this.columns); | ||
784 | + }, | ||
792 | exportCsv (params) { | 785 | exportCsv (params) { |
793 | if (params.filename) { | 786 | if (params.filename) { |
794 | if (params.filename.indexOf('.csv') === -1) { | 787 | if (params.filename.indexOf('.csv') === -1) { |
@@ -804,7 +797,7 @@ | @@ -804,7 +797,7 @@ | ||
804 | columns = params.columns; | 797 | columns = params.columns; |
805 | datas = params.data; | 798 | datas = params.data; |
806 | } else { | 799 | } else { |
807 | - columns = this.columns; | 800 | + columns = this.allColumns; |
808 | if (!('original' in params)) params.original = true; | 801 | if (!('original' in params)) params.original = true; |
809 | datas = params.original ? this.data : this.rebuildData; | 802 | datas = params.original ? this.data : this.rebuildData; |
810 | } | 803 | } |
@@ -863,7 +856,9 @@ | @@ -863,7 +856,9 @@ | ||
863 | columns: { | 856 | columns: { |
864 | handler () { | 857 | handler () { |
865 | // todo 这里有性能问题,可能是左右固定计算属性影响的 | 858 | // todo 这里有性能问题,可能是左右固定计算属性影响的 |
859 | + this.allColumns = getAllColumns(this.columns); | ||
866 | this.cloneColumns = this.makeColumns(); | 860 | this.cloneColumns = this.makeColumns(); |
861 | + this.columnRows = this.makeColumnRows(); | ||
867 | this.rebuildData = this.makeDataWithSortAndFilter(); | 862 | this.rebuildData = this.makeDataWithSortAndFilter(); |
868 | this.handleResize(); | 863 | this.handleResize(); |
869 | }, | 864 | }, |
1 | +import { deepCopy } from '../../utils/assist'; | ||
2 | + | ||
3 | +// set forTableHead to true when convertToRows, false in normal cases like table.vue | ||
4 | +const getAllColumns = (cols, forTableHead = false) => { | ||
5 | + const columns = deepCopy(cols); | ||
6 | + const result = []; | ||
7 | + columns.forEach((column) => { | ||
8 | + if (column.children) { | ||
9 | + if (forTableHead) result.push(column); | ||
10 | + result.push.apply(result, getAllColumns(column.children, forTableHead)); | ||
11 | + } else { | ||
12 | + result.push(column); | ||
13 | + } | ||
14 | + }); | ||
15 | + return result; | ||
16 | +}; | ||
17 | + | ||
18 | +export {getAllColumns}; | ||
19 | + | ||
20 | +const convertToRows = (columns) => { | ||
21 | + const originColumns = deepCopy(columns); | ||
22 | + let maxLevel = 1; | ||
23 | + const traverse = (column, parent) => { | ||
24 | + if (parent) { | ||
25 | + column.level = parent.level + 1; | ||
26 | + if (maxLevel < column.level) { | ||
27 | + maxLevel = column.level; | ||
28 | + } | ||
29 | + } | ||
30 | + if (column.children) { | ||
31 | + let colSpan = 0; | ||
32 | + column.children.forEach((subColumn) => { | ||
33 | + traverse(subColumn, column); | ||
34 | + colSpan += subColumn.colSpan; | ||
35 | + }); | ||
36 | + column.colSpan = colSpan; | ||
37 | + } else { | ||
38 | + column.colSpan = 1; | ||
39 | + } | ||
40 | + }; | ||
41 | + | ||
42 | + originColumns.forEach((column) => { | ||
43 | + column.level = 1; | ||
44 | + traverse(column); | ||
45 | + }); | ||
46 | + | ||
47 | + const rows = []; | ||
48 | + for (let i = 0; i < maxLevel; i++) { | ||
49 | + rows.push([]); | ||
50 | + } | ||
51 | + | ||
52 | + const allColumns = getAllColumns(originColumns, true); | ||
53 | + | ||
54 | + allColumns.forEach((column) => { | ||
55 | + if (!column.children) { | ||
56 | + column.rowSpan = maxLevel - column.level + 1; | ||
57 | + } else { | ||
58 | + column.rowSpan = 1; | ||
59 | + } | ||
60 | + rows[column.level - 1].push(column); | ||
61 | + }); | ||
62 | + | ||
63 | + return rows; | ||
64 | +}; | ||
65 | + | ||
66 | +export {convertToRows}; | ||
67 | + | ||
68 | +const convertColumnOrder = (columns, FixedType) => { | ||
69 | + let list = []; | ||
70 | + let other = []; | ||
71 | + columns.forEach((col) => { | ||
72 | + if (col.fixed && col.fixed === FixedType) { | ||
73 | + list.push(col); | ||
74 | + } else { | ||
75 | + other.push(col); | ||
76 | + } | ||
77 | + }); | ||
78 | + return list.concat(other); | ||
79 | +}; | ||
80 | + | ||
81 | +export {convertColumnOrder}; | ||
0 | \ No newline at end of file | 82 | \ No newline at end of file |
src/styles/components/table.less
@@ -71,7 +71,7 @@ | @@ -71,7 +71,7 @@ | ||
71 | overflow: hidden; | 71 | overflow: hidden; |
72 | } | 72 | } |
73 | &-body{ | 73 | &-body{ |
74 | - //overflow: auto; | 74 | + overflow: auto; |
75 | //position: relative; | 75 | //position: relative; |
76 | 76 | ||
77 | } | 77 | } |
@@ -285,7 +285,7 @@ | @@ -285,7 +285,7 @@ | ||
285 | box-shadow: -2px 0 6px -2px rgba(0, 0, 0, 0.2); | 285 | box-shadow: -2px 0 6px -2px rgba(0, 0, 0, 0.2); |
286 | } | 286 | } |
287 | &-fixed-header{ | 287 | &-fixed-header{ |
288 | - overflow: visible; | 288 | + overflow: hidden; |
289 | &-with-empty{ | 289 | &-with-empty{ |
290 | .@{table-prefix-cls}-hidden{ | 290 | .@{table-prefix-cls}-hidden{ |
291 | .@{table-prefix-cls}-sort{ | 291 | .@{table-prefix-cls}-sort{ |