update the master branch to the latest
This commit is contained in:
parent
67d534df27
commit
23a0ba9831
611 changed files with 122648 additions and 0 deletions
124
src/components/table/cell.vue
Normal file
124
src/components/table/cell.vue
Normal file
|
@ -0,0 +1,124 @@
|
|||
<template>
|
||||
<div :class="classes" ref="cell">
|
||||
<template v-if="renderType === 'index'"><span>{{ column.indexMethod ? column.indexMethod(row) : (naturalIndex + 1) }}</span></template>
|
||||
<template v-if="renderType === 'selection'">
|
||||
<Checkbox :value="checked" @click.native.stop="handleClick" @on-change="toggleSelect" :disabled="disabled"></Checkbox>
|
||||
</template>
|
||||
<template v-if="renderType === 'html'"><span v-html="row[column.key]"></span></template>
|
||||
<template v-if="renderType === 'normal'">
|
||||
<template v-if="column.tooltip">
|
||||
<Tooltip transfer :content="row[column.key]" :theme="tableRoot.tooltipTheme" :disabled="!showTooltip" :max-width="300" class="ivu-table-cell-tooltip">
|
||||
<span ref="content" @mouseenter="handleTooltipIn" @mouseleave="handleTooltipOut" class="ivu-table-cell-tooltip-content">{{ row[column.key] }}</span>
|
||||
</Tooltip>
|
||||
</template>
|
||||
<span v-else>{{row[column.key]}}</span>
|
||||
</template>
|
||||
<template v-if="renderType === 'expand' && !row._disableExpand">
|
||||
<div :class="expandCls" @click="toggleExpand">
|
||||
<Icon type="ios-arrow-forward"></Icon>
|
||||
</div>
|
||||
</template>
|
||||
<table-expand
|
||||
v-if="renderType === 'render'"
|
||||
:row="row"
|
||||
:column="column"
|
||||
:index="index"
|
||||
:render="column.render"></table-expand>
|
||||
<table-slot
|
||||
v-if="renderType === 'slot'"
|
||||
:row="row"
|
||||
:column="column"
|
||||
:index="index"></table-slot>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import TableExpand from './expand';
|
||||
import TableSlot from './slot';
|
||||
import Icon from '../icon/icon.vue';
|
||||
import Checkbox from '../checkbox/checkbox.vue';
|
||||
import Tooltip from '../tooltip/tooltip.vue';
|
||||
|
||||
export default {
|
||||
name: 'TableCell',
|
||||
components: { Icon, Checkbox, TableExpand, TableSlot, Tooltip },
|
||||
inject: ['tableRoot'],
|
||||
props: {
|
||||
prefixCls: String,
|
||||
row: Object,
|
||||
column: Object,
|
||||
naturalIndex: Number, // index of rebuildData
|
||||
index: Number, // _index of data
|
||||
checked: Boolean,
|
||||
disabled: Boolean,
|
||||
expanded: Boolean,
|
||||
fixed: {
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
renderType: '',
|
||||
uid: -1,
|
||||
context: this.$parent.$parent.$parent.currentContext,
|
||||
showTooltip: false, // 鼠标滑过overflow文本时,再检查是否需要显示
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
classes () {
|
||||
return [
|
||||
`${this.prefixCls}-cell`,
|
||||
{
|
||||
[`${this.prefixCls}-hidden`]: !this.fixed && this.column.fixed && (this.column.fixed === 'left' || this.column.fixed === 'right'),
|
||||
[`${this.prefixCls}-cell-ellipsis`]: this.column.ellipsis || false,
|
||||
[`${this.prefixCls}-cell-with-expand`]: this.renderType === 'expand',
|
||||
[`${this.prefixCls}-cell-with-selection`]: this.renderType === 'selection'
|
||||
}
|
||||
];
|
||||
},
|
||||
expandCls () {
|
||||
return [
|
||||
`${this.prefixCls}-cell-expand`,
|
||||
{
|
||||
[`${this.prefixCls}-cell-expand-expanded`]: this.expanded
|
||||
}
|
||||
];
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggleSelect () {
|
||||
this.$parent.$parent.$parent.toggleSelect(this.index);
|
||||
},
|
||||
toggleExpand () {
|
||||
this.$parent.$parent.$parent.toggleExpand(this.index);
|
||||
},
|
||||
handleClick () {
|
||||
// 放置 Checkbox 冒泡
|
||||
},
|
||||
handleTooltipIn () {
|
||||
const $content = this.$refs.content;
|
||||
this.showTooltip = $content.scrollWidth > $content.offsetWidth;
|
||||
},
|
||||
handleTooltipOut () {
|
||||
this.showTooltip = false;
|
||||
}
|
||||
},
|
||||
created () {
|
||||
if (this.column.type === 'index') {
|
||||
this.renderType = 'index';
|
||||
} else if (this.column.type === 'selection') {
|
||||
this.renderType = 'selection';
|
||||
} else if (this.column.type === 'html') {
|
||||
this.renderType = 'html';
|
||||
} else if (this.column.type === 'expand') {
|
||||
this.renderType = 'expand';
|
||||
} else if (this.column.render) {
|
||||
this.renderType = 'render';
|
||||
} else if (this.column.slot) {
|
||||
this.renderType = 'slot';
|
||||
} else {
|
||||
this.renderType = 'normal';
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
21
src/components/table/expand.js
Normal file
21
src/components/table/expand.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
export default {
|
||||
name: 'TableExpand',
|
||||
functional: true,
|
||||
props: {
|
||||
row: Object,
|
||||
render: Function,
|
||||
index: Number,
|
||||
column: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
render: (h, ctx) => {
|
||||
const params = {
|
||||
row: ctx.props.row,
|
||||
index: ctx.props.index
|
||||
};
|
||||
if (ctx.props.column) params.column = ctx.props.column;
|
||||
return ctx.props.render(h, params);
|
||||
}
|
||||
};
|
76
src/components/table/export-csv.js
Normal file
76
src/components/table/export-csv.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
function has (browser) {
|
||||
const ua = navigator.userAgent;
|
||||
if (browser === 'ie') {
|
||||
const isIE = ua.indexOf('compatible') > -1 && ua.indexOf('MSIE') > -1;
|
||||
if (isIE) {
|
||||
const reIE = new RegExp('MSIE (\\d+\\.\\d+);');
|
||||
reIE.test(ua);
|
||||
return parseFloat(RegExp['$1']);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return ua.indexOf(browser) > -1;
|
||||
}
|
||||
}
|
||||
|
||||
const csv = {
|
||||
_isIE11 () {
|
||||
let iev = 0;
|
||||
const ieold = (/MSIE (\d+\.\d+);/.test(navigator.userAgent));
|
||||
const trident = !!navigator.userAgent.match(/Trident\/7.0/);
|
||||
const rv = navigator.userAgent.indexOf('rv:11.0');
|
||||
|
||||
if (ieold) {
|
||||
iev = Number(RegExp.$1);
|
||||
}
|
||||
if (navigator.appVersion.indexOf('MSIE 10') !== -1) {
|
||||
iev = 10;
|
||||
}
|
||||
if (trident && rv !== -1) {
|
||||
iev = 11;
|
||||
}
|
||||
|
||||
return iev === 11;
|
||||
},
|
||||
|
||||
_isEdge () {
|
||||
return /Edge/.test(navigator.userAgent);
|
||||
},
|
||||
|
||||
_getDownloadUrl (text) {
|
||||
const BOM = '\uFEFF';
|
||||
// Add BOM to text for open in excel correctly
|
||||
if (window.Blob && window.URL && window.URL.createObjectURL) {
|
||||
const csvData = new Blob([BOM + text], { type: 'text/csv' });
|
||||
return URL.createObjectURL(csvData);
|
||||
} else {
|
||||
return 'data:attachment/csv;charset=utf-8,' + BOM + encodeURIComponent(text);
|
||||
}
|
||||
},
|
||||
|
||||
download (filename, text) {
|
||||
if (has('ie') && has('ie') < 10) {
|
||||
// has module unable identify ie11 and Edge
|
||||
const oWin = window.top.open('about:blank', '_blank');
|
||||
oWin.document.charset = 'utf-8';
|
||||
oWin.document.write(text);
|
||||
oWin.document.close();
|
||||
oWin.document.execCommand('SaveAs', filename);
|
||||
oWin.close();
|
||||
} else if (has('ie') === 10 || this._isIE11() || this._isEdge()) {
|
||||
const BOM = '\uFEFF';
|
||||
const csvData = new Blob([BOM + text], { type: 'text/csv' });
|
||||
navigator.msSaveBlob(csvData, filename);
|
||||
} else {
|
||||
const link = document.createElement('a');
|
||||
link.download = filename;
|
||||
link.href = this._getDownloadUrl(text);
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default csv;
|
16
src/components/table/header.js
Normal file
16
src/components/table/header.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
export default {
|
||||
name: 'TableRenderHeader',
|
||||
functional: true,
|
||||
props: {
|
||||
render: Function,
|
||||
column: Object,
|
||||
index: Number
|
||||
},
|
||||
render: (h, ctx) => {
|
||||
const params = {
|
||||
column: ctx.props.column,
|
||||
index: ctx.props.index
|
||||
};
|
||||
return ctx.props.render(h, params);
|
||||
}
|
||||
};
|
2
src/components/table/index.js
Normal file
2
src/components/table/index.js
Normal file
|
@ -0,0 +1,2 @@
|
|||
import Table from './table.vue';
|
||||
export default Table;
|
31
src/components/table/mixin.js
Normal file
31
src/components/table/mixin.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
export default {
|
||||
methods: {
|
||||
alignCls (column, row = {}) {
|
||||
let cellClassName = '';
|
||||
if (row.cellClassName && column.key && row.cellClassName[column.key]) {
|
||||
cellClassName = row.cellClassName[column.key];
|
||||
}
|
||||
return [
|
||||
{
|
||||
[`${cellClassName}`]: cellClassName, // cell className
|
||||
[`${column.className}`]: column.className, // column className
|
||||
[`${this.prefixCls}-column-${column.align}`]: column.align,
|
||||
[`${this.prefixCls}-hidden`]: (this.fixed === 'left' && column.fixed !== 'left') || (this.fixed === 'right' && column.fixed !== 'right') || (!this.fixed && column.fixed && (column.fixed === 'left' || column.fixed === 'right'))
|
||||
}
|
||||
];
|
||||
},
|
||||
isPopperShow (column) {
|
||||
return column.filters && ((!this.fixed && !column.fixed) || (this.fixed === 'left' && column.fixed === 'left') || (this.fixed === 'right' && column.fixed === 'right'));
|
||||
},
|
||||
setCellWidth (column) {
|
||||
let width = '';
|
||||
if (column.width) {
|
||||
width = column.width;
|
||||
} else if (this.columnsWidth[column._index]) {
|
||||
width = this.columnsWidth[column._index].width;
|
||||
}
|
||||
if (width === '0') width = '';
|
||||
return width;
|
||||
}
|
||||
}
|
||||
};
|
20
src/components/table/slot.js
Normal file
20
src/components/table/slot.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
export default {
|
||||
name: 'TableSlot',
|
||||
functional: true,
|
||||
inject: ['tableRoot'],
|
||||
props: {
|
||||
row: Object,
|
||||
index: Number,
|
||||
column: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
render: (h, ctx) => {
|
||||
return h('div', ctx.injections.tableRoot.$scopedSlots[ctx.props.column.slot]({
|
||||
row: ctx.props.row,
|
||||
column: ctx.props.column,
|
||||
index: ctx.props.index
|
||||
}));
|
||||
}
|
||||
};
|
110
src/components/table/table-body.vue
Normal file
110
src/components/table/table-body.vue
Normal file
|
@ -0,0 +1,110 @@
|
|||
<template>
|
||||
<table cellspacing="0" cellpadding="0" border="0" :style="styleObject">
|
||||
<colgroup>
|
||||
<col v-for="(column, index) in columns" :width="setCellWidth(column)">
|
||||
</colgroup>
|
||||
<tbody :class="[prefixCls + '-tbody']">
|
||||
<template v-for="(row, index) in data">
|
||||
<table-tr
|
||||
:draggable="draggable"
|
||||
:row="row"
|
||||
:key="rowKey ? row._rowKey : index"
|
||||
:prefix-cls="prefixCls"
|
||||
@mouseenter.native.stop="handleMouseIn(row._index)"
|
||||
@mouseleave.native.stop="handleMouseOut(row._index)"
|
||||
@click.native="clickCurrentRow(row._index)"
|
||||
@dblclick.native.stop="dblclickCurrentRow(row._index)">
|
||||
<td v-for="column in columns" :class="alignCls(column, row)">
|
||||
<table-cell
|
||||
:fixed="fixed"
|
||||
:prefix-cls="prefixCls"
|
||||
:row="row"
|
||||
:key="column._columnKey"
|
||||
:column="column"
|
||||
:natural-index="index"
|
||||
:index="row._index"
|
||||
:checked="rowChecked(row._index)"
|
||||
:disabled="rowDisabled(row._index)"
|
||||
:expanded="rowExpanded(row._index)"
|
||||
></table-cell>
|
||||
</td>
|
||||
</table-tr>
|
||||
<tr v-if="rowExpanded(row._index)" :class="{[prefixCls + '-expanded-hidden']: fixed}">
|
||||
<td :colspan="columns.length" :class="prefixCls + '-expanded-cell'">
|
||||
<Expand :key="rowKey ? row._rowKey : index" :row="row" :render="expandRender" :index="row._index"></Expand>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
<script>
|
||||
// todo :key="row"
|
||||
import TableTr from './table-tr.vue';
|
||||
import TableCell from './cell.vue';
|
||||
import Expand from './expand.js';
|
||||
import Mixin from './mixin';
|
||||
|
||||
export default {
|
||||
name: 'TableBody',
|
||||
mixins: [ Mixin ],
|
||||
components: { TableCell, Expand, TableTr },
|
||||
props: {
|
||||
prefixCls: String,
|
||||
styleObject: Object,
|
||||
columns: Array,
|
||||
data: Array, // rebuildData
|
||||
objData: Object,
|
||||
columnsWidth: Object,
|
||||
fixed: {
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
},
|
||||
draggable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
rowKey: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
expandRender () {
|
||||
let render = function () {
|
||||
return '';
|
||||
};
|
||||
for (let i = 0; i < this.columns.length; i++) {
|
||||
const column = this.columns[i];
|
||||
if (column.type && column.type === 'expand') {
|
||||
if (column.render) render = column.render;
|
||||
}
|
||||
}
|
||||
return render;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
rowChecked (_index) {
|
||||
return this.objData[_index] && this.objData[_index]._isChecked;
|
||||
},
|
||||
rowDisabled(_index){
|
||||
return this.objData[_index] && this.objData[_index]._isDisabled;
|
||||
},
|
||||
rowExpanded(_index){
|
||||
return this.objData[_index] && this.objData[_index]._isExpanded;
|
||||
},
|
||||
handleMouseIn (_index) {
|
||||
this.$parent.handleMouseIn(_index);
|
||||
},
|
||||
handleMouseOut (_index) {
|
||||
this.$parent.handleMouseOut(_index);
|
||||
},
|
||||
clickCurrentRow (_index) {
|
||||
this.$parent.clickCurrentRow(_index);
|
||||
},
|
||||
dblclickCurrentRow (_index) {
|
||||
this.$parent.dblclickCurrentRow(_index);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
228
src/components/table/table-head.vue
Normal file
228
src/components/table/table-head.vue
Normal file
|
@ -0,0 +1,228 @@
|
|||
<template>
|
||||
<table cellspacing="0" cellpadding="0" border="0" :style="styles">
|
||||
<colgroup>
|
||||
<col v-for="(column, index) in columns" :width="setCellWidth(column)">
|
||||
<col v-if="$parent.showVerticalScrollBar" :width="$parent.scrollBarWidth"/>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr v-for="(cols, rowIndex) in headRows">
|
||||
<th
|
||||
v-for="(column, index) in cols"
|
||||
:colspan="column.colSpan"
|
||||
:rowspan="column.rowSpan"
|
||||
:class="alignCls(column)">
|
||||
<div :class="cellClasses(column)">
|
||||
<template v-if="column.type === 'expand'">
|
||||
<span v-if="!column.renderHeader">{{ column.title || '' }}</span>
|
||||
<render-header v-else :render="column.renderHeader" :column="column" :index="index"></render-header>
|
||||
</template>
|
||||
<template v-else-if="column.type === 'selection'"><Checkbox :value="isSelectAll" :disabled="isSelectDisabled" @on-change="selectAll"></Checkbox></template>
|
||||
<template v-else>
|
||||
<span v-if="!column.renderHeader" :class="{[prefixCls + '-cell-sort']: column.sortable}" @click="handleSortByHead(getColumn(rowIndex, index)._index)">{{ column.title || '#' }}</span>
|
||||
<render-header v-else :render="column.renderHeader" :column="column" :index="index"></render-header>
|
||||
<span :class="[prefixCls + '-sort']" v-if="column.sortable">
|
||||
<i class="ivu-icon ivu-icon-md-arrow-dropup" :class="{on: getColumn(rowIndex, index)._sortType === 'asc'}" @click="handleSort(getColumn(rowIndex, index)._index, 'asc')"></i>
|
||||
<i class="ivu-icon ivu-icon-md-arrow-dropdown" :class="{on: getColumn(rowIndex, index)._sortType === 'desc'}" @click="handleSort(getColumn(rowIndex, index)._index, 'desc')"></i>
|
||||
</span>
|
||||
<Poptip
|
||||
v-if="isPopperShow(column)"
|
||||
v-model="getColumn(rowIndex, index)._filterVisible"
|
||||
placement="bottom"
|
||||
popper-class="ivu-table-popper"
|
||||
transfer
|
||||
@on-popper-hide="handleFilterHide(getColumn(rowIndex, index)._index)">
|
||||
<span :class="[prefixCls + '-filter']">
|
||||
<i class="ivu-icon ivu-icon-ios-funnel" :class="{on: getColumn(rowIndex, index)._isFiltered}"></i>
|
||||
</span>
|
||||
|
||||
<div slot="content" :class="[prefixCls + '-filter-list']" v-if="getColumn(rowIndex, index)._filterMultiple">
|
||||
<div :class="[prefixCls + '-filter-list-item']">
|
||||
<checkbox-group v-model="getColumn(rowIndex, index)._filterChecked">
|
||||
<checkbox v-for="(item, index) in column.filters" :key="index" :label="item.value">{{ item.label }}</checkbox>
|
||||
</checkbox-group>
|
||||
</div>
|
||||
<div :class="[prefixCls + '-filter-footer']">
|
||||
<i-button type="text" size="small" :disabled="!getColumn(rowIndex, index)._filterChecked.length" @click.native="handleFilter(getColumn(rowIndex, index)._index)">{{ t('i.table.confirmFilter') }}</i-button>
|
||||
<i-button type="text" size="small" @click.native="handleReset(getColumn(rowIndex, index)._index)">{{ t('i.table.resetFilter') }}</i-button>
|
||||
</div>
|
||||
</div>
|
||||
<div slot="content" :class="[prefixCls + '-filter-list']" v-else>
|
||||
<ul :class="[prefixCls + '-filter-list-single']">
|
||||
<li
|
||||
:class="itemAllClasses(getColumn(rowIndex, index))"
|
||||
@click="handleReset(getColumn(rowIndex, index)._index)">{{ t('i.table.clearFilter') }}</li>
|
||||
<li
|
||||
:class="itemClasses(getColumn(rowIndex, index), item)"
|
||||
v-for="item in column.filters"
|
||||
@click="handleSelect(getColumn(rowIndex, index)._index, item.value)">{{ item.label }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Poptip>
|
||||
</template>
|
||||
</div>
|
||||
</th>
|
||||
|
||||
<th v-if="$parent.showVerticalScrollBar && rowIndex===0" :class='scrollBarCellClass()' :rowspan="headRows.length"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</template>
|
||||
<script>
|
||||
import CheckboxGroup from '../checkbox/checkbox-group.vue';
|
||||
import Checkbox from '../checkbox/checkbox.vue';
|
||||
import Poptip from '../poptip/poptip.vue';
|
||||
import iButton from '../button/button.vue';
|
||||
import renderHeader from './header';
|
||||
import Mixin from './mixin';
|
||||
import Locale from '../../mixins/locale';
|
||||
|
||||
export default {
|
||||
name: 'TableHead',
|
||||
mixins: [ Mixin, Locale ],
|
||||
components: { CheckboxGroup, Checkbox, Poptip, iButton, renderHeader },
|
||||
props: {
|
||||
prefixCls: String,
|
||||
styleObject: Object,
|
||||
columns: Array,
|
||||
objData: Object,
|
||||
data: Array, // rebuildData
|
||||
columnsWidth: Object,
|
||||
fixed: {
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
},
|
||||
columnRows: Array,
|
||||
fixedColumnRows: Array
|
||||
},
|
||||
computed: {
|
||||
styles () {
|
||||
const style = Object.assign({}, this.styleObject);
|
||||
const width = parseInt(this.styleObject.width) ;
|
||||
style.width = `${width}px`;
|
||||
return style;
|
||||
},
|
||||
isSelectAll () {
|
||||
let isSelectAll = true;
|
||||
if (!this.data.length) isSelectAll = false;
|
||||
if (!this.data.find(item => !item._disabled)) isSelectAll = false; // #1751
|
||||
for (let i = 0; i < this.data.length; i++) {
|
||||
if (!this.objData[this.data[i]._index]._isChecked && !this.objData[this.data[i]._index]._isDisabled) {
|
||||
isSelectAll = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return isSelectAll;
|
||||
},
|
||||
headRows () {
|
||||
const isGroup = this.columnRows.length > 1;
|
||||
if (isGroup) {
|
||||
return this.fixed ? this.fixedColumnRows : this.columnRows;
|
||||
} else {
|
||||
return [this.columns];
|
||||
}
|
||||
},
|
||||
isSelectDisabled () {
|
||||
let isSelectDisabled = false;
|
||||
if (!this.data.length) isSelectDisabled = true;
|
||||
if (!this.data.find(item => !item._disabled)) isSelectDisabled = true;
|
||||
return isSelectDisabled;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
cellClasses (column) {
|
||||
return [
|
||||
`${this.prefixCls}-cell`,
|
||||
{
|
||||
[`${this.prefixCls}-hidden`]: !this.fixed && column.fixed && (column.fixed === 'left' || column.fixed === 'right'),
|
||||
[`${this.prefixCls}-cell-with-selection`]: column.type === 'selection'
|
||||
}
|
||||
];
|
||||
},
|
||||
scrollBarCellClass(){
|
||||
let hasRightFixed = false;
|
||||
for(let i in this.headRows){
|
||||
for(let j in this.headRows[i]){
|
||||
if(this.headRows[i][j].fixed === 'right') {
|
||||
hasRightFixed=true;
|
||||
break;
|
||||
}
|
||||
if(hasRightFixed) break;
|
||||
}
|
||||
}
|
||||
return [
|
||||
{
|
||||
[`${this.prefixCls}-hidden`]: hasRightFixed
|
||||
}
|
||||
];
|
||||
},
|
||||
itemClasses (column, item) {
|
||||
return [
|
||||
`${this.prefixCls}-filter-select-item`,
|
||||
{
|
||||
[`${this.prefixCls}-filter-select-item-selected`]: column._filterChecked[0] === item.value
|
||||
}
|
||||
];
|
||||
},
|
||||
itemAllClasses (column) {
|
||||
return [
|
||||
`${this.prefixCls}-filter-select-item`,
|
||||
{
|
||||
[`${this.prefixCls}-filter-select-item-selected`]: !column._filterChecked.length
|
||||
}
|
||||
];
|
||||
},
|
||||
selectAll () {
|
||||
const status = !this.isSelectAll;
|
||||
this.$parent.selectAll(status);
|
||||
},
|
||||
handleSort (index, type) {
|
||||
// 在固定列时,寻找正确的 index #5580
|
||||
const column = this.columns.find(item => item._index === index);
|
||||
const _index = column._index;
|
||||
|
||||
if (column._sortType === type) {
|
||||
type = 'normal';
|
||||
}
|
||||
this.$parent.handleSort(_index, type);
|
||||
},
|
||||
handleSortByHead (index) {
|
||||
// 在固定列时,寻找正确的 index #5580
|
||||
const column = this.columns.find(item => item._index === index);
|
||||
if (column.sortable) {
|
||||
const type = column._sortType;
|
||||
if (type === 'normal') {
|
||||
this.handleSort(index, 'asc');
|
||||
} else if (type === 'asc') {
|
||||
this.handleSort(index, 'desc');
|
||||
} else {
|
||||
this.handleSort(index, 'normal');
|
||||
}
|
||||
}
|
||||
},
|
||||
handleFilter (index) {
|
||||
this.$parent.handleFilter(index);
|
||||
},
|
||||
handleSelect (index, value) {
|
||||
this.$parent.handleFilterSelect(index, value);
|
||||
},
|
||||
handleReset (index) {
|
||||
this.$parent.handleFilterReset(index);
|
||||
},
|
||||
handleFilterHide (index) {
|
||||
this.$parent.handleFilterHide(index);
|
||||
},
|
||||
// 因为表头嵌套不是深拷贝,所以没有 _ 开头的方法,在 isGroup 下用此列
|
||||
getColumn (rowIndex, index) {
|
||||
const isGroup = this.columnRows.length > 1;
|
||||
|
||||
if (isGroup) {
|
||||
const id = this.headRows[rowIndex][index].__id;
|
||||
return this.columns.filter(item => item.__id === id)[0];
|
||||
} else {
|
||||
return this.headRows[rowIndex][index];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
44
src/components/table/table-tr.vue
Normal file
44
src/components/table/table-tr.vue
Normal file
|
@ -0,0 +1,44 @@
|
|||
<template>
|
||||
<tr :class="rowClasses(row._index)" :draggable="draggable" @dragstart="onDrag($event,row._index)" @drop="onDrop($event,row._index)" @dragover="allowDrop($event)" v-if="draggable"><slot></slot></tr>
|
||||
<tr :class="rowClasses(row._index)" v-else><slot></slot></tr>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
row: Object,
|
||||
prefixCls: String,
|
||||
draggable: Boolean
|
||||
},
|
||||
computed: {
|
||||
objData () {
|
||||
return this.$parent.objData;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onDrag (e,index) {
|
||||
e.dataTransfer.setData('index',index);
|
||||
},
|
||||
onDrop (e,index) {
|
||||
const dragIndex = e.dataTransfer.getData('index');
|
||||
this.$parent.$parent.dragAndDrop(dragIndex,index);
|
||||
e.preventDefault();
|
||||
},
|
||||
allowDrop (e) {
|
||||
e.preventDefault();
|
||||
},
|
||||
rowClasses (_index) {
|
||||
return [
|
||||
`${this.prefixCls}-row`,
|
||||
this.rowClsName(_index),
|
||||
{
|
||||
[`${this.prefixCls}-row-highlight`]: this.objData[_index] && this.objData[_index]._isHighlight,
|
||||
[`${this.prefixCls}-row-hover`]: this.objData[_index] && this.objData[_index]._isHover
|
||||
}
|
||||
];
|
||||
},
|
||||
rowClsName (_index) {
|
||||
return this.$parent.$parent.rowClassName(this.objData[_index], _index);
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
1024
src/components/table/table.vue
Normal file
1024
src/components/table/table.vue
Normal file
File diff suppressed because it is too large
Load diff
93
src/components/table/util.js
Normal file
93
src/components/table/util.js
Normal file
|
@ -0,0 +1,93 @@
|
|||
import { deepCopy } from '../../utils/assist';
|
||||
|
||||
const convertColumnOrder = (columns, fixedType) => {
|
||||
let list = [];
|
||||
let other = [];
|
||||
columns.forEach((col) => {
|
||||
if (col.fixed && col.fixed === fixedType) {
|
||||
list.push(col);
|
||||
} else {
|
||||
other.push(col);
|
||||
}
|
||||
});
|
||||
return list.concat(other);
|
||||
};
|
||||
|
||||
export {convertColumnOrder};
|
||||
|
||||
// set forTableHead to true when convertToRows, false in normal cases like table.vue
|
||||
const getAllColumns = (cols, forTableHead = false) => {
|
||||
const columns = deepCopy(cols);
|
||||
const result = [];
|
||||
columns.forEach((column) => {
|
||||
if (column.children) {
|
||||
if (forTableHead) result.push(column);
|
||||
result.push.apply(result, getAllColumns(column.children, forTableHead));
|
||||
} else {
|
||||
result.push(column);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
export {getAllColumns};
|
||||
|
||||
const convertToRows = (columns, fixedType = false) => {
|
||||
const originColumns = fixedType ? fixedType === 'left' ? deepCopy(convertColumnOrder(columns, 'left')) : deepCopy(convertColumnOrder(columns, 'right')) : deepCopy(columns);
|
||||
let maxLevel = 1;
|
||||
const traverse = (column, parent) => {
|
||||
if (parent) {
|
||||
column.level = parent.level + 1;
|
||||
if (maxLevel < column.level) {
|
||||
maxLevel = column.level;
|
||||
}
|
||||
}
|
||||
if (column.children) {
|
||||
let colSpan = 0;
|
||||
column.children.forEach((subColumn) => {
|
||||
traverse(subColumn, column);
|
||||
colSpan += subColumn.colSpan;
|
||||
});
|
||||
column.colSpan = colSpan;
|
||||
} else {
|
||||
column.colSpan = 1;
|
||||
}
|
||||
};
|
||||
|
||||
originColumns.forEach((column) => {
|
||||
column.level = 1;
|
||||
traverse(column);
|
||||
});
|
||||
|
||||
const rows = [];
|
||||
for (let i = 0; i < maxLevel; i++) {
|
||||
rows.push([]);
|
||||
}
|
||||
|
||||
const allColumns = getAllColumns(originColumns, true);
|
||||
|
||||
allColumns.forEach((column) => {
|
||||
if (!column.children) {
|
||||
column.rowSpan = maxLevel - column.level + 1;
|
||||
} else {
|
||||
column.rowSpan = 1;
|
||||
}
|
||||
rows[column.level - 1].push(column);
|
||||
});
|
||||
|
||||
return rows;
|
||||
};
|
||||
|
||||
export {convertToRows};
|
||||
|
||||
const getRandomStr = function (len = 32) {
|
||||
const $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
|
||||
const maxPos = $chars.length;
|
||||
let str = '';
|
||||
for (let i = 0; i < len; i++) {
|
||||
str += $chars.charAt(Math.floor(Math.random() * maxPos));
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
||||
export {getRandomStr};
|
Loading…
Add table
Add a link
Reference in a new issue