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 | 1 | <template> |
| 2 | 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 | 8 | </div> |
| 31 | 9 | </template> |
| 32 | 10 | <script> |
| 33 | 11 | export default { |
| 34 | 12 | data () { |
| 35 | 13 | return { |
| 36 | - columns4: [ | |
| 37 | - { | |
| 38 | - type: 'selection', | |
| 39 | - width: 60, | |
| 40 | - align: 'center' | |
| 41 | - }, | |
| 14 | + columns1: [ | |
| 42 | 15 | { |
| 43 | 16 | title: 'Name', |
| 44 | 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 | 90 | columns2: [ |
| 66 | 91 | { |
| 67 | 92 | title: 'Name', |
| ... | ... | @@ -72,7 +97,9 @@ |
| 72 | 97 | { |
| 73 | 98 | title: 'Age', |
| 74 | 99 | key: 'age', |
| 75 | - width: 100 | |
| 100 | + width: 100, | |
| 101 | + fixed: 'right', | |
| 102 | + sortable: true | |
| 76 | 103 | }, |
| 77 | 104 | { |
| 78 | 105 | title: 'Province', |
| ... | ... | @@ -92,8 +119,7 @@ |
| 92 | 119 | { |
| 93 | 120 | title: 'Postcode', |
| 94 | 121 | key: 'zip', |
| 95 | - width: 100, | |
| 96 | - fixed: 'right', | |
| 122 | + width: 100 | |
| 97 | 123 | }, |
| 98 | 124 | { |
| 99 | 125 | title: 'Action', |
| ... | ... | @@ -118,7 +144,8 @@ |
| 118 | 144 | } |
| 119 | 145 | } |
| 120 | 146 | ], |
| 121 | - data3: [ | |
| 147 | + data1: [], | |
| 148 | + data4: [ | |
| 122 | 149 | { |
| 123 | 150 | name: 'John Brown', |
| 124 | 151 | age: 18, |
| ... | ... | @@ -152,16 +179,6 @@ |
| 152 | 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 | 182 | name: 'John Brown', |
| 166 | 183 | age: 18, |
| 167 | 184 | address: 'New York No. 1 Lake Park', |
| ... | ... | @@ -192,167 +209,26 @@ |
| 192 | 209 | province: 'Canada', |
| 193 | 210 | city: 'Ottawa', |
| 194 | 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 | 234 | </script> |
| 359 | 235 | \ No newline at end of file | ... | ... |
src/components/table/table-head.vue
| ... | ... | @@ -4,8 +4,12 @@ |
| 4 | 4 | <col v-for="(column, index) in columns" :width="setCellWidth(column, index, true)"> |
| 5 | 5 | </colgroup> |
| 6 | 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 | 13 | <div :class="cellClasses(column)"> |
| 10 | 14 | <template v-if="column.type === 'expand'"> |
| 11 | 15 | <span v-if="!column.renderHeader">{{ column.title || '' }}</span> |
| ... | ... | @@ -67,6 +71,7 @@ |
| 67 | 71 | import renderHeader from './header'; |
| 68 | 72 | import Mixin from './mixin'; |
| 69 | 73 | import Locale from '../../mixins/locale'; |
| 74 | + import { convertColumnOrder } from './util'; | |
| 70 | 75 | |
| 71 | 76 | export default { |
| 72 | 77 | name: 'TableHead', |
| ... | ... | @@ -82,7 +87,8 @@ |
| 82 | 87 | fixed: { |
| 83 | 88 | type: [Boolean, String], |
| 84 | 89 | default: false |
| 85 | - } | |
| 90 | + }, | |
| 91 | + columnRows: Array | |
| 86 | 92 | }, |
| 87 | 93 | computed: { |
| 88 | 94 | styles () { |
| ... | ... | @@ -108,6 +114,25 @@ |
| 108 | 114 | } |
| 109 | 115 | |
| 110 | 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 | 138 | methods: { | ... | ... |
src/components/table/table.vue
| ... | ... | @@ -7,6 +7,7 @@ |
| 7 | 7 | :prefix-cls="prefixCls" |
| 8 | 8 | :styleObject="tableStyle" |
| 9 | 9 | :columns="cloneColumns" |
| 10 | + :column-rows="columnRows" | |
| 10 | 11 | :obj-data="objData" |
| 11 | 12 | :columns-width="columnsWidth" |
| 12 | 13 | :data="rebuildData"></table-head> |
| ... | ... | @@ -43,6 +44,7 @@ |
| 43 | 44 | :prefix-cls="prefixCls" |
| 44 | 45 | :styleObject="fixedTableStyle" |
| 45 | 46 | :columns="leftFixedColumns" |
| 47 | + :column-rows="columnRows" | |
| 46 | 48 | :obj-data="objData" |
| 47 | 49 | :columns-width="columnsWidth" |
| 48 | 50 | :data="rebuildData"></table-head> |
| ... | ... | @@ -65,6 +67,7 @@ |
| 65 | 67 | :prefix-cls="prefixCls" |
| 66 | 68 | :styleObject="fixedRightTableStyle" |
| 67 | 69 | :columns="rightFixedColumns" |
| 70 | + :column-rows="columnRows" | |
| 68 | 71 | :obj-data="objData" |
| 69 | 72 | :columns-width="columnsWidth" |
| 70 | 73 | :data="rebuildData"></table-head> |
| ... | ... | @@ -97,6 +100,7 @@ |
| 97 | 100 | import ExportCsv from './export-csv'; |
| 98 | 101 | import Locale from '../../mixins/locale'; |
| 99 | 102 | import elementResizeDetectorMaker from 'element-resize-detector'; |
| 103 | + import { getAllColumns, convertToRows, convertColumnOrder } from './util'; | |
| 100 | 104 | |
| 101 | 105 | const prefixCls = 'ivu-table'; |
| 102 | 106 | |
| ... | ... | @@ -180,6 +184,8 @@ |
| 180 | 184 | objData: this.makeObjData(), // checkbox or highlight-row |
| 181 | 185 | rebuildData: [], // for sort or filter |
| 182 | 186 | cloneColumns: this.makeColumns(), |
| 187 | + columnRows: this.makeColumnRows(), | |
| 188 | + allColumns: getAllColumns(this.columns), // for multiple table-head, get columns that have no children | |
| 183 | 189 | showSlotHeader: true, |
| 184 | 190 | showSlotFooter: true, |
| 185 | 191 | bodyHeight: 0, |
| ... | ... | @@ -308,28 +314,10 @@ |
| 308 | 314 | return style; |
| 309 | 315 | }, |
| 310 | 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 | 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 | 322 | isLeftFixed () { |
| 335 | 323 | return this.columns.some(col => col.fixed && col.fixed === 'left'); |
| ... | ... | @@ -344,9 +332,9 @@ |
| 344 | 332 | }, |
| 345 | 333 | handleResize () { |
| 346 | 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 | 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 | 338 | } else { |
| 351 | 339 | this.tableWidth = parseInt(getStyle(this.$el, 'width')) - 1; |
| 352 | 340 | } |
| ... | ... | @@ -614,7 +602,7 @@ |
| 614 | 602 | this.cloneColumns[index]._sortType = type; |
| 615 | 603 | |
| 616 | 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 | 606 | key: key, |
| 619 | 607 | order: type |
| 620 | 608 | }); |
| ... | ... | @@ -751,7 +739,8 @@ |
| 751 | 739 | return data; |
| 752 | 740 | }, |
| 753 | 741 | makeColumns () { |
| 754 | - let columns = deepCopy(this.columns); | |
| 742 | + // 在 data 时,this.allColumns 暂时为 undefined | |
| 743 | + let columns = deepCopy(getAllColumns(this.columns)); | |
| 755 | 744 | let left = []; |
| 756 | 745 | let right = []; |
| 757 | 746 | let center = []; |
| ... | ... | @@ -789,6 +778,10 @@ |
| 789 | 778 | }); |
| 790 | 779 | return left.concat(center).concat(right); |
| 791 | 780 | }, |
| 781 | + // create a multiple table-head | |
| 782 | + makeColumnRows () { | |
| 783 | + return convertToRows(this.columns); | |
| 784 | + }, | |
| 792 | 785 | exportCsv (params) { |
| 793 | 786 | if (params.filename) { |
| 794 | 787 | if (params.filename.indexOf('.csv') === -1) { |
| ... | ... | @@ -804,7 +797,7 @@ |
| 804 | 797 | columns = params.columns; |
| 805 | 798 | datas = params.data; |
| 806 | 799 | } else { |
| 807 | - columns = this.columns; | |
| 800 | + columns = this.allColumns; | |
| 808 | 801 | if (!('original' in params)) params.original = true; |
| 809 | 802 | datas = params.original ? this.data : this.rebuildData; |
| 810 | 803 | } |
| ... | ... | @@ -863,7 +856,9 @@ |
| 863 | 856 | columns: { |
| 864 | 857 | handler () { |
| 865 | 858 | // todo 这里有性能问题,可能是左右固定计算属性影响的 |
| 859 | + this.allColumns = getAllColumns(this.columns); | |
| 866 | 860 | this.cloneColumns = this.makeColumns(); |
| 861 | + this.columnRows = this.makeColumnRows(); | |
| 867 | 862 | this.rebuildData = this.makeDataWithSortAndFilter(); |
| 868 | 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 | 82 | \ No newline at end of file | ... | ... |
src/styles/components/table.less
| ... | ... | @@ -71,7 +71,7 @@ |
| 71 | 71 | overflow: hidden; |
| 72 | 72 | } |
| 73 | 73 | &-body{ |
| 74 | - //overflow: auto; | |
| 74 | + overflow: auto; | |
| 75 | 75 | //position: relative; |
| 76 | 76 | |
| 77 | 77 | } |
| ... | ... | @@ -285,7 +285,7 @@ |
| 285 | 285 | box-shadow: -2px 0 6px -2px rgba(0, 0, 0, 0.2); |
| 286 | 286 | } |
| 287 | 287 | &-fixed-header{ |
| 288 | - overflow: visible; | |
| 288 | + overflow: hidden; | |
| 289 | 289 | &-with-empty{ |
| 290 | 290 | .@{table-prefix-cls}-hidden{ |
| 291 | 291 | .@{table-prefix-cls}-sort{ | ... | ... |