Commit 486d4fda19c7b473b6cd08126a3805a28a4e833f
1 parent
b2012015
update Table
update Table
Showing
9 changed files
with
132 additions
and
106 deletions
Show diff stats
README.md
examples/app.vue
| @@ -49,6 +49,7 @@ li + li { border-left: solid 1px #bbb; padding-left: 10px; margin-left: 10px; } | @@ -49,6 +49,7 @@ li + li { border-left: solid 1px #bbb; padding-left: 10px; margin-left: 10px; } | ||
| 49 | <li><router-link to="/transfer">Transfer</router-link></li> | 49 | <li><router-link to="/transfer">Transfer</router-link></li> |
| 50 | <li><router-link to="/date">Date</router-link></li> | 50 | <li><router-link to="/date">Date</router-link></li> |
| 51 | <li><router-link to="/form">Form</router-link></li> | 51 | <li><router-link to="/form">Form</router-link></li> |
| 52 | + <li><router-link to="/table">Table</router-link></li> | ||
| 52 | </ul> | 53 | </ul> |
| 53 | </nav> | 54 | </nav> |
| 54 | <router-view></router-view> | 55 | <router-view></router-view> |
examples/main.js
| @@ -161,6 +161,10 @@ const router = new VueRouter({ | @@ -161,6 +161,10 @@ const router = new VueRouter({ | ||
| 161 | path: '/form', | 161 | path: '/form', |
| 162 | component: require('./routers/form.vue') | 162 | component: require('./routers/form.vue') |
| 163 | }, | 163 | }, |
| 164 | + { | ||
| 165 | + path: '/table', | ||
| 166 | + component: require('./routers/table.vue') | ||
| 167 | + }, | ||
| 164 | ] | 168 | ] |
| 165 | }); | 169 | }); |
| 166 | 170 |
examples/routers/table.vue
| 1 | <template> | 1 | <template> |
| 2 | - <i-table highlight-row border :content="self" :columns="columns7" :data="data6"></i-table> | 2 | + <Table width="550" border :columns="columns2" :data="data3"></Table> |
| 3 | </template> | 3 | </template> |
| 4 | <script> | 4 | <script> |
| 5 | export default { | 5 | export default { |
| 6 | data () { | 6 | data () { |
| 7 | return { | 7 | return { |
| 8 | - self: this, | ||
| 9 | - columns7: [ | ||
| 10 | - { | ||
| 11 | - type: 'selection', | ||
| 12 | - width: 60, | ||
| 13 | - align: 'center' | ||
| 14 | - }, | 8 | + columns2: [ |
| 15 | { | 9 | { |
| 16 | title: '姓名', | 10 | title: '姓名', |
| 17 | key: 'name', | 11 | key: 'name', |
| 18 | - render (row, column, index) { | ||
| 19 | - return `<Icon type="person"></Icon> <strong>${row.name}</strong>`; | ||
| 20 | - } | 12 | + width: 100, |
| 13 | + fixed: 'left' | ||
| 21 | }, | 14 | }, |
| 22 | { | 15 | { |
| 23 | title: '年龄', | 16 | title: '年龄', |
| 24 | key: 'age', | 17 | key: 'age', |
| 25 | - sortable: true, | ||
| 26 | - sortMethod: function (a, b, type) { | ||
| 27 | - if (type === 'asc') { | ||
| 28 | - return a < b ? 1 : -1; | ||
| 29 | - } else if (type === 'desc') { | ||
| 30 | - return a > b ? 1 : -1; | ||
| 31 | - } | ||
| 32 | - } | 18 | + width: 100 |
| 19 | + }, | ||
| 20 | + { | ||
| 21 | + title: '省份', | ||
| 22 | + key: 'province', | ||
| 23 | + width: 100 | ||
| 24 | + }, | ||
| 25 | + { | ||
| 26 | + title: '市区', | ||
| 27 | + key: 'city', | ||
| 28 | + width: 100 | ||
| 33 | }, | 29 | }, |
| 34 | { | 30 | { |
| 35 | title: '地址', | 31 | title: '地址', |
| 36 | - key: 'address' | 32 | + key: 'address', |
| 33 | + width: 200 | ||
| 34 | + }, | ||
| 35 | + { | ||
| 36 | + title: '邮编', | ||
| 37 | + key: 'zip', | ||
| 38 | + width: 100 | ||
| 37 | }, | 39 | }, |
| 38 | { | 40 | { |
| 39 | title: '操作', | 41 | title: '操作', |
| 40 | key: 'action', | 42 | key: 'action', |
| 41 | - width: 150, | ||
| 42 | - align: 'center', | ||
| 43 | - render (row, column, index) { | ||
| 44 | -// return `<i-button type="primary" size="small" @click="show(${index})">查看</i-button> <i-button type="error" size="small" @click="remove(${index})">删除</i-button>`; | ||
| 45 | - return `<Poptip width="250" confirm placement="left" title="您确认删除吗?" @on-ok="deleteProject(${index})"> | ||
| 46 | - <i-button size="small" type="error">删除</i-button> | ||
| 47 | - </Poptip>` | 43 | + fixed: 'right', |
| 44 | + width: 120, | ||
| 45 | + render () { | ||
| 46 | + return `<Button type="text" size="small">查看</Button><Button type="text" size="small">编辑</Button>`; | ||
| 48 | } | 47 | } |
| 49 | } | 48 | } |
| 50 | ], | 49 | ], |
| 51 | - data6: [ | 50 | + data3: [ |
| 52 | { | 51 | { |
| 53 | name: '王小明', | 52 | name: '王小明', |
| 54 | age: 18, | 53 | age: 18, |
| 55 | address: '北京市朝阳区芍药居', | 54 | address: '北京市朝阳区芍药居', |
| 56 | - _highlight: true, | ||
| 57 | - _checked: true, | ||
| 58 | - _disabled: false | 55 | + province: '北京市', |
| 56 | + city: '朝阳区', | ||
| 57 | + zip: 100000 | ||
| 59 | }, | 58 | }, |
| 60 | { | 59 | { |
| 61 | name: '张小刚', | 60 | name: '张小刚', |
| 62 | age: 25, | 61 | age: 25, |
| 63 | address: '北京市海淀区西二旗', | 62 | address: '北京市海淀区西二旗', |
| 64 | - _checked: false, | ||
| 65 | - _disabled: true | 63 | + province: '北京市', |
| 64 | + city: '海淀区', | ||
| 65 | + zip: 100000 | ||
| 66 | }, | 66 | }, |
| 67 | { | 67 | { |
| 68 | name: '李小红', | 68 | name: '李小红', |
| 69 | age: 30, | 69 | age: 30, |
| 70 | address: '上海市浦东新区世纪大道', | 70 | address: '上海市浦东新区世纪大道', |
| 71 | - _checked: true, | ||
| 72 | - _disabled: true | 71 | + province: '上海市', |
| 72 | + city: '浦东新区', | ||
| 73 | + zip: 100000 | ||
| 73 | }, | 74 | }, |
| 74 | { | 75 | { |
| 75 | name: '周小伟', | 76 | name: '周小伟', |
| 76 | age: 26, | 77 | age: 26, |
| 77 | address: '深圳市南山区深南大道', | 78 | address: '深圳市南山区深南大道', |
| 78 | - _checked: false, | ||
| 79 | - _disabled: false | 79 | + province: '广东', |
| 80 | + city: '南山区', | ||
| 81 | + zip: 100000 | ||
| 80 | } | 82 | } |
| 81 | ] | 83 | ] |
| 82 | } | 84 | } |
| 83 | - }, | ||
| 84 | - methods: { | ||
| 85 | - show (index) { | ||
| 86 | - this.$Modal.info({ | ||
| 87 | - title: '用户信息', | ||
| 88 | - content: `姓名:${this.data6[index].name}<br>年龄:${this.data6[index].age}<br>地址:${this.data6[index].address}` | ||
| 89 | - }) | ||
| 90 | - }, | ||
| 91 | - remove (index) { | ||
| 92 | - this.data6.splice(index, 1); | ||
| 93 | - } | ||
| 94 | } | 85 | } |
| 95 | } | 86 | } |
| 96 | </script> | 87 | </script> |
src/components/table/cell.vue
| @@ -2,15 +2,17 @@ | @@ -2,15 +2,17 @@ | ||
| 2 | <div :class="classes"> | 2 | <div :class="classes"> |
| 3 | <template v-if="renderType === 'index'">{{naturalIndex + 1}}</template> | 3 | <template v-if="renderType === 'index'">{{naturalIndex + 1}}</template> |
| 4 | <template v-if="renderType === 'selection'"> | 4 | <template v-if="renderType === 'selection'"> |
| 5 | - <Checkbox :checked="checked" @on-change="toggleSelect" :disabled="disabled"></Checkbox> | 5 | + <Checkbox :value="checked" @on-change="toggleSelect" :disabled="disabled"></Checkbox> |
| 6 | </template> | 6 | </template> |
| 7 | - <template v-if="renderType === 'normal'">{{{ row[column.key] }}}</template> | 7 | + <template v-if="renderType === 'normal'"><span v-html="row[column.key]"></span></template> |
| 8 | </div> | 8 | </div> |
| 9 | </template> | 9 | </template> |
| 10 | <script> | 10 | <script> |
| 11 | + import Vue from 'vue'; | ||
| 11 | import Checkbox from '../checkbox/checkbox.vue'; | 12 | import Checkbox from '../checkbox/checkbox.vue'; |
| 12 | 13 | ||
| 13 | export default { | 14 | export default { |
| 15 | + name: 'TableCell', | ||
| 14 | components: { Checkbox }, | 16 | components: { Checkbox }, |
| 15 | props: { | 17 | props: { |
| 16 | prefixCls: String, | 18 | prefixCls: String, |
| @@ -29,7 +31,7 @@ | @@ -29,7 +31,7 @@ | ||
| 29 | return { | 31 | return { |
| 30 | renderType: '', | 32 | renderType: '', |
| 31 | uid: -1, | 33 | uid: -1, |
| 32 | - content: this.$parent.$parent.content | 34 | + content: this.$parent.$parent.currentContent |
| 33 | }; | 35 | }; |
| 34 | }, | 36 | }, |
| 35 | computed: { | 37 | computed: { |
| @@ -51,14 +53,34 @@ | @@ -51,14 +53,34 @@ | ||
| 51 | const cell = document.createElement('div'); | 53 | const cell = document.createElement('div'); |
| 52 | cell.innerHTML = template; | 54 | cell.innerHTML = template; |
| 53 | const _oldParentChildLen = $parent.$children.length; | 55 | const _oldParentChildLen = $parent.$children.length; |
| 54 | - $parent.$compile(cell); // todo 这里无法触发 ready 钩子 | 56 | +// $parent.$compile(cell); // todo 这里无法触发 ready 钩子 |
| 55 | const _newParentChildLen = $parent.$children.length; | 57 | const _newParentChildLen = $parent.$children.length; |
| 56 | 58 | ||
| 57 | if (_oldParentChildLen !== _newParentChildLen) { // if render normal html node, do not tag | 59 | if (_oldParentChildLen !== _newParentChildLen) { // if render normal html node, do not tag |
| 58 | this.uid = $parent.$children[$parent.$children.length - 1]._uid; // tag it, and delete when data or columns update | 60 | this.uid = $parent.$children[$parent.$children.length - 1]._uid; // tag it, and delete when data or columns update |
| 59 | } | 61 | } |
| 60 | this.$el.innerHTML = ''; | 62 | this.$el.innerHTML = ''; |
| 61 | - this.$el.appendChild(cell); | 63 | +// this.$el.appendChild(cell); |
| 64 | + let methods = {}; | ||
| 65 | + let $_parent = this.$parent; | ||
| 66 | + while($_parent != null && $_parent._name != '<Table>'){ | ||
| 67 | + $_parent = $_parent.$parent; | ||
| 68 | + } | ||
| 69 | + if ($_parent) { | ||
| 70 | + Object.keys($_parent).forEach(key => { | ||
| 71 | + const func = this.$parent.$parent.$parent[`${key}`]; | ||
| 72 | + if(typeof(func) === 'function' &&func.name === 'boundFn'){ | ||
| 73 | + methods[`${key}`] = func; | ||
| 74 | + } | ||
| 75 | + }); | ||
| 76 | + } | ||
| 77 | + const res = Vue.compile(cell.outerHTML); | ||
| 78 | + const compt = new Vue({ | ||
| 79 | + render: res.render, | ||
| 80 | + staticRenderFns: res.staticRenderFns, | ||
| 81 | + methods: methods | ||
| 82 | + }); | ||
| 83 | + compt.$mount(this.$el); | ||
| 62 | } | 84 | } |
| 63 | }, | 85 | }, |
| 64 | destroy () { | 86 | destroy () { |
| @@ -73,7 +95,7 @@ | @@ -73,7 +95,7 @@ | ||
| 73 | this.$parent.$parent.toggleSelect(this.index); | 95 | this.$parent.$parent.toggleSelect(this.index); |
| 74 | } | 96 | } |
| 75 | }, | 97 | }, |
| 76 | - compiled () { | 98 | + created () { |
| 77 | if (this.column.type === 'index') { | 99 | if (this.column.type === 'index') { |
| 78 | this.renderType = 'index'; | 100 | this.renderType = 'index'; |
| 79 | } else if (this.column.type === 'selection') { | 101 | } else if (this.column.type === 'selection') { |
| @@ -84,8 +106,10 @@ | @@ -84,8 +106,10 @@ | ||
| 84 | this.renderType = 'normal'; | 106 | this.renderType = 'normal'; |
| 85 | } | 107 | } |
| 86 | }, | 108 | }, |
| 87 | - ready () { | ||
| 88 | - this.compile(); | 109 | + mounted () { |
| 110 | + this.$nextTick(() => { | ||
| 111 | + this.compile(); | ||
| 112 | + }); | ||
| 89 | }, | 113 | }, |
| 90 | beforeDestroy () { | 114 | beforeDestroy () { |
| 91 | this.destroy(); | 115 | this.destroy(); |
src/components/table/table-body.vue
| 1 | <template> | 1 | <template> |
| 2 | - <table cellspacing="0" cellpadding="0" border="0" :style="style"> | 2 | + <table cellspacing="0" cellpadding="0" border="0" :style="styleObject"> |
| 3 | <colgroup> | 3 | <colgroup> |
| 4 | - <col v-for="column in columns" :width="setCellWidth(column, $index, false)"> | 4 | + <col v-for="(column, index) in columns" :width="setCellWidth(column, index, false)"> |
| 5 | </colgroup> | 5 | </colgroup> |
| 6 | <tbody :class="[prefixCls + '-tbody']"> | 6 | <tbody :class="[prefixCls + '-tbody']"> |
| 7 | <tr | 7 | <tr |
| 8 | - v-for="(index, row) in data" | 8 | + v-for="(row, index) in data" |
| 9 | :class="rowClasses(row._index)" | 9 | :class="rowClasses(row._index)" |
| 10 | @mouseenter.stop="handleMouseIn(row._index)" | 10 | @mouseenter.stop="handleMouseIn(row._index)" |
| 11 | @mouseleave.stop="handleMouseOut(row._index)" | 11 | @mouseleave.stop="handleMouseOut(row._index)" |
| @@ -32,11 +32,12 @@ | @@ -32,11 +32,12 @@ | ||
| 32 | import Mixin from './mixin'; | 32 | import Mixin from './mixin'; |
| 33 | 33 | ||
| 34 | export default { | 34 | export default { |
| 35 | + name: 'TableBody', | ||
| 35 | mixins: [ Mixin ], | 36 | mixins: [ Mixin ], |
| 36 | components: { Cell }, | 37 | components: { Cell }, |
| 37 | props: { | 38 | props: { |
| 38 | prefixCls: String, | 39 | prefixCls: String, |
| 39 | - style: Object, | 40 | + styleObject: Object, |
| 40 | columns: Array, | 41 | columns: Array, |
| 41 | data: Array, // rebuildData | 42 | data: Array, // rebuildData |
| 42 | objData: Object, | 43 | objData: Object, |
src/components/table/table-head.vue
| 1 | <template> | 1 | <template> |
| 2 | <table cellspacing="0" cellpadding="0" border="0" :style="styles"> | 2 | <table cellspacing="0" cellpadding="0" border="0" :style="styles"> |
| 3 | <colgroup> | 3 | <colgroup> |
| 4 | - <col v-for="column in columns" :width="setCellWidth(column, $index, true)"> | 4 | + <col v-for="(column, index) in columns" :width="setCellWidth(column, index, true)"> |
| 5 | </colgroup> | 5 | </colgroup> |
| 6 | <thead> | 6 | <thead> |
| 7 | <tr> | 7 | <tr> |
| 8 | - <th v-for="(index, column) in columns" :class="alignCls(column)"> | 8 | + <th v-for="(column, index) in columns" :class="alignCls(column)"> |
| 9 | <div :class="cellClasses(column)"> | 9 | <div :class="cellClasses(column)"> |
| 10 | - <template v-if="column.type === 'selection'"><Checkbox :checked="isSelectAll" @on-change="selectAll"></Checkbox></template> | 10 | + <template v-if="column.type === 'selection'"><Checkbox :value="isSelectAll" @on-change="selectAll"></Checkbox></template> |
| 11 | <template v-else> | 11 | <template v-else> |
| 12 | - {{{ renderHeader(column, $index) }}} | 12 | + <span v-html="renderHeader(column, index)"></span> |
| 13 | <span :class="[prefixCls + '-sort']" v-if="column.sortable"> | 13 | <span :class="[prefixCls + '-sort']" v-if="column.sortable"> |
| 14 | - <i class="ivu-icon ivu-icon-arrow-up-b" :class="{on: column._sortType === 'asc'}" @click="handleSort($index, 'asc')"></i> | ||
| 15 | - <i class="ivu-icon ivu-icon-arrow-down-b" :class="{on: column._sortType === 'desc'}" @click="handleSort($index, 'desc')"></i> | 14 | + <i class="ivu-icon ivu-icon-arrow-up-b" :class="{on: column._sortType === 'asc'}" @click="handleSort(index, 'asc')"></i> |
| 15 | + <i class="ivu-icon ivu-icon-arrow-down-b" :class="{on: column._sortType === 'desc'}" @click="handleSort(index, 'desc')"></i> | ||
| 16 | </span> | 16 | </span> |
| 17 | <Poptip | 17 | <Poptip |
| 18 | v-if="isPopperShow(column)" | 18 | v-if="isPopperShow(column)" |
| 19 | - :visible.sync="column._filterVisible" | 19 | + :visible="column._filterVisible" |
| 20 | placement="bottom" | 20 | placement="bottom" |
| 21 | - @on-popper-hide="handleFilterHide($index)"> | 21 | + @on-popper-hide="handleFilterHide(index)"> |
| 22 | <span :class="[prefixCls + '-filter']"> | 22 | <span :class="[prefixCls + '-filter']"> |
| 23 | <i class="ivu-icon ivu-icon-funnel" :class="{on: column._isFiltered}"></i> | 23 | <i class="ivu-icon ivu-icon-funnel" :class="{on: column._isFiltered}"></i> |
| 24 | </span> | 24 | </span> |
| 25 | <div slot="content" :class="[prefixCls + '-filter-list']" v-if="column._filterMultiple"> | 25 | <div slot="content" :class="[prefixCls + '-filter-list']" v-if="column._filterMultiple"> |
| 26 | <div :class="[prefixCls + '-filter-list-item']"> | 26 | <div :class="[prefixCls + '-filter-list-item']"> |
| 27 | - <checkbox-group :model.sync="column._filterChecked"> | 27 | + <checkbox-group v-model="column._filterChecked"> |
| 28 | <checkbox v-for="item in column.filters" :value="item.value">{{ item.label }}</checkbox> | 28 | <checkbox v-for="item in column.filters" :value="item.value">{{ item.label }}</checkbox> |
| 29 | </checkbox-group> | 29 | </checkbox-group> |
| 30 | </div> | 30 | </div> |
| 31 | <div :class="[prefixCls + '-filter-footer']"> | 31 | <div :class="[prefixCls + '-filter-footer']"> |
| 32 | - <i-button type="text" size="small" :disabled="!column._filterChecked.length" @click="handleFilter($index)">{{ t('i.table.confirmFilter') }}</i-button> | ||
| 33 | - <i-button type="text" size="small" @click="handleReset($index)">{{ t('i.table.resetFilter') }}</i-button> | 32 | + <i-button type="text" size="small" :disabled="!column._filterChecked.length" @click.native="handleFilter(index)">{{ t('i.table.confirmFilter') }}</i-button> |
| 33 | + <i-button type="text" size="small" @click.native="handleReset(index)">{{ t('i.table.resetFilter') }}</i-button> | ||
| 34 | </div> | 34 | </div> |
| 35 | </div> | 35 | </div> |
| 36 | <div slot="content" :class="[prefixCls + '-filter-list']" v-else> | 36 | <div slot="content" :class="[prefixCls + '-filter-list']" v-else> |
| 37 | <ul :class="[prefixCls + '-filter-list-single']"> | 37 | <ul :class="[prefixCls + '-filter-list-single']"> |
| 38 | <li | 38 | <li |
| 39 | :class="itemAllClasses(column)" | 39 | :class="itemAllClasses(column)" |
| 40 | - @click="handleReset($index)">{{ t('i.table.clearFilter') }}</li> | 40 | + @click="handleReset(index)">{{ t('i.table.clearFilter') }}</li> |
| 41 | <li | 41 | <li |
| 42 | :class="itemClasses(column, item)" | 42 | :class="itemClasses(column, item)" |
| 43 | v-for="item in column.filters" | 43 | v-for="item in column.filters" |
| @@ -61,11 +61,12 @@ | @@ -61,11 +61,12 @@ | ||
| 61 | import Locale from '../../mixins/locale'; | 61 | import Locale from '../../mixins/locale'; |
| 62 | 62 | ||
| 63 | export default { | 63 | export default { |
| 64 | + name: 'TableHead', | ||
| 64 | mixins: [ Mixin, Locale ], | 65 | mixins: [ Mixin, Locale ], |
| 65 | components: { CheckboxGroup, Checkbox, Poptip, iButton }, | 66 | components: { CheckboxGroup, Checkbox, Poptip, iButton }, |
| 66 | props: { | 67 | props: { |
| 67 | prefixCls: String, | 68 | prefixCls: String, |
| 68 | - style: Object, | 69 | + styleObject: Object, |
| 69 | columns: Array, | 70 | columns: Array, |
| 70 | objData: Object, | 71 | objData: Object, |
| 71 | data: Array, // rebuildData | 72 | data: Array, // rebuildData |
| @@ -77,8 +78,8 @@ | @@ -77,8 +78,8 @@ | ||
| 77 | }, | 78 | }, |
| 78 | computed: { | 79 | computed: { |
| 79 | styles () { | 80 | styles () { |
| 80 | - const style = Object.assign({}, this.style); | ||
| 81 | - const width = this.$parent.bodyHeight === 0 ? parseInt(this.style.width) : parseInt(this.style.width) + this.$parent.scrollBarWidth; | 81 | + const style = Object.assign({}, this.styleObject); |
| 82 | + const width = this.$parent.bodyHeight === 0 ? parseInt(this.styleObject.width) : parseInt(this.styleObject.width) + this.$parent.scrollBarWidth; | ||
| 82 | style.width = `${width}px`; | 83 | style.width = `${width}px`; |
| 83 | return style; | 84 | return style; |
| 84 | }, | 85 | }, |
src/components/table/table.vue
| 1 | <template> | 1 | <template> |
| 2 | <div :class="wrapClasses" :style="styles"> | 2 | <div :class="wrapClasses" :style="styles"> |
| 3 | <div :class="classes"> | 3 | <div :class="classes"> |
| 4 | - <div :class="[prefixCls + '-title']" v-if="showSlotHeader" v-el:title><slot name="header"></slot></div> | ||
| 5 | - <div :class="[prefixCls + '-header']" v-if="showHeader" v-el:header @mousewheel="handleMouseWheel"> | 4 | + <div :class="[prefixCls + '-title']" v-if="showSlotHeader" ref="title"><slot name="header"></slot></div> |
| 5 | + <div :class="[prefixCls + '-header']" v-if="showHeader" ref="header" @mousewheel="handleMouseWheel"> | ||
| 6 | <table-head | 6 | <table-head |
| 7 | :prefix-cls="prefixCls" | 7 | :prefix-cls="prefixCls" |
| 8 | - :style="tableStyle" | 8 | + :styleObject="tableStyle" |
| 9 | :columns="cloneColumns" | 9 | :columns="cloneColumns" |
| 10 | :obj-data="objData" | 10 | :obj-data="objData" |
| 11 | :columns-width="columnsWidth" | 11 | :columns-width="columnsWidth" |
| 12 | :data="rebuildData"></table-head> | 12 | :data="rebuildData"></table-head> |
| 13 | </div> | 13 | </div> |
| 14 | - <div :class="[prefixCls + '-body']" :style="bodyStyle" v-el:body @scroll="handleBodyScroll" | 14 | + <div :class="[prefixCls + '-body']" :style="bodyStyle" ref="body" @scroll="handleBodyScroll" |
| 15 | v-show="!((!!noDataText && (!data || data.length === 0)) || (!!noFilteredDataText && (!rebuildData || rebuildData.length === 0)))"> | 15 | v-show="!((!!noDataText && (!data || data.length === 0)) || (!!noFilteredDataText && (!rebuildData || rebuildData.length === 0)))"> |
| 16 | <table-body | 16 | <table-body |
| 17 | - v-ref:tbody | 17 | + ref="tbody" |
| 18 | :prefix-cls="prefixCls" | 18 | :prefix-cls="prefixCls" |
| 19 | - :style="tableStyle" | 19 | + :styleObject="tableStyle" |
| 20 | :columns="cloneColumns" | 20 | :columns="cloneColumns" |
| 21 | :data="rebuildData" | 21 | :data="rebuildData" |
| 22 | :columns-width="columnsWidth" | 22 | :columns-width="columnsWidth" |
| @@ -24,12 +24,13 @@ | @@ -24,12 +24,13 @@ | ||
| 24 | </div> | 24 | </div> |
| 25 | <div | 25 | <div |
| 26 | :class="[prefixCls + '-tip']" | 26 | :class="[prefixCls + '-tip']" |
| 27 | - v-else> | 27 | + v-show="((!!noDataText && (!data || data.length === 0)) || (!!noFilteredDataText && (!rebuildData || rebuildData.length === 0)))"> |
| 28 | <table cellspacing="0" cellpadding="0" border="0"> | 28 | <table cellspacing="0" cellpadding="0" border="0"> |
| 29 | <tbody> | 29 | <tbody> |
| 30 | <tr> | 30 | <tr> |
| 31 | <td :style="{ 'height': bodyStyle.height }"> | 31 | <td :style="{ 'height': bodyStyle.height }"> |
| 32 | - {{{!data || data.length === 0 ? noDataText : noFilteredDataText}}} | 32 | + <span v-html="noDataText" v-if="!data || data.length === 0"></span> |
| 33 | + <span v-html="noFilteredDataText" v-else></span> | ||
| 33 | </td> | 34 | </td> |
| 34 | </tr> | 35 | </tr> |
| 35 | </tbody> | 36 | </tbody> |
| @@ -40,17 +41,17 @@ | @@ -40,17 +41,17 @@ | ||
| 40 | <table-head | 41 | <table-head |
| 41 | fixed="left" | 42 | fixed="left" |
| 42 | :prefix-cls="prefixCls" | 43 | :prefix-cls="prefixCls" |
| 43 | - :style="fixedTableStyle" | 44 | + :styleObject="fixedTableStyle" |
| 44 | :columns="leftFixedColumns" | 45 | :columns="leftFixedColumns" |
| 45 | :obj-data="objData" | 46 | :obj-data="objData" |
| 46 | :columns-width.sync="columnsWidth" | 47 | :columns-width.sync="columnsWidth" |
| 47 | :data="rebuildData"></table-head> | 48 | :data="rebuildData"></table-head> |
| 48 | </div> | 49 | </div> |
| 49 | - <div :class="[prefixCls + '-fixed-body']" :style="fixedBodyStyle" v-el:fixed-body> | 50 | + <div :class="[prefixCls + '-fixed-body']" :style="fixedBodyStyle" ref="fixedBody"> |
| 50 | <table-body | 51 | <table-body |
| 51 | fixed="left" | 52 | fixed="left" |
| 52 | :prefix-cls="prefixCls" | 53 | :prefix-cls="prefixCls" |
| 53 | - :style="fixedTableStyle" | 54 | + :styleObject="fixedTableStyle" |
| 54 | :columns="leftFixedColumns" | 55 | :columns="leftFixedColumns" |
| 55 | :data="rebuildData" | 56 | :data="rebuildData" |
| 56 | :columns-width="columnsWidth" | 57 | :columns-width="columnsWidth" |
| @@ -62,24 +63,24 @@ | @@ -62,24 +63,24 @@ | ||
| 62 | <table-head | 63 | <table-head |
| 63 | fixed="right" | 64 | fixed="right" |
| 64 | :prefix-cls="prefixCls" | 65 | :prefix-cls="prefixCls" |
| 65 | - :style="fixedRightTableStyle" | 66 | + :styleObject="fixedRightTableStyle" |
| 66 | :columns="rightFixedColumns" | 67 | :columns="rightFixedColumns" |
| 67 | :obj-data="objData" | 68 | :obj-data="objData" |
| 68 | - :columns-width.sync="columnsWidth" | 69 | + :columns-width="columnsWidth" |
| 69 | :data="rebuildData"></table-head> | 70 | :data="rebuildData"></table-head> |
| 70 | </div> | 71 | </div> |
| 71 | - <div :class="[prefixCls + '-fixed-body']" :style="fixedBodyStyle" v-el:fixed-right-body> | 72 | + <div :class="[prefixCls + '-fixed-body']" :style="fixedBodyStyle" ref="fixedRightBody"> |
| 72 | <table-body | 73 | <table-body |
| 73 | fixed="right" | 74 | fixed="right" |
| 74 | :prefix-cls="prefixCls" | 75 | :prefix-cls="prefixCls" |
| 75 | - :style="fixedRightTableStyle" | 76 | + :styleObject="fixedRightTableStyle" |
| 76 | :columns="rightFixedColumns" | 77 | :columns="rightFixedColumns" |
| 77 | :data="rebuildData" | 78 | :data="rebuildData" |
| 78 | :columns-width="columnsWidth" | 79 | :columns-width="columnsWidth" |
| 79 | :obj-data="objData"></table-body> | 80 | :obj-data="objData"></table-body> |
| 80 | </div> | 81 | </div> |
| 81 | </div> | 82 | </div> |
| 82 | - <div :class="[prefixCls + '-footer']" v-if="showSlotFooter" v-el:footer><slot name="footer"></slot></div> | 83 | + <div :class="[prefixCls + '-footer']" v-if="showSlotFooter" ref="footer"><slot name="footer"></slot></div> |
| 83 | </div> | 84 | </div> |
| 84 | </div> | 85 | </div> |
| 85 | </template> | 86 | </template> |
| @@ -93,6 +94,7 @@ | @@ -93,6 +94,7 @@ | ||
| 93 | const prefixCls = 'ivu-table'; | 94 | const prefixCls = 'ivu-table'; |
| 94 | 95 | ||
| 95 | export default { | 96 | export default { |
| 97 | + name: 'Table', | ||
| 96 | components: { tableHead, tableBody }, | 98 | components: { tableHead, tableBody }, |
| 97 | props: { | 99 | props: { |
| 98 | data: { | 100 | data: { |
| @@ -170,7 +172,8 @@ | @@ -170,7 +172,8 @@ | ||
| 170 | showSlotFooter: true, | 172 | showSlotFooter: true, |
| 171 | bodyHeight: 0, | 173 | bodyHeight: 0, |
| 172 | bodyRealHeight: 0, | 174 | bodyRealHeight: 0, |
| 173 | - scrollBarWidth: getScrollBarSize() | 175 | + scrollBarWidth: getScrollBarSize(), |
| 176 | + currentContent: this.content | ||
| 174 | }; | 177 | }; |
| 175 | }, | 178 | }, |
| 176 | computed: { | 179 | computed: { |
| @@ -415,9 +418,9 @@ | @@ -415,9 +418,9 @@ | ||
| 415 | fixedHeader () { | 418 | fixedHeader () { |
| 416 | if (this.height) { | 419 | if (this.height) { |
| 417 | this.$nextTick(() => { | 420 | this.$nextTick(() => { |
| 418 | - const titleHeight = parseInt(getStyle(this.$els.title, 'height')) || 0; | ||
| 419 | - const headerHeight = parseInt(getStyle(this.$els.header, 'height')) || 0; | ||
| 420 | - const footerHeight = parseInt(getStyle(this.$els.footer, 'height')) || 0; | 421 | + const titleHeight = parseInt(getStyle(this.$refs.title, 'height')) || 0; |
| 422 | + const headerHeight = parseInt(getStyle(this.$refs.header, 'height')) || 0; | ||
| 423 | + const footerHeight = parseInt(getStyle(this.$refs.footer, 'height')) || 0; | ||
| 421 | this.bodyHeight = this.height - titleHeight - headerHeight - footerHeight; | 424 | this.bodyHeight = this.height - titleHeight - headerHeight - footerHeight; |
| 422 | }); | 425 | }); |
| 423 | } else { | 426 | } else { |
| @@ -428,14 +431,14 @@ | @@ -428,14 +431,14 @@ | ||
| 428 | this.cloneColumns.forEach((col) => col._filterVisible = false); | 431 | this.cloneColumns.forEach((col) => col._filterVisible = false); |
| 429 | }, | 432 | }, |
| 430 | handleBodyScroll (event) { | 433 | handleBodyScroll (event) { |
| 431 | - if (this.showHeader) this.$els.header.scrollLeft = event.target.scrollLeft; | ||
| 432 | - if (this.isLeftFixed) this.$els.fixedBody.scrollTop = event.target.scrollTop; | ||
| 433 | - if (this.isRightFixed) this.$els.fixedRightBody.scrollTop = event.target.scrollTop; | 434 | + if (this.showHeader) this.$refs.header.scrollLeft = event.target.scrollLeft; |
| 435 | + if (this.isLeftFixed) this.$refs.fixedBody.scrollTop = event.target.scrollTop; | ||
| 436 | + if (this.isRightFixed) this.$refs.fixedRightBody.scrollTop = event.target.scrollTop; | ||
| 434 | this.hideColumnFilter(); | 437 | this.hideColumnFilter(); |
| 435 | }, | 438 | }, |
| 436 | handleMouseWheel (event) { | 439 | handleMouseWheel (event) { |
| 437 | const deltaX = event.deltaX; | 440 | const deltaX = event.deltaX; |
| 438 | - const $body = this.$els.body; | 441 | + const $body = this.$refs.body; |
| 439 | 442 | ||
| 440 | if (deltaX > 0) { | 443 | if (deltaX > 0) { |
| 441 | $body.scrollLeft = $body.scrollLeft + 10; | 444 | $body.scrollLeft = $body.scrollLeft + 10; |
| @@ -639,13 +642,13 @@ | @@ -639,13 +642,13 @@ | ||
| 639 | ExportCsv.download(params.filename, data); | 642 | ExportCsv.download(params.filename, data); |
| 640 | } | 643 | } |
| 641 | }, | 644 | }, |
| 642 | - compiled () { | ||
| 643 | - if (!this.content) this.content = this.$parent; | ||
| 644 | - this.showSlotHeader = this.$els.title.innerHTML.replace(/\n/g, '').replace(/<!--[\w\W\r\n]*?-->/gmi, '') !== ''; | ||
| 645 | - this.showSlotFooter = this.$els.footer.innerHTML.replace(/\n/g, '').replace(/<!--[\w\W\r\n]*?-->/gmi, '') !== ''; | 645 | + created () { |
| 646 | + if (!this.content) this.currentContent = this.$parent; | ||
| 647 | + this.showSlotHeader = this.$refs.title !== undefined; | ||
| 648 | + this.showSlotFooter = this.$refs.footer !== undefined; | ||
| 646 | this.rebuildData = this.makeDataWithSortAndFilter(); | 649 | this.rebuildData = this.makeDataWithSortAndFilter(); |
| 647 | }, | 650 | }, |
| 648 | - ready () { | 651 | + mounted () { |
| 649 | this.handleResize(); | 652 | this.handleResize(); |
| 650 | this.fixedHeader(); | 653 | this.fixedHeader(); |
| 651 | this.$nextTick(() => this.ready = true); | 654 | this.$nextTick(() => this.ready = true); |
src/index.js
| @@ -33,7 +33,7 @@ import Slider from './components/slider'; | @@ -33,7 +33,7 @@ import Slider from './components/slider'; | ||
| 33 | import Spin from './components/spin'; | 33 | import Spin from './components/spin'; |
| 34 | import Steps from './components/steps'; | 34 | import Steps from './components/steps'; |
| 35 | import Switch from './components/switch'; | 35 | import Switch from './components/switch'; |
| 36 | -// import Table from './components/table'; | 36 | +import Table from './components/table'; |
| 37 | import Tabs from './components/tabs'; | 37 | import Tabs from './components/tabs'; |
| 38 | import Tag from './components/tag'; | 38 | import Tag from './components/tag'; |
| 39 | import Timeline from './components/timeline'; | 39 | import Timeline from './components/timeline'; |
| @@ -100,6 +100,7 @@ const iview = { | @@ -100,6 +100,7 @@ const iview = { | ||
| 100 | Steps, | 100 | Steps, |
| 101 | iSwitch: Switch, | 101 | iSwitch: Switch, |
| 102 | // iTable: Table, | 102 | // iTable: Table, |
| 103 | + Table, | ||
| 103 | Tabs: Tabs, | 104 | Tabs: Tabs, |
| 104 | TabPane: Tabs.Pane, | 105 | TabPane: Tabs.Pane, |
| 105 | Tag, | 106 | Tag, |