Commit 6cbd947611b8b9d1eeb6d3cc0c13a339d286e5f1

Authored by Aresn
Committed by GitHub
2 parents dee03ef3 5c9c4dff

Merge pull request #3284 from huanghong1125/2.0

column add prop minWidth and maxWidth
examples/routers/table.vue
1 1 <template>
2 2 <div>
3 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>-->
  4 + <Table border :show-header='false' :columns="columns1" height="500" :data="data1"></Table>
  5 + <!-- <Table border :columns="columns1" height='300'></Table> -->
  6 + <!-- <br><br><br><br><br> -->
  7 + <!-- <Table width="550" height="200" border :columns="columns2" :data="data4"></Table> -->
7 8 <!--<br><br><br><br><br>-->
8   - <Table border :columns="columns5" height="240" :data="data5"></Table>
9   - <br><br><br><br><br>
10   - <Table border :columns="columns6" :data="data5"></Table>
11   - <br><br><br><br><br>
  9 + <!-- <Table border :columns="columns5" height="240" :data="data5"></Table> -->
  10 + <!-- <br><br><br><br><br> -->
  11 + <!-- <Table border :columns="columns6" :data="data5"></Table> -->
  12 + <!-- <br><br><br><br><br> -->
  13 + <Table border :show-header='false' :columns="columns7" height="200" :data="data7"></Table>
12 14 <Table border :columns="columns7" height="240" :data="data7"></Table>
  15 + <!-- <br><br><br><br><br> -->
  16 + <!-- <Table border :columns="columns8" :data="data7" height="200"></Table> -->
  17 + <!-- <Table border :columns="columns8" height="200"></Table> -->
13 18 <br><br><br><br><br>
14 19 </div>
15 20 </template>
... ... @@ -22,7 +27,8 @@
22 27 title: 'Name',
23 28 key: 'name',
24 29 align: 'center',
25   - width: 200,
  30 + minWidth: 100,
  31 + maxWidth: 200,
26 32 fixed: 'left',
27 33 filters: [
28 34 {
... ... @@ -51,7 +57,8 @@
51 57 title: 'Age',
52 58 key: 'age',
53 59 align: 'center',
54   - width: 200,
  60 + minWidth: 100,
  61 + maxWidth: 200,
55 62 sortable: true
56 63 },
57 64 {
... ... @@ -62,7 +69,8 @@
62 69 title: 'Street',
63 70 key: 'street',
64 71 align: 'center',
65   - width: 200
  72 + minWidth: 100,
  73 + maxWidth: 200,
66 74 },
67 75 {
68 76 title: 'Block',
... ... @@ -72,14 +80,16 @@
72 80 title: 'Building',
73 81 key: 'building',
74 82 align: 'center',
75   - width: 200,
  83 + minWidth: 100,
  84 + maxWidth: 200,
76 85 sortable: true
77 86 },
78 87 {
79 88 title: 'Door No.',
80 89 key: 'door',
81 90 align: 'center',
82   - width: 200
  91 + minWidth: 100,
  92 + maxWidth: 200,
83 93 }
84 94 ]
85 95 }
... ... @@ -95,13 +105,15 @@
95 105 title: 'Company Address',
96 106 key: 'caddress',
97 107 align: 'center',
98   - width: 200
  108 + minWidth: 100,
  109 + maxWidth: 200,
99 110 },
100 111 {
101 112 title: 'Company Name',
102 113 key: 'cname',
103 114 align: 'center',
104   - width: 200
  115 + minWidth: 100,
  116 + maxWidth: 200,
105 117 }
106 118 ]
107 119 },
... ... @@ -116,8 +128,9 @@
116 128 title: 'Gender',
117 129 key: 'gender',
118 130 align: 'center',
119   - width: 200,
120   - //fixed: 'right'
  131 + minWidth: 100,
  132 + maxWidth: 200,
  133 + fixed: 'right'
121 134 }
122 135 ],
123 136 columns2: [
... ... @@ -360,6 +373,7 @@
360 373 {
361 374 title: 'Age',
362 375 key: 'age',
  376 + width:200,
363 377 },
364 378 {
365 379 title: 'Address',
... ... @@ -393,6 +407,34 @@
393 407 date: '2016-10-04'
394 408 }
395 409 ],
  410 +
  411 + columns8: [
  412 + {
  413 + title: 'Date',
  414 + key: 'date',
  415 + sortable: true,
  416 + minWidth:100,
  417 + maxWidth:200,
  418 + },
  419 + {
  420 + title: 'Name',
  421 + key: 'name',
  422 + minWidth:100,
  423 + maxWidth:200,
  424 + },
  425 + {
  426 + title: 'Age',
  427 + key: 'age',
  428 + minWidth:100,
  429 + maxWidth:200,
  430 + },
  431 + {
  432 + title: 'Address',
  433 + key: 'address',
  434 + minWidth:200,
  435 + maxWidth:300,
  436 + }
  437 + ],
