Merge remote-tracking branch 'upstream/master' into clean-css
This commit is contained in:
commit
6dee0a655c
7 changed files with 228 additions and 125 deletions
|
@ -1,16 +1,24 @@
|
|||
<template>
|
||||
<div :class="[prefixCls + '-cell']">
|
||||
<div :class="classes">
|
||||
<template v-if="renderType === 'index'">{{index + 1}}</template>
|
||||
<template v-if="renderType === 'selection'">
|
||||
<Checkbox :checked="checked" @on-change="toggleSelect(index)"></Checkbox>
|
||||
</template>
|
||||
<template v-if="renderType === 'normal'">{{{ row[column.key] }}}</template>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Checkbox from '../checkbox/checkbox.vue';
|
||||
|
||||
export default {
|
||||
components: { Checkbox },
|
||||
props: {
|
||||
prefixCls: String,
|
||||
row: Object,
|
||||
column: Object,
|
||||
index: Number
|
||||
index: Number,
|
||||
checked: Boolean,
|
||||
fixed: Boolean
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
|
@ -18,34 +26,51 @@
|
|||
uid: -1
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
classes () {
|
||||
return [
|
||||
`${this.prefixCls}-cell`,
|
||||
{
|
||||
[`${this.prefixCls}-hidden`]: !this.fixed && this.column.fixed && (this.column.fixed === 'left' || this.column.fixed === 'right')
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
compile () {
|
||||
if (this.column.render) {
|
||||
const $parent = this.$parent.$parent.$parent;
|
||||
const template = this.column.render(this.row, this.column, this.index);
|
||||
const cell = document.createElement('div');
|
||||
cell.innerHTML = template;
|
||||
const _oldParentChildLen = this.$parent.$parent.$children.length;
|
||||
this.$parent.$parent.$compile(cell);
|
||||
const _newParentChildLen = this.$parent.$parent.$children.length;
|
||||
const _oldParentChildLen = $parent.$children.length;
|
||||
$parent.$compile(cell);
|
||||
const _newParentChildLen = $parent.$children.length;
|
||||
|
||||
if (_oldParentChildLen !== _newParentChildLen) { // if render normal html node, do not tag
|
||||
this.uid = this.$parent.$parent.$children[this.$parent.$parent.$children.length - 1]._uid; // tag it, and delete when data or columns update
|
||||
this.uid = $parent.$children[$parent.$children.length - 1]._uid; // tag it, and delete when data or columns update
|
||||
}
|
||||
this.$el.innerHTML = '';
|
||||
this.$el.appendChild(cell);
|
||||
}
|
||||
},
|
||||
destroy () {
|
||||
for (let i = 0; i < this.$parent.$parent.$children.length; i++) {
|
||||
if (this.$parent.$parent.$children[i]._uid === this.uid) {
|
||||
this.$parent.$parent.$children[i].$destroy();
|
||||
const $parent = this.$parent.$parent.$parent;
|
||||
for (let i = 0; i < $parent.$children.length; i++) {
|
||||
if ($parent.$children[i]._uid === this.uid) {
|
||||
$parent.$children[i].$destroy();
|
||||
}
|
||||
}
|
||||
},
|
||||
toggleSelect (index) {
|
||||
this.$parent.$parent.toggleSelect(index);
|
||||
}
|
||||
},
|
||||
compiled () {
|
||||
if (this.column.type === 'index') {
|
||||
this.renderType = 'index';
|
||||
} else if (this.column.type === 'selection') {
|
||||
this.renderType = 'selection';
|
||||
} else if (this.column.render) {
|
||||
this.renderType = 'render';
|
||||
} else {
|
||||
|
|
|
@ -1,21 +1,59 @@
|
|||
<template>
|
||||
|
||||
<table cellspacing="0" cellpadding="0" border="0" :style="style">
|
||||
<colgroup>
|
||||
<col v-for="column in columns" :width="setCellWidth(column, $index)">
|
||||
</colgroup>
|
||||
<tbody :class="[prefixCls + '-tbody']">
|
||||
<tr
|
||||
v-for="(index, row) in data"
|
||||
:class="[prefixCls + '-row', rowClsName(index), {[prefixCls + '-row-highlight']: cloneData[index] && cloneData[index]._isHighlight, [prefixCls + '-row-hover']: cloneData[index] && cloneData[index]._isHover}]"
|
||||
@mouseenter.stop="handleMouseIn(index)"
|
||||
@mouseleave.stop="handleMouseOut(index)"
|
||||
@click.stop="highlightCurrentRow(index)">
|
||||
<td v-for="column in columns" :class="alignCls(column)">
|
||||
<Cell
|
||||
:fixed="fixed"
|
||||
:prefix-cls="prefixCls"
|
||||
:row="row"
|
||||
:column="column"
|
||||
:index="index"
|
||||
:checked="cloneData[index] && cloneData[index]._isChecked"></Cell>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
<script>
|
||||
import Cell from './cell.vue';
|
||||
import Mixin from './mixin';
|
||||
|
||||
export default {
|
||||
mixins: [ Mixin ],
|
||||
components: { Cell },
|
||||
props: {
|
||||
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
prefixCls: String,
|
||||
style: Object,
|
||||
columns: Array,
|
||||
data: Array,
|
||||
cloneData: Array,
|
||||
fixed: Boolean
|
||||
},
|
||||
methods: {
|
||||
|
||||
setCellWidth (column, index) {
|
||||
return this.$parent.setCellWidth(column, index);
|
||||
},
|
||||
rowClsName (index) {
|
||||
return this.$parent.rowClassName(this.data[index], index);
|
||||
},
|
||||
handleMouseIn (index) {
|
||||
this.$parent.handleMouseIn(index);
|
||||
},
|
||||
handleMouseOut (index) {
|
||||
this.$parent.handleMouseOut(index);
|
||||
},
|
||||
highlightCurrentRow (index) {
|
||||
this.$parent.highlightCurrentRow(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,21 +0,0 @@
|
|||
<template>
|
||||
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,14 +1,19 @@
|
|||
<template>
|
||||
<thead>
|
||||
<tr>
|
||||
<th v-for="column in columns" :class="alignCls(column)">
|
||||
<div :class="[prefixCls + '-cell']">
|
||||
<template v-if="column.type === 'selection'"><Checkbox :checked="isSelectAll" @on-change="selectAll"></Checkbox></template>
|
||||
<template v-else>{{{ renderHeader(column, $index) }}}</template>
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<table cellspacing="0" cellpadding="0" border="0" :style="style">
|
||||
<colgroup>
|
||||
<col v-for="column in columns" :width="setCellWidth(column, $index)">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th v-for="column in columns" :class="alignCls(column)">
|
||||
<div :class="[prefixCls + '-cell', {[prefixCls + '-hidden']: !fixed && column.fixed && (column.fixed === 'left' || column.fixed === 'right')}]">
|
||||
<template v-if="column.type === 'selection'"><Checkbox :checked="isSelectAll" @on-change="selectAll"></Checkbox></template>
|
||||
<template v-else>{{{ renderHeader(column, $index) }}}</template>
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</template>
|
||||
<script>
|
||||
import Checkbox from '../checkbox/checkbox.vue';
|
||||
|
@ -20,13 +25,10 @@
|
|||
components: { Checkbox },
|
||||
props: {
|
||||
prefixCls: String,
|
||||
style: Object,
|
||||
columns: Array,
|
||||
cloneData: Array
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
|
||||
}
|
||||
cloneData: Array,
|
||||
fixed: Boolean
|
||||
},
|
||||
computed: {
|
||||
isSelectAll () {
|
||||
|
@ -34,6 +36,9 @@
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
setCellWidth (column, index) {
|
||||
return this.$parent.setCellWidth(column, index);
|
||||
},
|
||||
renderHeader (column, $index) {
|
||||
if ('renderHeader' in this.columns[$index]) {
|
||||
return this.columns[$index].renderHeader(column, $index);
|
||||
|
@ -43,16 +48,17 @@
|
|||
},
|
||||
selectAll () {
|
||||
const status = !this.isSelectAll;
|
||||
this.$parent.selectAll(status);
|
||||
|
||||
let tmpData = deepCopy(this.cloneData);
|
||||
tmpData.forEach((data) => {
|
||||
data._isChecked = status;
|
||||
});
|
||||
this.cloneData = tmpData;
|
||||
|
||||
if (status) {
|
||||
this.$parent.selectAll();
|
||||
}
|
||||
// let tmpData = deepCopy(this.cloneData);
|
||||
// tmpData.forEach((data) => {
|
||||
// data._isChecked = status;
|
||||
// });
|
||||
// this.cloneData = tmpData;
|
||||
//
|
||||
// if (status) {
|
||||
// this.$parent.selectAll();
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,68 +2,63 @@
|
|||
<div :class="classes" :style="styles">
|
||||
<div :class="[prefixCls + '-title']" v-if="showSlotHeader" v-el:title><slot name="header"></slot></div>
|
||||
<div :class="[prefixCls + '-header']" v-if="showHeader" v-el:header @mousewheel="handleMouseWheel">
|
||||
<table cellspacing="0" cellpadding="0" border="0" :style="tableStyle">
|
||||
<colgroup>
|
||||
<col v-for="column in cloneColumns" :width="setCellWidth(column, $index)">
|
||||
</colgroup>
|
||||
<thead
|
||||
is="table-head"
|
||||
:prefix-cls="prefixCls"
|
||||
:clone-data.sync="cloneData"
|
||||
:columns="cloneColumns"></thead>
|
||||
</table>
|
||||
<table-head
|
||||
:prefix-cls="prefixCls"
|
||||
:style="tableStyle"
|
||||
:columns="cloneColumns"
|
||||
:clone-data="cloneData"></table-head>
|
||||
</div>
|
||||
<div :class="[prefixCls + '-body']" :style="bodyStyle" @scroll="handleBodyScroll">
|
||||
<table cellspacing="0" cellpadding="0" border="0" :style="tableStyle" v-el:tbody>
|
||||
<colgroup>
|
||||
<col v-for="column in cloneColumns" :width="setCellWidth(column, $index)">
|
||||
</colgroup>
|
||||
<tbody :class="[prefixCls + '-tbody']" v-el:render>
|
||||
<tr
|
||||
v-for="(index, row) in data"
|
||||
:class="[prefixCls + '-row', rowClsName(index), {[prefixCls + '-row-highlight']: cloneData[index] && cloneData[index]._isHighlight, [prefixCls + '-row-hover']: cloneData[index] && cloneData[index]._isHover}]"
|
||||
@mouseenter.stop="handleMouseIn(index)"
|
||||
@mouseleave.stop="handleMouseOut(index)"
|
||||
@click.stop="highlightCurrentRow(index)">
|
||||
<td v-for="column in cloneColumns" :class="alignCls(column)">
|
||||
<div :class="[prefixCls + '-cell']" v-if="column.type === 'selection'">
|
||||
<Checkbox :checked="cloneData[index] && cloneData[index]._isChecked" @on-change="toggleSelect(index)"></Checkbox>
|
||||
</div>
|
||||
<Cell v-else :prefix-cls="prefixCls" :row="row" :column="column" :index="index"></Cell>
|
||||
<!--<div :class="[prefixCls + '-cell']" v-else>-->
|
||||
<!--{{{ renderRow(row, column, index) }}}-->
|
||||
<!--</div>-->
|
||||
<!--<div :class="[prefixCls + '-cell']">-->
|
||||
<!--<template v-if="column.type === 'selection'">-->
|
||||
<!--<Checkbox :checked="cloneData[index] && cloneData[index]._isChecked" @on-change="toggleSelect(index)"></Checkbox>-->
|
||||
<!--</template>-->
|
||||
<!--<template v-else>{{{ renderRow(row, column, index) }}}</template>-->
|
||||
<!--</div>-->
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div :class="[prefixCls + '-body']" :style="bodyStyle" v-el:body @scroll="handleBodyScroll">
|
||||
<table-body
|
||||
v-ref:tbody
|
||||
:prefix-cls="prefixCls"
|
||||
:style="tableStyle"
|
||||
:columns="cloneColumns"
|
||||
:data="data"
|
||||
:clone-data="cloneData"></table-body>
|
||||
</div>
|
||||
<div :class="[prefixCls + '-fixed']">
|
||||
|
||||
<!--todo 设置个div头部-->
|
||||
<table-head
|
||||
fixed
|
||||
:prefix-cls="prefixCls"
|
||||
:style="fixedTableStyle"
|
||||
:columns="leftFixedColumns"
|
||||
:clone-data="cloneData"></table-head>
|
||||
<table-body
|
||||
fixed
|
||||
:prefix-cls="prefixCls"
|
||||
:style="fixedTableStyle"
|
||||
:columns="leftFixedColumns"
|
||||
:data="data"
|
||||
:clone-data="cloneData"></table-body>
|
||||
</div>
|
||||
<div :class="[prefixCls + '-fixed-right']">
|
||||
|
||||
<table-head
|
||||
fixed
|
||||
:prefix-cls="prefixCls"
|
||||
:style="fixedRightTableStyle"
|
||||
:columns="rightFixedColumns"
|
||||
:clone-data="cloneData"></table-head>
|
||||
<table-body
|
||||
fixed
|
||||
:prefix-cls="prefixCls"
|
||||
:style="fixedRightTableStyle"
|
||||
:columns="rightFixedColumns"
|
||||
:data="data"
|
||||
:clone-data="cloneData"></table-body>
|
||||
</div>
|
||||
<div :class="[prefixCls + '-footer']" v-if="showSlotFooter" v-el:footer><slot name="footer"></slot></div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import TableHead from './table-head.vue';
|
||||
import Checkbox from '../checkbox/checkbox.vue';
|
||||
import Cell from './cell.vue';
|
||||
import Mixin from './mixin';
|
||||
import tableHead from './table-head.vue';
|
||||
import tableBody from './table-body.vue';
|
||||
import { oneOf, getStyle, deepCopy } from '../../utils/assist';
|
||||
const prefixCls = 'ivu-table';
|
||||
|
||||
export default {
|
||||
mixins: [ Mixin ],
|
||||
components: { TableHead, Checkbox, Cell },
|
||||
components: { tableHead, tableBody },
|
||||
props: {
|
||||
data: {
|
||||
type: Array,
|
||||
|
@ -82,6 +77,9 @@
|
|||
return oneOf(value, ['small', 'large']);
|
||||
}
|
||||
},
|
||||
width: {
|
||||
type: [Number, String]
|
||||
},
|
||||
height: {
|
||||
type: [Number, String]
|
||||
},
|
||||
|
@ -141,6 +139,7 @@
|
|||
styles () {
|
||||
let style = {};
|
||||
if (!!this.height) style.height = `${this.height}px`;
|
||||
if (!!this.width) style.width = `${this.width}px`;
|
||||
return style;
|
||||
},
|
||||
tableStyle () {
|
||||
|
@ -148,6 +147,16 @@
|
|||
if (this.tableWidth !== 0) style.width = `${this.tableWidth}px`;
|
||||
return style;
|
||||
},
|
||||
fixedTableStyle () {
|
||||
let style = {};
|
||||
if (this.leftFixedColumns.length) style.width = this.leftFixedColumns.reduce((a, b) => a + b);
|
||||
return style;
|
||||
},
|
||||
fixedRightTableStyle () {
|
||||
let style = {};
|
||||
if (this.rightFixedColumns.length) style.width = this.rightFixedColumns.reduce((a, b) => a + b);
|
||||
return style;
|
||||
},
|
||||
bodyStyle () {
|
||||
let style = {};
|
||||
if (this.bodyHeight !== 0) style.height = `${this.bodyHeight}px`;
|
||||
|
@ -171,7 +180,7 @@
|
|||
let autoWidthIndex = -1;
|
||||
if (allWidth) autoWidthIndex = this.cloneColumns.findIndex(cell => !cell.width);
|
||||
|
||||
const $td = this.$els.tbody.querySelectorAll('tbody tr')[0].querySelectorAll('td');
|
||||
const $td = this.$refs.tbody.$el.querySelectorAll('tbody tr')[0].querySelectorAll('td');
|
||||
for (let i = 0; i < $td.length; i++) { // can not use forEach in Firefox
|
||||
if (i === autoWidthIndex) {
|
||||
this.columnsWidth.push(parseInt(getStyle($td[i], 'width')) - 1);
|
||||
|
@ -241,8 +250,16 @@
|
|||
}
|
||||
this.$emit('on-selection-change', selection);
|
||||
},
|
||||
selectAll () {
|
||||
this.$emit('on-select-all', this.getSelection());
|
||||
selectAll (status) {
|
||||
let tmpData = deepCopy(this.cloneData);
|
||||
tmpData.forEach((data) => {
|
||||
data._isChecked = status;
|
||||
});
|
||||
this.cloneData = tmpData;
|
||||
|
||||
if (status) {
|
||||
this.$emit('on-select-all', this.getSelection());
|
||||
}
|
||||
},
|
||||
fixedHeader () {
|
||||
if (!!this.height) {
|
||||
|
@ -277,8 +294,15 @@
|
|||
|
||||
// todo 固定时上下滚动,固定的表头也滚动 scrollTop
|
||||
},
|
||||
handleMouseWheel () {
|
||||
console.log(111)
|
||||
handleMouseWheel (event) {
|
||||
const deltaX = event.deltaX;
|
||||
const $body = this.$els.body;
|
||||
|
||||
if (deltaX > 0) {
|
||||
$body.scrollLeft = $body.scrollLeft + 10;
|
||||
} else {
|
||||
$body.scrollLeft = $body.scrollLeft - 10;
|
||||
}
|
||||
}
|
||||
},
|
||||
compiled () {
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
border: 1px solid @border-color-base;
|
||||
border-bottom: 0;
|
||||
border-right: 0;
|
||||
border-collapse: collapse;
|
||||
//border-collapse: collapse;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
|
@ -130,6 +130,9 @@
|
|||
word-break: break-all;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
&-hidden{
|
||||
visibility: hidden;
|
||||
}
|
||||
th &-cell{
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
|
@ -186,4 +189,29 @@
|
|||
background-color: @table-td-highlight-bg;
|
||||
}
|
||||
}
|
||||
|
||||
&-fixed, &-fixed-right{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
box-shadow: 1px 0 8px #d3d4d6;
|
||||
overflow-x: hidden;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background-color: @border-color-base;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
z-index: 4;
|
||||
}
|
||||
}
|
||||
&-fixed-right{
|
||||
top: 0;
|
||||
left: auto;
|
||||
right: 0;
|
||||
box-shadow: -1px 0 8px #d3d4d6;
|
||||
}
|
||||
}
|
|
@ -8,9 +8,8 @@
|
|||
<!--<i-table size="large" border stripe :columns="columns" :data="data"></i-table>-->
|
||||
<br>
|
||||
<i-table
|
||||
style="width:450px"
|
||||
width="450"
|
||||
border
|
||||
highlight-row
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
:row-class-name="rowClsName"
|
||||
|
@ -37,6 +36,10 @@
|
|||
type: 'selection',
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
type: 'index',
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
title: '姓名',
|
||||
key: 'name',
|
||||
|
@ -48,7 +51,7 @@
|
|||
title: '年龄',
|
||||
key: 'age',
|
||||
align: 'right',
|
||||
fixed: 'left',
|
||||
// fixed: 'left',
|
||||
width: 100
|
||||
// render (row) {
|
||||
// return `<i-button>${row.age}</i-button>`
|
||||
|
@ -142,7 +145,7 @@
|
|||
},
|
||||
ready () {
|
||||
setTimeout(() => {
|
||||
return;
|
||||
// return;
|
||||
// this.height = 150;
|
||||
// return
|
||||
// this.data.push({
|
||||
|
@ -151,7 +154,7 @@
|
|||
// address: '北京市东城区2',
|
||||
// edit: false
|
||||
// });
|
||||
this.data.splice(1, 1)
|
||||
// this.data.splice(1, 1)
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue