Commit 7f34c510307215cc599a2ba86d638570e16e0fe5

Authored by 梁灏
1 parent 3ef4dfb9

update Table

update Table
src/components/table/cell.vue
... ... @@ -17,7 +17,8 @@
17 17 row: Object,
18 18 column: Object,
19 19 index: Number,
20   - checked: Boolean
  20 + checked: Boolean,
  21 + fixed: Boolean
21 22 },
22 23 data () {
23 24 return {
... ... @@ -30,7 +31,7 @@
30 31 return [
31 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 39 methods: {
39 40 compile () {
40 41 if (this.column.render) {
  42 + const $parent = this.$parent.$parent.$parent;
41 43 const template = this.column.render(this.row, this.column, this.index);
42 44 const cell = document.createElement('div');
43 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 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 53 this.$el.innerHTML = '';
52 54 this.$el.appendChild(cell);
53 55 }
54 56 },
55 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 65 toggleSelect (index) {
63   - this.$parent.toggleSelect(index);
  66 + this.$parent.$parent.toggleSelect(index);
64 67 }
65 68 },
66 69 compiled () {
... ...
src/components/table/table-body.vue
1 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 24 </table>
5 25 </template>
6 26 <script>
  27 + import Cell from './cell.vue';
  28 + import Mixin from './mixin';
  29 +
7 30 export default {
  31 + mixins: [ Mixin ],
  32 + components: { Cell },
8 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 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 59 </script>
24 60 \ No newline at end of file
... ...
src/components/table/table-head.vue
1 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 17 </template>
13 18 <script>
14 19 import Checkbox from '../checkbox/checkbox.vue';
... ... @@ -20,13 +25,10 @@
20 25 components: { Checkbox },
21 26 props: {
22 27 prefixCls: String,
  28 + style: Object,
23 29 columns: Array,
24   - cloneData: Array
25   - },
26   - data () {
27   - return {
28   -
29   - }
  30 + cloneData: Array,
  31 + fixed: Boolean
30 32 },
31 33 computed: {
32 34 isSelectAll () {
... ... @@ -34,6 +36,9 @@
34 36 }
35 37 },
36 38 methods: {
  39 + setCellWidth (column, index) {
  40 + return this.$parent.setCellWidth(column, index);
  41 + },
37 42 renderHeader (column, $index) {
38 43 if ('renderHeader' in this.columns[$index]) {
39 44 return this.columns[$index].renderHeader(column, $index);
... ...
src/components/table/table.vue
... ... @@ -2,70 +2,51 @@
2 2 <div :class="classes" :style="styles">
3 3 <div :class="[prefixCls + '-title']" v-if="showSlotHeader" v-el:title><slot name="header"></slot></div>
4 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 10 </div>
16 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 19 </div>
40 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 29 </div>
52 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 38 </div>
55 39 <div :class="[prefixCls + '-footer']" v-if="showSlotFooter" v-el:footer><slot name="footer"></slot></div>
56 40 </div>
57 41 </template>
58 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 45 import { oneOf, getStyle, deepCopy } from '../../utils/assist';
64 46 const prefixCls = 'ivu-table';
65 47  
66 48 export default {
67   - mixins: [ Mixin ],
68   - components: { TableHead, Checkbox, Cell },
  49 + components: { tableHead, tableBody },
69 50 props: {
70 51 data: {
71 52 type: Array,
... ... @@ -154,6 +135,16 @@
154 135 if (this.tableWidth !== 0) style.width = `${this.tableWidth}px`;
155 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 148 bodyStyle () {
158 149 let style = {};
159 150 if (this.bodyHeight !== 0) style.height = `${this.bodyHeight}px`;
... ... @@ -177,7 +168,7 @@
177 168 let autoWidthIndex = -1;
178 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 172 for (let i = 0; i < $td.length; i++) { // can not use forEach in Firefox
182 173 if (i === autoWidthIndex) {
183 174 this.columnsWidth.push(parseInt(getStyle($td[i], 'width')) - 1);
... ...
src/styles/components/table.less
... ... @@ -189,4 +189,29 @@
189 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 218 \ No newline at end of file
... ...
test/routers/table.vue
... ... @@ -145,7 +145,7 @@
145 145 },
146 146 ready () {
147 147 setTimeout(() => {
148   - return;
  148 +// return;
149 149 // this.height = 150;
150 150 // return
151 151 // this.data.push({
... ...