vue Element-UI 的 Table 组件添加列拖动和表头显示与隐藏
vue Element-UI 的 Table 组件添加列拖动和表头显示与隐藏<template><div :class="{'w-table_moving': dragState.dragging}" class="w-table">&am
·
vue Element-UI 的 Table 组件添加列拖动和表头显示与隐藏
<template>
<div :class="{'w-table_moving': dragState.dragging}" class="w-table">
<div class="filter-container">
<el-checkbox-group v-model="checkboxVal">
<el-checkbox v-for="checkColumn in tableHeader" :label="checkColumn.label" :key="checkColumn.label"/>
</el-checkbox-group>
</div>
<el-table
:data="data"
:border="option.border"
:height="option.height"
:max-height="option.maxHeight"
:style="{ width: parseInt(option.width)+'px' }"
:cell-class-name="cellClassName"
:header-cell-class-name="headerCellClassName"
stripe
>
<slot name="fixed"/>
<el-table-column
v-for="(col, index) in formThead"
:key="index"
:prop="col.prop"
:label="col.label"
:width="col.width"
:min-width="col.minWidth"
:type="col.type"
:header-align="col.headerAlign"
:column-key="index.toString()"
:render-header="renderHeader"
show-overflow-tooltip>
<template slot-scope="scope">
{{ scope.row[col.prop] }}
</template>
</el-table-column>
<slot name="handled"/>
</el-table>
</div>
</template>
<script>
export default {
props: {
data: {
default: function() {
return []
},
type: Array
},
header: {
default: function() {
return []
},
type: Array
},
option: {
default: function() {
return {}
},
type: Object
},
defaultcheck: {
default: function() {
return []
},
type: Array
},
defaultheader: {
default: function() {
return []
},
type: Array
}
},
data() {
return {
tableHeader: this.header,
dragState: {
start: -9, // 起始元素的 index
end: -9, // 移动鼠标时所覆盖的元素 index
dragging: false, // 是否正在拖动
direction: undefined // 拖动方向
},
checkboxVal: this.defaultcheck,
formThead: this.defaultheader
}
},
watch: {
header(val, oldVal) {
this.formThead = val
},
checkboxVal(valArr) {
this.formThead = this.tableHeader.filter(i => valArr.indexOf(i.label) >= 0)
this.key = this.key + 1// 为了保证table 每次都会重渲
}
},
methods: {
renderHeader(createElement, { column }) {
return createElement(
'div', {
'class': ['thead-cell'],
on: {
mousedown: ($event) => { this.handleMouseDown($event, column) },
mousemove: ($event) => { this.handleMouseMove($event, column) }
}
}, [
// 添加 <a> 用于显示表头 label
createElement('a', column.label),
// 添加一个空标签用于显示拖动动画
createElement('span', {
'class': ['virtual']
})
])
},
// 按下鼠标开始拖动
handleMouseDown(e, column) {
this.dragState.dragging = true
this.dragState.start = parseInt(column.columnKey)
// 给拖动时的虚拟容器添加宽高
const table = document.getElementsByClassName('w-table')[0]
const virtual = document.getElementsByClassName('virtual')
for (const item of virtual) {
item.style.height = table.clientHeight - 1 + 'px'
item.style.width = item.parentElement.parentElement.clientWidth + 'px'
}
document.addEventListener('mouseup', this.handleMouseUp)
},
// 鼠标放开结束拖动
handleMouseUp() {
this.dragColumn(this.dragState)
// 初始化拖动状态
this.dragState = {
start: -9,
end: -9,
dragging: false,
direction: undefined
}
document.removeEventListener('mouseup', this.handleMouseUp)
},
// 拖动中
handleMouseMove(e, column) {
if (this.dragState.dragging) {
const index = parseInt(column.columnKey) // 记录起始列
if (index - this.dragState.start !== 0) {
this.dragState.direction = index - this.dragState.start < 0 ? 'left' : 'right' // 判断拖动方向
this.dragState.end = parseInt(column.columnKey)
} else {
this.dragState.direction = undefined
}
} else {
return false
}
},
// 拖动易位
dragColumn({ start, end, direction }) {
const tempData = []
const left = direction === 'left'
const min = left ? end : start - 1
const max = left ? start + 1 : end
for (let i = 0; i < this.formThead.length; i++) {
if (i === end) {
tempData.push(this.formThead[start])
} else if (i > min && i < max) {
tempData.push(this.formThead[ left ? i - 1 : i + 1 ])
} else {
tempData.push(this.formThead[i])
}
}
this.formThead = tempData
},
headerCellClassName({ column, columnIndex }) {
const active = columnIndex === this.dragState.end ? `darg_active_${this.dragState.direction}` : ''
const start = columnIndex === this.dragState.start ? `darg_start` : ''
return `${active} ${start}`
},
cellClassName({ column, columnIndex }) {
return (columnIndex === this.dragState.start ? `darg_start` : '')
}
}
}
</script>
<style lang="scss">
.w-table {
.el-table .darg_start {
background-color: #f3f3f3;
}
.el-table th {
padding: 0;
.virtual{
position: fixed;
display: block;
width: 0;
height: 0;
margin-left: -10px;
background: none;
border: none;
}
&.darg_active_left {
.virtual {
border-left: 2px dotted #666;
z-index: 99;
}
}
&.darg_active_right {
.virtual {
border-right: 2px dotted #666;
z-index: 99;
}
}
}
.thead-cell {
padding: 0;
display: inline-flex;
flex-direction: column;
align-items: left;
cursor: pointer;
overflow: initial;
&:before {
content: "";
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
}
&.w-table_moving {
.el-table th .thead-cell{
cursor: move !important;
}
.el-table__fixed {
cursor: not-allowed;
}
}
}
</style>
**数据处理组件**
<template>
<div class="app-container">
<wTable
v-loading="listLoading"
:data="tableData"
:header="tableHeader"
:option="tableOption"
:defaultcheck="defaultCheck"
:defaultheader="defaultHeader"
element-loading-text="Loading"
border
fit
stripe
highlight-current-row/>
</div>
</template>
import wTable from '@/views/w-table.vue'
export default {
components: {
wTable
},
data() {
return {
tableData: [{
signCode:11,
startTime:212,
startMile:11
},
{
signCode:11,
startTime:212,
startMile:11
}
],
listLoading: false,
tableOption: {
border: true
},
defaultCheck: ['车牌号', '开始时间', '开始里程'],
defaultHeader: [{
prop: 'signCode',
label: '车牌号'
}, {
prop: 'startTime',
label: '开始时间'
}, {
prop: 'startMile',
label: '开始里程'
}],
tableHeader: [{
prop: 'signCode',
label: '车牌号'
}]
}
},
更多推荐
已为社区贡献1条内容
所有评论(0)