396 438 }
397 439 },
398 440 mounted () {
... ...
package.json
... ... @@ -20,6 +20,7 @@
20 20 ],
21 21 "scripts": {
22 22 "dev": "webpack-dev-server --content-base test/ --open --inline --hot --compress --history-api-fallback --port 8081 --config build/webpack.dev.config.js",
  23 + "dev:s": "webpack-dev-server --content-base test/ --open --inline --hot --compress --history-api-fallback --port 8081 --host 0.0.0.0 --config build/webpack.dev.config.js",
23 24 "dist:style": "gulp --gulpfile build/build-style.js",
24 25 "dist:dev": "webpack --config build/webpack.dist.dev.config.js",
25 26 "dist:prod": "webpack --config build/webpack.dist.prod.config.js",
... ...
src/components/table/table.vue
... ... @@ -187,6 +187,8 @@
187 187 objData: this.makeObjData(), // checkbox or highlight-row
188 188 rebuildData: [], // for sort or filter
189 189 cloneColumns: this.makeColumns(),
  190 + minWidthColumns:[],
  191 + maxWidthColumns:[],
190 192 columnRows: this.makeColumnRows(false),
191 193 leftFixedColumnRows: this.makeColumnRows('left'),
192 194 rightFixedColumnRows: this.makeColumnRows('right'),
... ... @@ -194,7 +196,6 @@
194 196 showSlotHeader: true,
195 197 showSlotFooter: true,
196 198 bodyHeight: 0,
197   - bodyRealHeight: 0,
198 199 scrollBarWidth: getScrollBarSize(),
199 200 currentContext: this.context,
200 201 cloneData: deepCopy(this.data), // when Cell has a button to delete row data, clickCurrentRow will throw an error, so clone a data
... ... @@ -251,7 +252,7 @@
251 252 styles () {
252 253 let style = {};
253 254 if (this.height) {
254   - const height = (this.isLeftFixed || this.isRightFixed) ? parseInt(this.height) + this.scrollBarWidth : parseInt(this.height);
  255 + const height = parseInt(this.height);
255 256 style.height = `${height}px`;
256 257 }
257 258 if (this.width) style.width = `${this.width}px`;
... ... @@ -264,11 +265,7 @@
264 265 if (this.bodyHeight === 0) {
265 266 width = this.tableWidth;
266 267 } else {
267   - if (this.bodyHeight > this.bodyRealHeight) {
268   - width = this.tableWidth;
269   - } else {
270   - width = this.tableWidth - (this.showVerticalScrollBar?this.scrollBarWidth:0);
271   - }
  268 + width = this.tableWidth - (this.showVerticalScrollBar?this.scrollBarWidth:0);
272 269 }
273 270 // const width = this.bodyHeight === 0 ? this.tableWidth : this.tableWidth - this.scrollBarWidth;
274 271 style.width = `${width}px`;
... ... @@ -318,8 +315,7 @@
318 315 bodyStyle () {
319 316 let style = {};
320 317 if (this.bodyHeight !== 0) {
321   - // add a height to resolve scroll bug when browser has a scrollBar in fixed type and height prop
322   - const height = (this.isLeftFixed || this.isRightFixed) ? this.bodyHeight + this.scrollBarWidth : this.bodyHeight;
  318 + const height = this.bodyHeight;
323 319 style.height = `${height}px`;
324 320 }
325 321 return style;
... ... @@ -327,15 +323,8 @@
327 323 fixedBodyStyle () {
328 324 let style = {};
329 325 if (this.bodyHeight !== 0) {
330   - let height = this.bodyHeight + (!this.showHorizontalScrollBar?this.scrollBarWidth:0) - 1;
331   -
332   - // #2102 里,如果 Table 没有设置 width,而是集成父级的 width,固定列也应该不包含滚动条高度,所以这里直接计算表格宽度
333   - const tableWidth = parseInt(getStyle(this.$el, 'width')) - 1;
334   - if ((this.width && this.width < this.tableWidth) || tableWidth < this.tableWidth+(this.showVerticalScrollBar?this.scrollBarWidth:0)){
335   - height = this.bodyHeight;
336   - }
337   -// style.height = this.scrollBarWidth > 0 ? `${this.bodyHeight}px` : `${this.bodyHeight - 1}px`;
338   - style.height = this.scrollBarWidth > 0 ? `${height}px` : `${height - 1}px`;
  326 + let height = this.bodyHeight - (this.showHorizontalScrollBar?this.scrollBarWidth:0);
  327 + style.height = this.showHorizontalScrollBar ? `${height}px` : `${height - 1}px`;
339 328 }
340 329 return style;
341 330 },
... ... @@ -357,82 +346,118 @@
357 346 return this.rowClassName(this.data[index], index);
358 347 },
359 348 handleResize () {
360   - this.$nextTick(() => {
361   - const allWidth = !this.allColumns.some(cell => !cell.width); // each column set a width
362   - if (allWidth) {
363   - this.tableWidth = this.allColumns.map(cell => cell.width).reduce((a, b) => a + b, 0);
364   - } else {
365   - this.tableWidth = parseInt(getStyle(this.$el, 'width')) - 1;
366   - }
367   - this.columnsWidth = {};
368   - this.$nextTick(()=>{
369   - this.headerWidth = this.$refs.header.childNodes[0].offsetWidth;
370   - this.headerHeight = this.$refs.header.childNodes[0].offsetHeight;
371   - if (!this.$refs.tbody) {
372   - this.showVerticalScrollBar = false;
373   - return;
374   - }
375   - });
376   - this.$nextTick(() => {
377   - let columnsWidth = {};
378   - let autoWidthIndex = -1;
379   - if (allWidth) autoWidthIndex = this.cloneColumns.findIndex(cell => !cell.width);//todo 这行可能有问题
380   -
381   - if (this.data.length) {
382   - const $tr = this.$refs.tbody.$el.querySelectorAll('tbody tr');
383   - if ($tr.length === 0) return;
384   - const $td = $tr[0].children;
385   - for (let i = 0; i < $td.length; i++) { // can not use forEach in Firefox
386   - const column = this.cloneColumns[i];
387   -
388   - let width = parseInt(getStyle($td[i], 'width'));
389   - if (i === autoWidthIndex) {
390   - width = parseInt(getStyle($td[i], 'width')) - 1;
391   - }
392   - if (column.width) width = column.width;
  349 + //let tableWidth = parseInt(getStyle(this.$el, 'width')) - 1;
  350 + let tableWidth = this.$el.offsetWidth - 1;
  351 + let columnsWidth = {};
  352 +
  353 + let hasWidthColumns = [];
  354 + let noWidthColumns = [];
  355 + let minWidthColumns = this.minWidthColumns;
  356 + let maxWidthColumns = this.maxWidthColumns;
  357 + this.cloneColumns.forEach((col) => {
  358 + if (col.width) {
  359 + hasWidthColumns.push(col);
  360 + }
  361 + else{
  362 + noWidthColumns.push(col);
  363 + }
  364 + col._width = null;
  365 + });
393 366  
394   - this.cloneColumns[i]._width = width;
395 367  
396   - columnsWidth[column._index] = {
397   - width: width
398   - };
  368 + let unUsableWidth = hasWidthColumns.map(cell => cell.width).reduce((a, b) => a + b, 0);
  369 + let usableWidth = tableWidth - unUsableWidth - (this.showVerticalScrollBar?this.scrollBarWidth:0);
  370 + let usableLength = noWidthColumns.length;
  371 + let columnWidth = 0;
  372 + if(usableWidth > 0 && usableLength > 0){
  373 + columnWidth = parseInt(usableWidth / usableLength);
  374 + }
  375 + for (let i = 0; i < maxWidthColumns.length; i++) {
  376 + if(columnWidth > maxWidthColumns[i].maxWidth){
  377 + maxWidthColumns[i]._width = maxWidthColumns[i].maxWidth;
  378 + usableWidth -= maxWidthColumns[i].maxWidth;
  379 + usableLength--;
  380 + if (usableWidth>0) {
  381 + if (usableLength === 0) {
  382 + columnWidth = 0;
  383 + }
  384 + else {
  385 + columnWidth = parseInt(usableWidth / usableLength);
399 386 }
400   - this.columnsWidth = columnsWidth;
401   - this.$nextTick(()=>{
402   - this.fixedHeader();
403   - if (this.$refs.tbody) {
404   - let bodyContentEl = this.$refs.tbody.$el;
405   - let bodyEl = bodyContentEl.parentElement;
406   - let bodyContentHeight = bodyContentEl.offsetHeight;
407   - let bodyContentWidth = bodyContentEl.offsetWidth;
408   - let bodyWidth = bodyEl.offsetWidth;
409   - let bodyHeight = bodyEl.offsetHeight;
410   - let scrollBarWidth = 0;
411   - if (bodyWidth < bodyContentWidth + (bodyHeight<bodyContentHeight?this.scrollBarWidth : 0)) {
412   - scrollBarWidth = this.scrollBarWidth;
413   - }
414   -
415   - this.showVerticalScrollBar = this.bodyHeight? bodyHeight - scrollBarWidth < bodyContentHeight : false;
416   - this.showHorizontalScrollBar = bodyWidth < bodyContentWidth + (this.showVerticalScrollBar?this.scrollBarWidth:0);
417   -
418   - if(this.showVerticalScrollBar){
419   - bodyEl.classList.add(this.prefixCls +'-overflowY');
420   - }else{
421   - bodyEl.classList.remove(this.prefixCls +'-overflowY');
422   - }
423   - if(this.showHorizontalScrollBar){
424   - bodyEl.classList.add(this.prefixCls +'-overflowX');
425   - }else{
426   - bodyEl.classList.remove(this.prefixCls +'-overflowX');
427   - }
  387 + }
  388 + else{
  389 + columnWidth = 0;
  390 + }
  391 + }
  392 + }
428 393  
  394 + for (let i = 0; i < minWidthColumns.length; i++) {
  395 + if(columnWidth < minWidthColumns[i].minWidth && !minWidthColumns[i].width){
  396 + if(!minWidthColumns[i]._width){
  397 + minWidthColumns[i]._width = minWidthColumns[i].minWidth;
  398 + usableWidth -= minWidthColumns[i].minWidth;
  399 + usableLength--;
  400 + if (usableWidth>0) {
  401 + if (usableLength === 0) {
  402 + columnWidth = 0;
429 403 }
430   - });
  404 + else {
  405 + columnWidth = parseInt(usableWidth / usableLength);
  406 + }
  407 + }
  408 + else{
  409 + columnWidth = 0;
  410 + }
431 411 }
432   - });
433   - // get table real height,for fixed when set height prop,but height < table's height,show scrollBarWidth
434   - this.bodyRealHeight = parseInt(getStyle(this.$refs.tbody.$el, 'height'));
435   - });
  412 +
  413 + }
  414 + }
  415 +
  416 +
  417 + for (let i = 0; i < this.cloneColumns.length; i++) {
  418 + const column = this.cloneColumns[i];
  419 + let width = columnWidth;
  420 + if(column.width){
  421 + width = column.width;
  422 + }
  423 + else{
  424 + if (column._width) {
  425 + width = column._width;
  426 + }
  427 + else if (column.minWidth > width){
  428 + width = column.minWidth;
  429 + }
  430 + else if (column.maxWidth < width){
  431 + width = column.maxWidth;
  432 + }
  433 + else {
  434 + if (usableWidth>0) {
  435 + if (usableLength > 1) {
  436 + usableLength--;
  437 + usableWidth -= width;
  438 + columnWidth = parseInt(usableWidth / usableLength);
  439 + }
  440 + else {
  441 + columnWidth = 0;
  442 + }
  443 + }
  444 + else{
  445 + columnWidth = 0;
  446 + }
  447 + }
  448 + }
  449 +
  450 + this.cloneColumns[i]._width = width;
  451 +
  452 + columnsWidth[column._index] = {
  453 + width: width
  454 + };
  455 +
  456 + }
  457 + //this.tableWidth = this.cloneColumns.map(cell => cell._width).reduce((a, b) => a + b, 0);
  458 + this.tableWidth = this.cloneColumns.map(cell => cell._width).reduce((a, b) => a + b, 0) + (this.showVerticalScrollBar?this.scrollBarWidth:0);
  459 + this.columnsWidth = columnsWidth;
  460 + this.fixedHeader();
436 461 },
437 462 handleMouseIn (_index) {
438 463 if (this.disabledHover) return;
... ... @@ -540,11 +565,49 @@
540 565 const headerHeight = parseInt(getStyle(this.$refs.header, 'height')) || 0;
541 566 const footerHeight = parseInt(getStyle(this.$refs.footer, 'height')) || 0;
542 567 this.bodyHeight = this.height - titleHeight - headerHeight - footerHeight;
  568 + this.fixedBody();
543 569 });
544 570 } else {
545 571 this.bodyHeight = 0;
  572 + this.fixedBody();
  573 + }
  574 + },
  575 + fixedBody (){
  576 + if (this.$refs.header) {
  577 + this.headerWidth = this.$refs.header.children[0].offsetWidth;
  578 + this.headerHeight = this.$refs.header.children[0].offsetHeight;
  579 + this.showHorizontalScrollBar = this.headerWidth>this.$refs.header.offsetWidth;
  580 +
  581 + }
  582 +
  583 + if (!this.$refs.tbody || !this.data || this.data.length === 0) {
  584 + this.showVerticalScrollBar = false;
546 585 }
  586 + else{
  587 + let bodyContentEl = this.$refs.tbody.$el;
  588 + let bodyEl = bodyContentEl.parentElement;
  589 + let bodyContentHeight = bodyContentEl.offsetHeight;
  590 + let bodyHeight = bodyEl.offsetHeight;
  591 +
  592 + if (!this.$refs.header) {
  593 + this.showHorizontalScrollBar = bodyEl.offsetWidth < bodyContentEl.offsetWidth + (this.showVerticalScrollBar?this.scrollBarWidth:0);
  594 + }
  595 +
  596 + this.showVerticalScrollBar = this.bodyHeight? bodyHeight - (this.showHorizontalScrollBar?this.scrollBarWidth:0) < bodyContentHeight : false;
  597 +
  598 + if(this.showVerticalScrollBar){
  599 + bodyEl.classList.add(this.prefixCls +'-overflowY');
  600 + }else{
  601 + bodyEl.classList.remove(this.prefixCls +'-overflowY');
  602 + }
  603 + if(this.showHorizontalScrollBar){
  604 + bodyEl.classList.add(this.prefixCls +'-overflowX');
  605 + }else{
  606 + bodyEl.classList.remove(this.prefixCls +'-overflowX');
  607 + }
  608 + }
547 609 },
  610 +
548 611 hideColumnFilter () {
549 612 this.cloneColumns.forEach((col) => col._filterVisible = false);
550 613 },
... ... @@ -809,6 +872,25 @@
809 872 makeColumnRows (fixedType) {
810 873 return convertToRows(this.columns, fixedType);
811 874 },
  875 + setMinMaxColumnRows (){
  876 + let minWidthColumns=[];
  877 + let maxWidthColumns=[];
  878 + this.cloneColumns.forEach((col) => {
  879 + if (!col.width) {
  880 + if(col.minWidth){
  881 + minWidthColumns.push(col);
  882 + }
  883 + if(col.maxWidth){
  884 + maxWidthColumns.push(col);
  885 + }
  886 + }
  887 + });
  888 +
  889 + minWidthColumns.sort((a,b)=>a.minWidth > b.minWidth);
  890 + maxWidthColumns.sort((a,b)=>a.maxWidth < b.maxWidth);
  891 + this.minWidthColumns = minWidthColumns;
  892 + this.maxWidthColumns = maxWidthColumns;
  893 + },
812 894 exportCsv (params) {
813 895 if (params.filename) {
814 896 if (params.filename.indexOf('.csv') === -1) {
... ... @@ -845,7 +927,7 @@
845 927 },
846 928 mounted () {
847 929 this.handleResize();
848   - this.fixedHeader();
  930 + this.setMinMaxColumnRows();
849 931 this.$nextTick(() => this.ready = true);
850 932  
851 933 on(window, 'resize', this.handleResize);
... ... @@ -855,7 +937,6 @@
855 937 this.$on('on-visible-change', (val) => {
856 938 if (val) {
857 939 this.handleResize();
858   - this.fixedHeader();
859 940 }
860 941 });
861 942 },
... ... @@ -885,6 +966,8 @@
885 966 // todo 这里有性能问题,可能是左右固定计算属性影响的
886 967 this.allColumns = getAllColumns(this.columns);
887 968 this.cloneColumns = this.makeColumns();
  969 + this.setMinMaxColumnRows();
  970 +
888 971 this.columnRows = this.makeColumnRows(false);
889 972 this.leftFixedColumnRows = this.makeColumnRows('left');
890 973 this.rightFixedColumnRows = this.makeColumnRows('right');
... ... @@ -895,11 +978,12 @@
895 978 },
896 979 height () {
897 980 this.handleResize();
898   - this.fixedHeader();
899 981 },
900 982 showHorizontalScrollBar () {
901 983 this.handleResize();
902   - this.fixedHeader();
  984 + },
  985 + showVerticalScrollBar () {
  986 + this.handleResize();
903 987 }
904 988 }
905 989 };
... ...