Commit 0d13646576cd1ce46e506c5bd7e1fd1a3d24c72f
1 parent
744eb0af
update Table
update Table
Showing
7 changed files
with
304 additions
and
57 deletions
Show diff stats
src/components/table/table-head.vue
| 1 | <template> | 1 | <template> |
| 2 | <thead> | 2 | <thead> |
| 3 | <tr> | 3 | <tr> |
| 4 | - <th v-for="column in columns" :class="fixedCls(column)">{{{ renderHeader(column, $index) }}}</th> | 4 | + <th v-for="column in columns" :class="alignCls(column)"> |
| 5 | + <div :class="[prefixCls + '-cell']"> | ||
| 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> | ||
| 5 | </tr> | 10 | </tr> |
| 6 | </thead> | 11 | </thead> |
| 7 | </template> | 12 | </template> |
| 8 | <script> | 13 | <script> |
| 14 | + import Checkbox from '../checkbox/checkbox.vue'; | ||
| 15 | + import Mixin from './mixin'; | ||
| 16 | + import { deepCopy } from '../../utils/assist'; | ||
| 17 | + | ||
| 9 | export default { | 18 | export default { |
| 19 | + mixins: [ Mixin ], | ||
| 20 | + components: { Checkbox }, | ||
| 10 | props: { | 21 | props: { |
| 11 | prefixCls: String, | 22 | prefixCls: String, |
| 12 | - columns: Array | 23 | + columns: Array, |
| 24 | + cloneData: Array | ||
| 13 | }, | 25 | }, |
| 14 | data () { | 26 | data () { |
| 15 | return { | 27 | return { |
| @@ -17,7 +29,9 @@ | @@ -17,7 +29,9 @@ | ||
| 17 | } | 29 | } |
| 18 | }, | 30 | }, |
| 19 | computed: { | 31 | computed: { |
| 20 | - | 32 | + isSelectAll () { |
| 33 | + return !this.cloneData.some(data => !data._isChecked); | ||
| 34 | + } | ||
| 21 | }, | 35 | }, |
| 22 | methods: { | 36 | methods: { |
| 23 | renderHeader (column, $index) { | 37 | renderHeader (column, $index) { |
| @@ -27,8 +41,18 @@ | @@ -27,8 +41,18 @@ | ||
| 27 | return column.title || '#'; | 41 | return column.title || '#'; |
| 28 | } | 42 | } |
| 29 | }, | 43 | }, |
| 30 | - fixedCls (column) { | ||
| 31 | - return column.fixed ? `${this.prefixCls}-${column.fixed}` : ''; | 44 | + selectAll () { |
| 45 | + const status = !this.isSelectAll; | ||
| 46 | + | ||
| 47 | + let tmpData = deepCopy(this.cloneData); | ||
| 48 | + tmpData.forEach((data) => { | ||
| 49 | + data._isChecked = status; | ||
| 50 | + }); | ||
| 51 | + this.cloneData = tmpData; | ||
| 52 | + | ||
| 53 | + if (status) { | ||
| 54 | + this.$parent.selectAll(); | ||
| 55 | + } | ||
| 32 | } | 56 | } |
| 33 | } | 57 | } |
| 34 | } | 58 | } |
src/components/table/table.vue
| 1 | <template> | 1 | <template> |
| 2 | <div :class="classes"> | 2 | <div :class="classes"> |
| 3 | - <div :class="[prefixCls + '-header']"> | ||
| 4 | - <table cellspacing="0" cellpadding="0" border="0" :style="{width: tableWidth + 'px'}"> | 3 | + <div :class="[prefixCls + '-header']" v-if="showHeader"> |
| 4 | + <table cellspacing="0" cellpadding="0" border="0" :style="tableStyle"> | ||
| 5 | <colgroup> | 5 | <colgroup> |
| 6 | <col v-for="column in columns" :width="setCellWidth(column, $index)"> | 6 | <col v-for="column in columns" :width="setCellWidth(column, $index)"> |
| 7 | </colgroup> | 7 | </colgroup> |
| 8 | <thead | 8 | <thead |
| 9 | is="table-head" | 9 | is="table-head" |
| 10 | - :prefix-cls="prefixCls + '-thead'" | 10 | + :prefix-cls="prefixCls" |
| 11 | + :clone-data.sync="cloneData" | ||
| 11 | :columns="columns"></thead> | 12 | :columns="columns"></thead> |
| 12 | </table> | 13 | </table> |
| 13 | </div> | 14 | </div> |
| 14 | <div :class="[prefixCls + '-body']"> | 15 | <div :class="[prefixCls + '-body']"> |
| 15 | - <table cellspacing="0" cellpadding="0" border="0" :style="{width: tableWidth + 'px'}" v-el:tbody> | 16 | + <table cellspacing="0" cellpadding="0" border="0" :style="tableStyle" v-el:tbody> |
| 16 | <colgroup> | 17 | <colgroup> |
| 17 | <col v-for="column in columns" :width="setCellWidth(column, $index)"> | 18 | <col v-for="column in columns" :width="setCellWidth(column, $index)"> |
| 18 | </colgroup> | 19 | </colgroup> |
| 19 | <tbody :class="[prefixCls + '-tbody']" v-el:render> | 20 | <tbody :class="[prefixCls + '-tbody']" v-el:render> |
| 20 | - <tr :class="[prefixCls + '-row']" v-for="(index, row) in data"> | ||
| 21 | - <td v-for="column in columns">{{{ renderRow(row, column) }}}</td> | 21 | + <tr |
| 22 | + v-for="(index, row) in data" | ||
| 23 | + :class="[prefixCls + '-row', {[prefixCls + '-row-highlight']: cloneData[index] && cloneData[index]._isHighlight}]" | ||
| 24 | + @click.stop="highlightCurrentRow(index)"> | ||
| 25 | + <td v-for="column in columns" :class="alignCls(column)"> | ||
| 26 | + <div :class="[prefixCls + '-cell']"> | ||
| 27 | + <template v-if="column.type === 'selection'"> | ||
| 28 | + <Checkbox :checked="cloneData[index] && cloneData[index]._isChecked" @on-change="toggleSelect(index)"></Checkbox> | ||
| 29 | + </template> | ||
| 30 | + <template v-else>{{{ renderRow(row, column, index) }}}</template> | ||
| 31 | + </div> | ||
| 32 | + </td> | ||
| 22 | </tr> | 33 | </tr> |
| 23 | </tbody> | 34 | </tbody> |
| 24 | </table> | 35 | </table> |
| @@ -27,11 +38,14 @@ | @@ -27,11 +38,14 @@ | ||
| 27 | </template> | 38 | </template> |
| 28 | <script> | 39 | <script> |
| 29 | import TableHead from './table-head.vue'; | 40 | import TableHead from './table-head.vue'; |
| 30 | - import { oneOf, getStyle } from '../../utils/assist'; | 41 | + import Checkbox from '../checkbox/checkbox.vue'; |
| 42 | + import Mixin from './mixin'; | ||
| 43 | + import { oneOf, getStyle, deepCopy } from '../../utils/assist'; | ||
| 31 | const prefixCls = 'ivu-table'; | 44 | const prefixCls = 'ivu-table'; |
| 32 | 45 | ||
| 33 | export default { | 46 | export default { |
| 34 | - components: { TableHead }, | 47 | + mixins: [ Mixin ], |
| 48 | + components: { TableHead, Checkbox }, | ||
| 35 | props: { | 49 | props: { |
| 36 | data: { | 50 | data: { |
| 37 | type: Array, | 51 | type: Array, |
| @@ -58,21 +72,11 @@ | @@ -58,21 +72,11 @@ | ||
| 58 | type: Boolean, | 72 | type: Boolean, |
| 59 | default: false | 73 | default: false |
| 60 | }, | 74 | }, |
| 61 | - fit: { | ||
| 62 | - type: Boolean, | ||
| 63 | - default: true | ||
| 64 | - }, | ||
| 65 | showHeader: { | 75 | showHeader: { |
| 66 | type: Boolean, | 76 | type: Boolean, |
| 67 | default: true | 77 | default: true |
| 68 | }, | 78 | }, |
| 69 | - selection: { | ||
| 70 | - validator (value) { | ||
| 71 | - return oneOf(value, ['single', 'multiple', false]); | ||
| 72 | - }, | ||
| 73 | - default: false | ||
| 74 | - }, | ||
| 75 | - showIndex: { | 79 | + highlightRow: { |
| 76 | type: Boolean, | 80 | type: Boolean, |
| 77 | default: false | 81 | default: false |
| 78 | } | 82 | } |
| @@ -82,7 +86,8 @@ | @@ -82,7 +86,8 @@ | ||
| 82 | tableWidth: 0, | 86 | tableWidth: 0, |
| 83 | columnsWidth: [], | 87 | columnsWidth: [], |
| 84 | prefixCls: prefixCls, | 88 | prefixCls: prefixCls, |
| 85 | - compiledUids: [] | 89 | + compiledUids: [], |
| 90 | + cloneData: deepCopy(this.data) | ||
| 86 | } | 91 | } |
| 87 | }, | 92 | }, |
| 88 | computed: { | 93 | computed: { |
| @@ -90,14 +95,21 @@ | @@ -90,14 +95,21 @@ | ||
| 90 | return [ | 95 | return [ |
| 91 | `${prefixCls}`, | 96 | `${prefixCls}`, |
| 92 | { | 97 | { |
| 93 | - [`${prefixCls}-${this.size}`]: !!this.size | 98 | + [`${prefixCls}-${this.size}`]: !!this.size, |
| 99 | + [`${prefixCls}-border`]: this.border, | ||
| 100 | + [`${prefixCls}-stripe`]: this.stripe | ||
| 94 | } | 101 | } |
| 95 | ] | 102 | ] |
| 103 | + }, | ||
| 104 | + tableStyle () { | ||
| 105 | + let style = {}; | ||
| 106 | + if (this.tableWidth !== 0) style.width = `${this.tableWidth}px`; | ||
| 107 | + return style; | ||
| 96 | } | 108 | } |
| 97 | }, | 109 | }, |
| 98 | methods: { | 110 | methods: { |
| 99 | - renderRow (row, column) { | ||
| 100 | - return 'render' in column ? '' : row[column.key]; | 111 | + renderRow (row, column, index) { |
| 112 | + return column.type === 'index' ? index + 1 : column.render ? '' : row[column.key]; | ||
| 101 | }, | 113 | }, |
| 102 | compileRender (update = false) { | 114 | compileRender (update = false) { |
| 103 | this.$nextTick(() => { | 115 | this.$nextTick(() => { |
| @@ -117,7 +129,7 @@ | @@ -117,7 +129,7 @@ | ||
| 117 | const column = this.columns[i]; | 129 | const column = this.columns[i]; |
| 118 | if (column.render) { | 130 | if (column.render) { |
| 119 | for (let j = 0; j < this.data.length; j++) { | 131 | for (let j = 0; j < this.data.length; j++) { |
| 120 | - // todo 做一个缓存,只在需要改render时再重新编译,否则data改变时不用再编译 | 132 | + // todo 做一个缓存,只在需要改render时再重新编译,data改变时不用再编译 |
| 121 | const row = this.data[j]; | 133 | const row = this.data[j]; |
| 122 | const template = column.render(row, column, j); | 134 | const template = column.render(row, column, j); |
| 123 | const cell = document.createElement('div'); | 135 | const cell = document.createElement('div'); |
| @@ -129,8 +141,8 @@ | @@ -129,8 +141,8 @@ | ||
| 129 | if (_oldParentChildLen !== _newParentChildLen) { // if render normal html node, do not tag | 141 | if (_oldParentChildLen !== _newParentChildLen) { // if render normal html node, do not tag |
| 130 | this.compiledUids.push(this.$parent.$children[this.$parent.$children.length - 1]._uid); // tag it, and delete when data or columns update | 142 | this.compiledUids.push(this.$parent.$children[this.$parent.$children.length - 1]._uid); // tag it, and delete when data or columns update |
| 131 | } | 143 | } |
| 132 | - $el.children[j].children[i].innerHTML = ''; | ||
| 133 | - $el.children[j].children[i].appendChild(cell); | 144 | + $el.children[j].children[i].children[0].innerHTML = ''; |
| 145 | + $el.children[j].children[i].children[0].appendChild(cell); | ||
| 134 | } | 146 | } |
| 135 | } | 147 | } |
| 136 | } | 148 | } |
| @@ -148,6 +160,49 @@ | @@ -148,6 +160,49 @@ | ||
| 148 | }, | 160 | }, |
| 149 | setCellWidth (column, index) { | 161 | setCellWidth (column, index) { |
| 150 | return column.width ? column.width : this.columnsWidth[index]; | 162 | return column.width ? column.width : this.columnsWidth[index]; |
| 163 | + }, | ||
| 164 | + highlightCurrentRow (index) { | ||
| 165 | + if (!this.highlightRow || this.cloneData[index]._isHighlight) return; | ||
| 166 | + | ||
| 167 | + let oldIndex = -1; | ||
| 168 | + this.cloneData.forEach((item, index) => { | ||
| 169 | + if (item._isHighlight) { | ||
| 170 | + oldIndex = index; | ||
| 171 | + item._isHighlight = false; | ||
| 172 | + return true; | ||
| 173 | + } | ||
| 174 | + }); | ||
| 175 | + const row = Object.assign({}, this.cloneData[index], { | ||
| 176 | + _isHighlight: true | ||
| 177 | + }); | ||
| 178 | + this.cloneData.$set(index, row); | ||
| 179 | + | ||
| 180 | + const oldData = oldIndex < 0 ? null : JSON.parse(JSON.stringify(this.data[oldIndex])); | ||
| 181 | + this.$emit('on-current-change', JSON.parse(JSON.stringify(this.data[index])), oldData); | ||
| 182 | + }, | ||
| 183 | + getSelection () { | ||
| 184 | + let selectionIndexes = []; | ||
| 185 | + this.cloneData.forEach((data, index) => { | ||
| 186 | + if (data._isChecked) selectionIndexes.push(index); | ||
| 187 | + }); | ||
| 188 | + | ||
| 189 | + return JSON.parse(JSON.stringify(this.data.filter((data, index) => selectionIndexes.indexOf(index) > -1))); | ||
| 190 | + }, | ||
| 191 | + toggleSelect (index) { | ||
| 192 | + const status = !this.cloneData[index]._isChecked; | ||
| 193 | + const row = Object.assign({}, this.cloneData[index], { | ||
| 194 | + _isChecked: status | ||
| 195 | + }); | ||
| 196 | + this.cloneData.$set(index, row); | ||
| 197 | + | ||
| 198 | + const selection = this.getSelection(); | ||
| 199 | + if (status) { | ||
| 200 | + this.$emit('on-select', selection, JSON.parse(JSON.stringify(this.data[index]))); | ||
| 201 | + } | ||
| 202 | + this.$emit('on-selection-change', selection); | ||
| 203 | + }, | ||
| 204 | + selectAll () { | ||
| 205 | + this.$emit('on-select-all', this.getSelection()); | ||
| 151 | } | 206 | } |
| 152 | }, | 207 | }, |
| 153 | ready () { | 208 | ready () { |
| @@ -160,6 +215,7 @@ | @@ -160,6 +215,7 @@ | ||
| 160 | watch: { | 215 | watch: { |
| 161 | data: { | 216 | data: { |
| 162 | handler () { | 217 | handler () { |
| 218 | + this.cloneData = deepCopy(this.data); | ||
| 163 | this.compileRender(true); | 219 | this.compileRender(true); |
| 164 | }, | 220 | }, |
| 165 | deep: true | 221 | deep: true |
src/styles/components/table.less
| 1 | @table-prefix-cls: ~"@{css-prefix}table"; | 1 | @table-prefix-cls: ~"@{css-prefix}table"; |
| 2 | 2 | ||
| 3 | .@{table-prefix-cls} { | 3 | .@{table-prefix-cls} { |
| 4 | - position: relative; | ||
| 5 | - overflow: hidden; | ||
| 6 | - box-sizing: border-box; | 4 | + width: 100%; |
| 7 | max-width: 100%; | 5 | max-width: 100%; |
| 8 | - background-color: #fff; | ||
| 9 | - border-collapse: collapse; | ||
| 10 | - border: 1px solid @border-color-base; | 6 | + overflow: hidden; |
| 11 | color: @text-color; | 7 | color: @text-color; |
| 12 | font-size: @font-size-small; | 8 | font-size: @font-size-small; |
| 9 | + background-color: #fff; | ||
| 10 | + border: 1px solid @border-color-base; | ||
| 11 | + border-bottom: 0; | ||
| 12 | + border-collapse: collapse; | ||
| 13 | + box-sizing: border-box; | ||
| 14 | + position: relative; | ||
| 13 | 15 | ||
| 14 | - &-large { | ||
| 15 | - font-size: @font-size-base; | 16 | + th, td |
| 17 | + { | ||
| 18 | + min-width: 0; | ||
| 19 | + height: 48px; | ||
| 20 | + box-sizing: border-box; | ||
| 21 | + text-align: left; | ||
| 22 | + text-overflow: ellipsis; | ||
| 23 | + vertical-align: middle; | ||
| 24 | + position: relative; | ||
| 25 | + border-bottom: 1px solid @border-color-split; | ||
| 16 | } | 26 | } |
| 17 | 27 | ||
| 18 | - & th { | 28 | + th { |
| 29 | + height: 40px; | ||
| 19 | white-space: nowrap; | 30 | white-space: nowrap; |
| 20 | overflow: hidden; | 31 | overflow: hidden; |
| 32 | + background-color: @table-thead-bg; | ||
| 33 | + } | ||
| 34 | + td{ | ||
| 35 | + background-color: #fff; | ||
| 36 | + transition: background-color @transition-time @ease-in-out; | ||
| 21 | } | 37 | } |
| 22 | 38 | ||
| 23 | - & th, | ||
| 24 | - td | 39 | + th&-column, |
| 40 | + td&-column | ||
| 25 | { | 41 | { |
| 26 | - min-width: 0; | ||
| 27 | - height: 40px; | ||
| 28 | - box-sizing: border-box; | ||
| 29 | - text-align: left; | 42 | + &-left{ |
| 43 | + text-align: left; | ||
| 44 | + } | ||
| 45 | + &-center{ | ||
| 46 | + text-align: center; | ||
| 47 | + } | ||
| 48 | + &-right{ | ||
| 49 | + text-align: right; | ||
| 50 | + } | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + & table{ | ||
| 54 | + width: 100%; | ||
| 55 | + } | ||
| 56 | + &-border{ | ||
| 57 | + th,td{ | ||
| 58 | + border-right: 1px solid @border-color-split; | ||
| 59 | + } | ||
| 60 | + } | ||
| 61 | + &-cell{ | ||
| 62 | + padding-left: 18px; | ||
| 63 | + padding-right: 18px; | ||
| 64 | + overflow: hidden; | ||
| 30 | text-overflow: ellipsis; | 65 | text-overflow: ellipsis; |
| 31 | - vertical-align: middle; | 66 | + white-space: normal; |
| 67 | + word-break: break-all; | ||
| 68 | + box-sizing: border-box; | ||
| 69 | + } | ||
| 70 | + th &-cell{ | ||
| 71 | + display: inline-block; | ||
| 32 | position: relative; | 72 | position: relative; |
| 33 | - border-bottom: 1px solid @border-color-base; | 73 | + word-wrap: normal; |
| 74 | + vertical-align: middle; | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + &-stripe &-body{ | ||
| 78 | + tr:nth-child(2n) { | ||
| 79 | + td{ | ||
| 80 | + background-color: @table-td-stripe-bg; | ||
| 81 | + } | ||
| 82 | + } | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + tr:hover{ | ||
| 86 | + td{ | ||
| 87 | + background-color: @table-td-hover-bg; | ||
| 88 | + } | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + &-large { | ||
| 92 | + font-size: @font-size-base; | ||
| 93 | + th{ | ||
| 94 | + height: 48px; | ||
| 95 | + } | ||
| 96 | + td{ | ||
| 97 | + height: 60px; | ||
| 98 | + } | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + &-small{ | ||
| 102 | + th{ | ||
| 103 | + height: 32px; | ||
| 104 | + } | ||
| 105 | + td{ | ||
| 106 | + height: 40px; | ||
| 107 | + } | ||
| 108 | + } | ||
| 109 | + | ||
| 110 | + &-row-highlight, | ||
| 111 | + tr&-row-highlight:hover, | ||
| 112 | + &-stripe &-body tr&-row-highlight:nth-child(2n) | ||
| 113 | + { | ||
| 114 | + td{ | ||
| 115 | + background-color: @table-td-highlight-bg; | ||
| 116 | + } | ||
| 34 | } | 117 | } |
| 35 | } | 118 | } |
| 36 | \ No newline at end of file | 119 | \ No newline at end of file |
src/styles/themes/default/custom.less
| @@ -38,6 +38,10 @@ | @@ -38,6 +38,10 @@ | ||
| 38 | @background-color-select-hover: @input-disabled-bg; | 38 | @background-color-select-hover: @input-disabled-bg; |
| 39 | @tooltip-bg : rgba(70, 76, 91, .9); | 39 | @tooltip-bg : rgba(70, 76, 91, .9); |
| 40 | @head-bg : #f9fafc; | 40 | @head-bg : #f9fafc; |
| 41 | +@table-thead-bg : #f5f7f9; | ||
| 42 | +@table-td-stripe-bg : #f5f7f9; | ||
| 43 | +@table-td-hover-bg : #ebf7ff; | ||
| 44 | +@table-td-highlight-bg : #ebf7ff; | ||
| 41 | 45 | ||
| 42 | // Shadow | 46 | // Shadow |
| 43 | @shadow-color : rgba(0, 0, 0, .2); | 47 | @shadow-color : rgba(0, 0, 0, .2); |
src/utils/assist.js
| @@ -70,7 +70,7 @@ export function getStyle (element, styleName) { | @@ -70,7 +70,7 @@ export function getStyle (element, styleName) { | ||
| 70 | styleName = 'cssFloat'; | 70 | styleName = 'cssFloat'; |
| 71 | } | 71 | } |
| 72 | try { | 72 | try { |
| 73 | - var computed = document.defaultView.getComputedStyle(element, ''); | 73 | + const computed = document.defaultView.getComputedStyle(element, ''); |
| 74 | return element.style[styleName] || computed ? computed[styleName] : null; | 74 | return element.style[styleName] || computed ? computed[styleName] : null; |
| 75 | } catch(e) { | 75 | } catch(e) { |
| 76 | return element.style[styleName]; | 76 | return element.style[styleName]; |
| @@ -87,4 +87,48 @@ export function warnProp(component, prop, correctType, wrongType) { | @@ -87,4 +87,48 @@ export function warnProp(component, prop, correctType, wrongType) { | ||
| 87 | correctType = firstUpperCase(correctType); | 87 | correctType = firstUpperCase(correctType); |
| 88 | wrongType = firstUpperCase(wrongType); | 88 | wrongType = firstUpperCase(wrongType); |
| 89 | console.error(`[iView warn]: Invalid prop: type check failed for prop ${prop}. Expected ${correctType}, got ${wrongType}. (found in component: ${component})`); | 89 | console.error(`[iView warn]: Invalid prop: type check failed for prop ${prop}. Expected ${correctType}, got ${wrongType}. (found in component: ${component})`); |
| 90 | -} | ||
| 91 | \ No newline at end of file | 90 | \ No newline at end of file |
| 91 | +} | ||
| 92 | + | ||
| 93 | +function typeOf(obj) { | ||
| 94 | + const toString = Object.prototype.toString; | ||
| 95 | + const map = { | ||
| 96 | + '[object Boolean]' : 'boolean', | ||
| 97 | + '[object Number]' : 'number', | ||
| 98 | + '[object String]' : 'string', | ||
| 99 | + '[object Function]' : 'function', | ||
| 100 | + '[object Array]' : 'array', | ||
| 101 | + '[object Date]' : 'date', | ||
| 102 | + '[object RegExp]' : 'regExp', | ||
| 103 | + '[object Undefined]': 'undefined', | ||
| 104 | + '[object Null]' : 'null', | ||
| 105 | + '[object Object]' : 'object' | ||
| 106 | + }; | ||
| 107 | + return map[toString.call(obj)]; | ||
| 108 | +} | ||
| 109 | + | ||
| 110 | +// deepCopy | ||
| 111 | +function deepCopy(data) { | ||
| 112 | + const t = typeOf(data); | ||
| 113 | + let o; | ||
| 114 | + | ||
| 115 | + if (t === 'array') { | ||
| 116 | + o = []; | ||
| 117 | + } else if ( t === 'object') { | ||
| 118 | + o = {}; | ||
| 119 | + } else { | ||
| 120 | + return data; | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + if (t === 'array') { | ||
| 124 | + for (let i = 0; i < data.length; i++) { | ||
| 125 | + o.push(deepCopy(data[i])); | ||
| 126 | + } | ||
| 127 | + } else if ( t === 'object') { | ||
| 128 | + for (let i in data) { | ||
| 129 | + o[i] = deepCopy(data[i]); | ||
| 130 | + } | ||
| 131 | + } | ||
| 132 | + return o; | ||
| 133 | +} | ||
| 134 | + | ||
| 135 | +export {deepCopy} | ||
| 92 | \ No newline at end of file | 136 | \ No newline at end of file |
test/routers/table.vue
| 1 | <template> | 1 | <template> |
| 2 | <div> | 2 | <div> |
| 3 | - <i-table :columns="columns" :data="data"></i-table> | 3 | + <!--<i-table size="large" border stripe :columns="columns" :data="data"></i-table>--> |
| 4 | + <br> | ||
| 5 | + <i-table border :columns="columns" :data="data" @on-current-change="current" @on-select="select" @on-selection-change="schange" @on-select-all="sall"></i-table> | ||
| 6 | + <br> | ||
| 7 | + <!--<i-table size="small" border stripe :columns="columns" :data="data"></i-table>--> | ||
| 4 | </div> | 8 | </div> |
| 5 | </template> | 9 | </template> |
| 6 | <script> | 10 | <script> |
| @@ -12,15 +16,19 @@ | @@ -12,15 +16,19 @@ | ||
| 12 | return { | 16 | return { |
| 13 | columns: [ | 17 | columns: [ |
| 14 | { | 18 | { |
| 19 | + type: 'selection', | ||
| 20 | + width: 50 | ||
| 21 | + }, | ||
| 22 | + { | ||
| 15 | title: '姓名', | 23 | title: '姓名', |
| 16 | key: 'name', | 24 | key: 'name', |
| 17 | - fixed: 'left', | 25 | + align: 'left', |
| 18 | // width: 100 | 26 | // width: 100 |
| 19 | }, | 27 | }, |
| 20 | { | 28 | { |
| 21 | title: '年龄', | 29 | title: '年龄', |
| 22 | key: 'age', | 30 | key: 'age', |
| 23 | - fixed: 'right', | 31 | + align: 'right', |
| 24 | // width: 100 | 32 | // width: 100 |
| 25 | // render (row) { | 33 | // render (row) { |
| 26 | // return `<i-button>${row.age}</i-button>` | 34 | // return `<i-button>${row.age}</i-button>` |
| @@ -29,7 +37,7 @@ | @@ -29,7 +37,7 @@ | ||
| 29 | { | 37 | { |
| 30 | title: '地址', | 38 | title: '地址', |
| 31 | key: 'address', | 39 | key: 'address', |
| 32 | - fixed: 'center', | 40 | + align: 'center', |
| 33 | // width: 100 | 41 | // width: 100 |
| 34 | // render (row, column, index) { | 42 | // render (row, column, index) { |
| 35 | // if (row.edit) { | 43 | // if (row.edit) { |
| @@ -65,7 +73,13 @@ | @@ -65,7 +73,13 @@ | ||
| 65 | name: '刘天娇', | 73 | name: '刘天娇', |
| 66 | age: 27, | 74 | age: 27, |
| 67 | address: '北京市东城区', | 75 | address: '北京市东城区', |
| 68 | - edit: true | 76 | + edit: false |
| 77 | + }, | ||
| 78 | + { | ||
| 79 | + name: '胡国伟', | ||
| 80 | + age: 28, | ||
| 81 | + address: '北京市西城区', | ||
| 82 | + edit: false | ||
| 69 | } | 83 | } |
| 70 | ] | 84 | ] |
| 71 | } | 85 | } |
| @@ -78,12 +92,27 @@ | @@ -78,12 +92,27 @@ | ||
| 78 | this.$Message.info(name); | 92 | this.$Message.info(name); |
| 79 | }, | 93 | }, |
| 80 | edit (index) { | 94 | edit (index) { |
| 81 | - this.data[index].edit = true; | 95 | +// this.data[index].edit = true; |
| 96 | + this.$Message.info(this.data[index].name); | ||
| 97 | + }, | ||
| 98 | + current (newData, oldData) { | ||
| 99 | + console.log(newData); | ||
| 100 | + console.log(oldData); | ||
| 101 | + }, | ||
| 102 | + select (a,b){ | ||
| 103 | + console.log(a); | ||
| 104 | + console.log(b); | ||
| 105 | + }, | ||
| 106 | + schange (a) { | ||
| 107 | + console.log(a) | ||
| 108 | + }, | ||
| 109 | + sall (a) { | ||
| 110 | + console.log(a) | ||
| 82 | } | 111 | } |
| 83 | }, | 112 | }, |
| 84 | ready () { | 113 | ready () { |
| 85 | setTimeout(() => { | 114 | setTimeout(() => { |
| 86 | - return; | 115 | +// return |
| 87 | this.data.push({ | 116 | this.data.push({ |
| 88 | name: '刘天娇2', | 117 | name: '刘天娇2', |
| 89 | age: 272, | 118 | age: 272, |