时间:2022-08-18 11:58:01 | 栏目:vue | 点击:次
1. css: dragTable.css
@charset "UTF-8"; .w-table{ height: 100%; width: 100%; float: left; } /* 拖动过程中,鼠标显示样式 */ .w-table_moving .el-table th .thead-cell{ cursor: move !important; } .w-table_moving .el-table__fixed{ cursor: not-allowed; } .w-table .thead-cell{ display: inline-flex; flex-direction: column; align-items: center; width: auto; max-height: 23px; vertical-align: middle; overflow: initial; position: relative; }
2. 封装组件: dragTable.vue
<template> <div class="w-table" :class="{'w-table_moving': dragState.dragging}"> <el-table :data="data" :ref="option.ref" :class="option.class" :stripe="option.stripe" :border="option.border" :height="option.height" :max-height="option.maxHeight" highlight-current-row :style="{ width: parseInt(option.width)+'px' }" :cell-class-name="cellClassName" :header-cell-class-name="headerCellClassName" @sort-change="option.sortChange" > <slot name="fixed"></slot> <template v-for="(col, index) in tableHeader"> <el-table-column :label="col.label" :key="index" :prop="col.prop" :width="col.width" v-if="col.useTemplate==true"> <template slot-scope="scope"> <span v-html=col.useTemplateRes(scope.row)></span> </template> </el-table-column> <el-table-column v-else :key="index" :prop="col.prop" :label="col.label" :width="col.width" :min-width="col.minWidth" :type="col.type" :sortable="col.sortable" :header-align="col.headerAlign" :align="col.align" :column-key="index.toString()" :render-header="renderHeader" show-overflow-tooltip :formatter="col.formatter" > </el-table-column> <el-table-column :label="v.name" :key="k" :prop="v.prop" :width="v.width" v-else></el-table-column> </template> <!--<el-table-column v-for="(col, index) in tableHeader" :key="index" :prop="col.prop" :label="col.label" :width="col.width" :min-width="col.minWidth" :type="col.type" :sortable="col.sortable" :header-align="col.headerAlign" :align="col.align" :column-key="index.toString()" :render-header="renderHeader" show-overflow-tooltip :formatter="col.formatter" > </el-table-column>--> </el-table> </div> </template> <script> import Sortable from 'sortablejs' export default { name: "", data () { return { tableHeader: this.header, dragState: { start: -9, // 起始元素的 index end: -9, // 移动鼠标时所覆盖的元素 index dragging: false, // 是否正在拖动 direction: undefined // 拖动方向 } } }, props: { data: { default: function () { return [] }, type: Array }, header: { default: function () { return [] }, type: Array }, option: { default: function () { return {} }, type: Object } }, mounted() { }, watch: { header (val, oldVal) { this.tableHeader = val } }, 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('span', column.label), // 添加一个空标签用于显示拖动动画 createElement('span', { 'class': ['virtual'] }) ]) }, // 按下鼠标开始拖动 handleMouseDown (e, column) { this.dragState.dragging = true this.dragState.start = parseInt(column.columnKey) // 给拖动时的虚拟容器添加宽高 let table = document.getElementsByClassName('w-table')[0] let virtual = document.getElementsByClassName('virtual') for (let item of virtual) { item.style.height = table.clientHeight - 1 + 'px' // item.style.width = item.parentElement.parentElement.clientWidth + 'px' item.style.width = item.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) { let 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}) { let tempData = [] let left = direction === 'left' let min = left ? end : start - 1 let max = left ? start + 1 : end for (let i = 0; i < this.tableHeader.length; i++) { if (i === end) { tempData.push(this.tableHeader[start]) } else if (i > min && i < max) { tempData.push(this.tableHeader[ left ? i - 1 : i + 1 ]) } else { tempData.push(this.tableHeader[i]) } } this.tableHeader = tempData }, headerCellClassName ({column, columnIndex}) { let active = columnIndex - 1 === this.dragState.end ? `darg_active_${this.dragState.direction}` : '' let start = columnIndex - 1 === this.dragState.start ? `darg_start` : '' return `${active} ${start}` }, cellClassName ({column, columnIndex}) { return (columnIndex - 1 === this.dragState.start ? `darg_start` : '') }, }, } </script> <style > @import '~@/assets/css/dragTable.css'; </style>
3. 调用封装组件
<template> <div> <wTable :data="WarnResTable_Data_SS" :header="tableHeaderSS" :option="tableOptionSS"> <el-table-column type="index" slot="fixed" fixed prop="" label="序号" align="center" width="60" > </el-table-column> <el-table-column label="操作" slot="fixed" fixed prop="" width="95" align="center"> <template slot-scope="scope"> <el-button size="mini" @click="lookDetails(scope.$index, scope.row)">查看 </el-button> </template> </el-table-column> </wTable> </div> </template> <script> import wTable from '../../components/dragTable/dragTable' export default { name: 'Table', data () { return { tableOptionSS: { border: true, stripe: true, ref:'WarnResSSTable', class:'pms-table', maxHeight: "100%", height: "100%", sortChange:this.changeTableSortSS }, tableHeaderSS: [ { label: '地市名称', prop: 'dsmc', sortable: true, align:'center', width:'200', }, { label: '运维单位', prop: 'ywdw', align:'center', width:'200', }, { label: '变电站', prop: 'bdzmc', align:'center', width:'170', }, { label: '设备名称', prop: 'sbmc', sortable: true, align:'center', width:'150', }, { label: '预警参数', prop: 'yjcs', align:'center', width:'150', }, { label: '预警类型', prop: 'yjlx', align:'center', width:'140', }, { label: '首次预警时间', prop: 'scyjsj', sortable:true, align:'center', width:'160', formatter:this.formatTime }, { label: '更新数据时间', prop: 'dqyjsj', sortable:true, align:'center', width:'160', formatter:this.formatTime }, { label: '预警描述', prop: 'yjgz', align:'center', width:'170', }, { label: '设备类型', prop: 'sblx', sortable:true, align:'center', width:'140', }, { label: '电压等级', prop: 'dydjid', sortable:true, align:'center', width:'120', formatter:this.formatVoltageLevel } ], WarnResTable_Data_SS:[ {dsmc:'dsmc1',sbmc:'sbmc1',dydjid:'hhhhh1'}, {dsmc:'dsmc2',sbmc:'sbmc2',dydjid:'hhhhh2'}, {dsmc:'dsmc3',sbmc:'sbmc3',dydjid:'hhhhh3'} ], } }, methods: { handleNameSort () { console.log('handleNameSort') }, formatVoltageLevel: function (row, column) { let val = row[column.property]; if (val == undefined) { return ""; } console.log('val ') return '5555' }, changeTableSortSS(column){ console.log(' sortHandle column',column) }, formatTime: function (row, column) { let date = row[column.property]; if (date == undefined) { return ""; } return date?moment(new Date(date)).format('YYYY-MM-DD HH:MM:SS'):''; }, formatVoltageLevel: function (row, column) { let val = row[column.property]; if (val == undefined) { return ""; } return val+'kV' }, }, components: { wTable } } </script>