Commit 7f34c510307215cc599a2ba86d638570e16e0fe5

Authored by 梁灏
1 parent 3ef4dfb9

update Table

update Table
src/components/table/cell.vue
@@ -17,7 +17,8 @@ @@ -17,7 +17,8 @@
17 row: Object, 17 row: Object,
18 column: Object, 18 column: Object,
19 index: Number, 19 index: Number,
20 - checked: Boolean 20 + checked: Boolean,
  21 + fixed: Boolean
21 }, 22 },
22 data () { 23 data () {
23 return { 24 return {
@@ -30,7 +31,7 @@ @@ -30,7 +31,7 @@
30 return [ 31 return [
31 `${this.prefixCls}-cell`, 32 `${this.prefixCls}-cell`,
32 { 33 {
33 - [`${this.prefixCls}-hidden`]: this.column.fixed && (this.column.fixed === 'left' || this.column.fixed === 'right') 34 + [`${this.prefixCls}-hidden`]: !this.fixed && this.column.fixed && (this.column.fixed === 'left' || this.column.fixed === 'right')
34 } 35 }
35 ] 36 ]
36 } 37 }
@@ -38,29 +39,31 @@ @@ -38,29 +39,31 @@
38 methods: { 39 methods: {
39 compile () { 40 compile () {
40 if (this.column.render) { 41 if (this.column.render) {
  42 + const $parent = this.$parent.$parent.$parent;
41 const template = this.column.render(this.row, this.column, this.index); 43 const template = this.column.render(this.row, this.column, this.index);
42 const cell = document.createElement('div'); 44 const cell = document.createElement('div');
43 cell.innerHTML = template; 45 cell.innerHTML = template;
44 - const _oldParentChildLen = this.$parent.$parent.$children.length;  
45 - this.$parent.$parent.$compile(cell);  
46 - const _newParentChildLen = this.$parent.$parent.$children.length; 46 + const _oldParentChildLen = $parent.$children.length;
  47 + $parent.$compile(cell);
  48 + const _newParentChildLen = $parent.$children.length;
47 49
48 if (_oldParentChildLen !== _newParentChildLen) { // if render normal html node, do not tag 50 if (_oldParentChildLen !== _newParentChildLen) { // if render normal html node, do not tag
49 - this.uid = this.$parent.$parent.$children[this.$parent.$parent.$children.length - 1]._uid; // tag it, and delete when data or columns update 51 + this.uid = $parent.$children[$parent.$children.length - 1]._uid; // tag it, and delete when data or columns update
50 } 52 }
51 this.$el.innerHTML = ''; 53 this.$el.innerHTML = '';
52 this.$el.appendChild(cell); 54 this.$el.appendChild(cell);
53 } 55 }
54 }, 56 },
55 destroy () { 57 destroy () {
56 - for (let i = 0; i < this.$parent.$parent.$children.length; i++) {  
57 - if (this.$parent.$parent.$children[i]._uid === this.uid) {  
58 - this.$parent.$parent.$children[i].$destroy(); 58 + const $parent = this.$parent.$parent.$parent;
  59 + for (let i = 0; i < $parent.$children.length; i++) {
  60 + if ($parent.$children[i]._uid === this.uid) {
  61 + $parent.$children[i].$destroy();
59 } 62 }
60 } 63 }
61 }, 64 },
62 toggleSelect (index) { 65 toggleSelect (index) {
63 - this.$parent.toggleSelect(index); 66 + this.$parent.$parent.toggleSelect(index);
64 } 67 }
65 }, 68 },
66 compiled () { 69 compiled () {
src/components/table/table-body.vue
1 <template> 1 <template>
2 - <table cellspacing="0" cellpadding="0" border="0">  
3 - 2 + <table cellspacing="0" cellpadding="0" border="0" :style="style">
  3 + <colgroup>
  4 + <col v-for="column in columns" :width="setCellWidth(column, $index)">
  5 + </colgroup>
  6 + <tbody :class="[prefixCls + '-tbody']">
  7 + <tr
  8 + v-for="(index, row) in data"
  9 + :class="[prefixCls + '-row', rowClsName(index), {[prefixCls + '-row-highlight']: cloneData[index] && cloneData[index]._isHighlight, [prefixCls + '-row-hover']: cloneData[index] && cloneData[index]._isHover}]"
  10 + @mouseenter.stop="handleMouseIn(index)"
  11 + @mouseleave.stop="handleMouseOut(index)"
  12 + @click.stop="highlightCurrentRow(index)">
  13 + <td v-for="column in columns" :class="alignCls(column)">
  14 + <Cell
  15 + :fixed="fixed"
  16 + :prefix-cls="prefixCls"
  17 + :row="row"
  18 + :column="column"
  19 + :index="index"
  20 + :checked="cloneData[index] && cloneData[index]._isChecked"></Cell>
  21 + </td>
  22 + </tr>
  23 + </tbody>
4 </table> 24 </table>
5 </template> 25 </template>
6 <script> 26 <script>
  27 + import Cell from './cell.vue';
  28 + import Mixin from './mixin';
  29 +
7 export default { 30 export default {
  31 + mixins: [ Mixin ],
  32 + components: { Cell },
8 props: { 33 props: {
9 -  
10 - },  
11 - data () {  
12 - return {  
13 -  
14 - }  
15 - },  
16 - computed: {  
17 - 34 + prefixCls: String,
  35 + style: Object,
  36 + columns: Array,
  37 + data: Array,
  38 + cloneData: Array,
  39 + fixed: Boolean
18 }, 40 },
19 methods: { 41 methods: {
20 - 42 + setCellWidth (column, index) {
  43 + return this.$parent.setCellWidth(column, index);
  44 + },
  45 + rowClsName (index) {
  46 + return this.$parent.rowClassName(this.data[index], index);
  47 + },
  48 + handleMouseIn (index) {
  49 + this.$parent.handleMouseIn(index);
  50 + },
  51 + handleMouseOut (index) {
  52 + this.$parent.handleMouseOut(index);
  53 + },
  54 + highlightCurrentRow (index) {
  55 + this.$parent.highlightCurrentRow(index);
  56 + }
21 } 57 }
22 } 58 }
23 </script> 59 </script>
24 \ No newline at end of file 60 \ No newline at end of file
src/components/table/table-head.vue
1 <template> 1 <template>
2 - <thead>  
3 - <tr>  
4 - <th v-for="column in columns" :class="alignCls(column)">  
5 - <div :class="[prefixCls + '-cell', {[prefixCls + '-hidden']: column.fixed && (column.fixed === 'left' || column.fixed === 'right')}]">  
6 - <template v-if="column.type === 'selection'"><Checkbox :checked="isSelectAll" @on-change="selectAll"></Checkbox></template>  
7 - <template v-else>{{{ renderHeader(column, $index) }}}</template>  
8 - </div>  
9 - </th>  
10 - </tr>  
11 - </thead> 2 + <table cellspacing="0" cellpadding="0" border="0" :style="style">
  3 + <colgroup>
  4 + <col v-for="column in columns" :width="setCellWidth(column, $index)">
  5 + </colgroup>
  6 + <thead>
  7 + <tr>
  8 + <th v-for="column in columns" :class="alignCls(column)">
  9 + <div :class="[prefixCls + '-cell', {[prefixCls + '-hidden']: !fixed && column.fixed && (column.fixed === 'left' || column.fixed === 'right')}]">
  10 + <template v-if="column.type === 'selection'"><Checkbox :checked="isSelectAll" @on-change="selectAll"></Checkbox></template>
  11 + <template v-else>{{{ renderHeader(column, $index) }}}</template>
  12 + </div>
  13 + </th>
  14 + </tr>
  15 + </thead>
  16 + </table>
12 </template> 17 </template>
13 <script> 18 <script>
14 import Checkbox from '../checkbox/checkbox.vue'; 19 import Checkbox from '../checkbox/checkbox.vue';
@@ -20,13 +25,10 @@ @@ -20,13 +25,10 @@
20 components: { Checkbox }, 25 components: { Checkbox },
21 props: { 26 props: {
22 prefixCls: String, 27 prefixCls: String,
  28 + style: Object,
23 columns: Array, 29 columns: Array,
24 - cloneData: Array  
25 - },  
26 - data () {  
27 - return {  
28 -  
29 - } 30 + cloneData: Array,
  31 + fixed: Boolean
30 }, 32 },
31 computed: { 33 computed: {
32 isSelectAll () { 34 isSelectAll () {
@@ -34,6 +36,9 @@ @@ -34,6 +36,9 @@
34 } 36 }
35 }, 37 },
36 methods: { 38 methods: {
  39 + setCellWidth (column, index) {
  40 + return this.$parent.setCellWidth(column, index);
  41 + },
37 renderHeader (column, $index) { 42 renderHeader (column, $index) {
38 if ('renderHeader' in this.columns[$index]) { 43 if ('renderHeader' in this.columns[$index]) {
39 return this.columns[$index].renderHeader(column, $index); 44 return this.columns[$index].renderHeader(column, $index);
src/components/table/table.vue
@@ -2,70 +2,51 @@ @@ -2,70 +2,51 @@
2 <div :class="classes" :style="styles"> 2 <div :class="classes" :style="styles">
3 <div :class="[prefixCls + '-title']" v-if="showSlotHeader" v-el:title><slot name="header"></slot></div> 3 <div :class="[prefixCls + '-title']" v-if="showSlotHeader" v-el:title><slot name="header"></slot></div>
4 <div :class="[prefixCls + '-header']" v-if="showHeader" v-el:header @mousewheel="handleMouseWheel"> 4 <div :class="[prefixCls + '-header']" v-if="showHeader" v-el:header @mousewheel="handleMouseWheel">
5 - <table cellspacing="0" cellpadding="0" border="0" :style="tableStyle">  
6 - <colgroup>  
7 - <col v-for="column in cloneColumns" :width="setCellWidth(column, $index)">  
8 - </colgroup>  
9 - <thead  
10 - is="table-head"  
11 - :prefix-cls="prefixCls"  
12 - :clone-data.sync="cloneData"  
13 - :columns="cloneColumns"></thead>  
14 - </table> 5 + <table-head
  6 + :prefix-cls="prefixCls"
  7 + :style="tableStyle"
  8 + :columns="cloneColumns"
  9 + :clone-data="cloneData"></table-head>
15 </div> 10 </div>
16 <div :class="[prefixCls + '-body']" :style="bodyStyle" v-el:body @scroll="handleBodyScroll"> 11 <div :class="[prefixCls + '-body']" :style="bodyStyle" v-el:body @scroll="handleBodyScroll">
17 - <table cellspacing="0" cellpadding="0" border="0" :style="tableStyle" v-el:tbody>  
18 - <colgroup>  
19 - <col v-for="column in cloneColumns" :width="setCellWidth(column, $index)">  
20 - </colgroup>  
21 - <tbody :class="[prefixCls + '-tbody']" v-el:render>  
22 - <tr  
23 - v-for="(index, row) in data"  
24 - :class="[prefixCls + '-row', rowClsName(index), {[prefixCls + '-row-highlight']: cloneData[index] && cloneData[index]._isHighlight, [prefixCls + '-row-hover']: cloneData[index] && cloneData[index]._isHover}]"  
25 - @mouseenter.stop="handleMouseIn(index)"  
26 - @mouseleave.stop="handleMouseOut(index)"  
27 - @click.stop="highlightCurrentRow(index)">  
28 - <td v-for="column in cloneColumns" :class="alignCls(column)">  
29 - <Cell  
30 - :prefix-cls="prefixCls"  
31 - :row="row"  
32 - :column="column"  
33 - :index="index"  
34 - :checked="cloneData[index] && cloneData[index]._isChecked"></Cell>  
35 - </td>  
36 - </tr>  
37 - </tbody>  
38 - </table> 12 + <table-body
  13 + v-ref:tbody
  14 + :prefix-cls="prefixCls"
  15 + :style="tableStyle"
  16 + :columns="cloneColumns"
  17 + :data="data"
  18 + :clone-data="cloneData"></table-body>
39 </div> 19 </div>
40 <div :class="[prefixCls + '-fixed']"> 20 <div :class="[prefixCls + '-fixed']">
41 - <table cellspacing="0" cellpadding="0" border="0">  
42 - <colgroup>  
43 - <col v-for="column in leftFixedColumns" :width="setCellWidth(column, $index)">  
44 - </colgroup>  
45 - <tbody :class="[prefixCls + '-tbody']">  
46 - <tr>  
47 -  
48 - </tr>  
49 - </tbody>  
50 - </table> 21 + <!--todo设置个div头部-->
  22 + <table-body
  23 + fixed
  24 + :prefix-cls="prefixCls"
  25 + :style="fixedTableStyle"
  26 + :columns="leftFixedColumns"
  27 + :data="data"
  28 + :clone-data="cloneData"></table-body>
51 </div> 29 </div>
52 <div :class="[prefixCls + '-fixed-right']"> 30 <div :class="[prefixCls + '-fixed-right']">
53 - 31 + <table-body
  32 + fixed
  33 + :prefix-cls="prefixCls"
  34 + :style="fixedRightTableStyle"
  35 + :columns="rightFixedColumns"
  36 + :data="data"
  37 + :clone-data="cloneData"></table-body>
54 </div> 38 </div>
55 <div :class="[prefixCls + '-footer']" v-if="showSlotFooter" v-el:footer><slot name="footer"></slot></div> 39 <div :class="[prefixCls + '-footer']" v-if="showSlotFooter" v-el:footer><slot name="footer"></slot></div>
56 </div> 40 </div>
57 </template> 41 </template>
58 <script> 42 <script>
59 - import TableHead from './table-head.vue';  
60 - import Checkbox from '../checkbox/checkbox.vue';  
61 - import Cell from './cell.vue';  
62 - import Mixin from './mixin'; 43 + import tableHead from './table-head.vue';
  44 + import tableBody from './table-body.vue';
63 import { oneOf, getStyle, deepCopy } from '../../utils/assist'; 45 import { oneOf, getStyle, deepCopy } from '../../utils/assist';
64 const prefixCls = 'ivu-table'; 46 const prefixCls = 'ivu-table';
65 47
66 export default { 48 export default {
67 - mixins: [ Mixin ],  
68 - components: { TableHead, Checkbox, Cell }, 49 + components: { tableHead, tableBody },
69 props: { 50 props: {
70 data: { 51 data: {
71 type: Array, 52 type: Array,
@@ -154,6 +135,16 @@ @@ -154,6 +135,16 @@
154 if (this.tableWidth !== 0) style.width = `${this.tableWidth}px`; 135 if (this.tableWidth !== 0) style.width = `${this.tableWidth}px`;
155 return style; 136 return style;
156 }, 137 },
  138 + fixedTableStyle () {
  139 + let style = {};
  140 + if (this.leftFixedColumns.length) style.width = this.leftFixedColumns.reduce((a, b) => a + b);
  141 + return style;
  142 + },
  143 + fixedRightTableStyle () {
  144 + let style = {};
  145 + if (this.rightFixedColumns.length) style.width = this.rightFixedColumns.reduce((a, b) => a + b);
  146 + return style;
  147 + },
157 bodyStyle () { 148 bodyStyle () {
158 let style = {}; 149 let style = {};
159 if (this.bodyHeight !== 0) style.height = `${this.bodyHeight}px`; 150 if (this.bodyHeight !== 0) style.height = `${this.bodyHeight}px`;
@@ -177,7 +168,7 @@ @@ -177,7 +168,7 @@
177 let autoWidthIndex = -1; 168 let autoWidthIndex = -1;
178 if (allWidth) autoWidthIndex = this.cloneColumns.findIndex(cell => !cell.width); 169 if (allWidth) autoWidthIndex = this.cloneColumns.findIndex(cell => !cell.width);
179 170
180 - const $td = this.$els.tbody.querySelectorAll('tbody tr')[0].querySelectorAll('td'); 171 + const $td = this.$refs.tbody.$el.querySelectorAll('tbody tr')[0].querySelectorAll('td');
181 for (let i = 0; i < $td.length; i++) { // can not use forEach in Firefox 172 for (let i = 0; i < $td.length; i++) { // can not use forEach in Firefox
182 if (i === autoWidthIndex) { 173 if (i === autoWidthIndex) {
183 this.columnsWidth.push(parseInt(getStyle($td[i], 'width')) - 1); 174 this.columnsWidth.push(parseInt(getStyle($td[i], 'width')) - 1);
src/styles/components/table.less
@@ -189,4 +189,29 @@ @@ -189,4 +189,29 @@
189 background-color: @table-td-highlight-bg; 189 background-color: @table-td-highlight-bg;
190 } 190 }
191 } 191 }
  192 +
  193 + &-fixed, &-fixed-right{
  194 + position: absolute;
  195 + top: 0;
  196 + left: 0;
  197 + box-shadow: 1px 0 8px #d3d4d6;
  198 + overflow-x: hidden;
  199 +
  200 + &::before {
  201 + content: '';
  202 + width: 100%;
  203 + height: 1px;
  204 + background-color: @border-color-base;
  205 + position: absolute;
  206 + left: 0;
  207 + bottom: 0;
  208 + z-index: 4;
  209 + }
  210 + }
  211 + &-fixed-right{
  212 + top: 0;
  213 + left: auto;
  214 + right: 0;
  215 + box-shadow: -1px 0 8px #d3d4d6;
  216 + }
192 } 217 }
193 \ No newline at end of file 218 \ No newline at end of file
test/routers/table.vue
@@ -145,7 +145,7 @@ @@ -145,7 +145,7 @@
145 }, 145 },
146 ready () { 146 ready () {
147 setTimeout(() => { 147 setTimeout(() => {
148 - return; 148 +// return;
149 // this.height = 150; 149 // this.height = 150;
150 // return 150 // return
151 // this.data.push({ 151 // this.data.push({