功能:1.根据底部运行低、高。。。的颜色来展示表格数据在那个颜色
测试(http://10.0.16.47:8001/#/login)
2.实现表头拖拽
v-loading="loading"
element-loading-text="拼命加载中"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.8)"
:data="tableData"
stripe
border
:height="height"
class="drag_table"
@sort-change="handleSortChange"
@row-contextmenu="rowContextmenu"
@header-dragend="headerDragend"
@row-dblclick="handleRowDblClick"
>
:current-page="currentPage"
:page-sizes="pageSizes"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
script
import ColumnTree from './ColumnTree'
export default {
name: 'DynamicTable',
components: {
ColumnTree
},
props: {
tableColumns: {
// 表头
type: Array,
default: function() {
return []
}
},
tableData: {
// 表格数据
type: Array,
default: function() {
return []
}
},
height: {
// 表格高度
type: Number,
default: 800
},
pageSizes: {
// 每页显示个数选择器的选项设置
type: Array,
default: function() {
return [20, 50, 100, 200]
}
},
pageSize: {
// 每页显示条目个数,支持 .sync 修饰符
type: Number,
default: 20
},
total: {
// 总条数
type: Number,
default: 0
},
showTableExtensions: {
// 是否显示表格扩展功能
type: Boolean,
default: false
},
loading: {
// 显示正在加载状态
type: Boolean,
default: false
}
},
data() {
return {
data: [],
pagination: {
Page: 1,
PageSize: this.pageSize,
SortName: '',
SortType: ''
},
pageOrder: 'ascending', // 排序
currentPage: 1, // 当前页
sortColumn: '', // 排序字段
tableColumnsCopy: [],
key: 1, // table key
dragState: {
startIndex: -1, // 拖动起始元素的index
endIndex: -1, // 拖动结束元素的index
afterMoveIndex: -1, // 拖动后元素的index
dragging: false, // 是否正在拖动
direction: null, // 拖动方向
moveTableOutsideBack: false // 拖出到table外之后又拖回来
}
}
},
computed: {},
watch: {
tableColumns: {
handler: function(val) {
this.tableColumnsCopy = val
},
immediate: true
},
tableData(val) {
// console.log(val)
// const idArr = [];
// val.forEach(element => {
// for (var item in element) {
// const cell = element[item];
// if (cell && typeof cell === "object") {
// idArr.push(cell.RealValue);
// }
// }
// });
}
},
created() {},
methods: {
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
// console.log(row, column, rowIndex, columnIndex)
if (columnIndex < 2) {
if (rowIndex % 2 === 0) {
return {
rowspan: 2,
colspan: 1
}
} else {
return {
rowspan: 0,
colspan: 0
}
}
}
},
spliceHead(start, end) {
this.tableColumnsCopy.splice(end, 0, this.tableColumnsCopy[start])
this.tableColumnsCopy.splice(start + 1, 1)
},
spliceHeadRight(start, end) {
this.tableColumnsCopy.splice(end + 1, 0, this.tableColumnsCopy[start])
this.tableColumnsCopy.splice(start, 1)
},
cleanDragState() {
// 再次初始化拖动状态
this.dragState = {
startIndex: -1, // 拖到的起始index
endIndex: -1,
afterMoveIndex: -1,
dragging: false, // 是否拖到
direction: null, // 拖到方向
moveTableOutsideBack: false
}
},
// 改变页尺寸时触发
handleSizeChange(val) {
this.pagination.PageSize = val
this.emitPagination()
},
// 改变当前页时触发
handleCurrentChange(val) {
// this.pagination.Page = val
// this.emitPagination()
this.$emit('handleCurrentChange', val)
},
// 自定义排序
handleSortChange(data) {
this.pagination.SortName = data.prop
if (data.column) {
// 有排序
this.pagination.SortType = data.order === 'ascending' ? 'asc' : 'desc'
this.emitPagination()
} else {
// 无排序,使用默认排序
this.pagination.SortType = 'asc'
this.pagination.SortName = ''
this.emitPagination()
}
},
// 表格双击事件
handleRowDblClick(row, column, event) {
this.$emit('handleRowDblClick', row, column.property, event)
},
// 数据刷新
emitPagination() {
// 父组件处理分页,向其传递分页参数
this.$emit('handlePageChange', this.pagination)
},
rowContextmenu(row, event, MouseEvent) {
// 父组件处理右键菜单,向其传递右键菜单参数
this.$emit('getContextMenu', row, event, MouseEvent)
},
headerDragend(newWidth, oldWidth, column) {
// 用户改变表头宽度时触发
this.$emit('headerDragend', { width: newWidth, prop: column.property })
}
}
}
表头组件columnTree
:label="columnData.name"
:prop="columnData.columnName ? columnData.columnName : ''"
:width="columnData.width"
:column-key="keyIndex.toString()"
:resizable="columnData.draggle"
header-align="center"
align="center"
:render-header="renderHead"
>
v-for="(item, index) in row.pointDetailList"
v-show="item.columnName === columnData.columnName"
:key="item.value + index"
class="dd"
:class="getDynamicCellClass(item)"
>
{{ item.value }}
{{ row[columnData.columnName] }}
script中实现拖拽事件
export default {
name: 'ColumnTree',
// draggle: false
props: {
columnData: {
// 表头
type: Object,
default: function() {
return null
}
},
keyIndex: {
type: Number,
default: 0
},
dragState: {
type: Object,
default: () => {}
}
},
methods: {
renderHead(createElement, { column, $index }) {
// 这里可以根据$index的值来对自身需求进行修改,
return createElement(
'span',
{
class: ['thead-cell'],
style: {
display: 'block',
width: '100%',
cursor: 'move'
},
on: {
mousedown: ($event) => {
this.handleMouseDown($event, column)
},
mouseup: ($event) => {
this.handleMouseUp($event, column)
},
mousemove: ($event) => {
this.handleMouseMove($event, column)
}
}
},
[
createElement('a', column.label, {
class: ['labelColor']
}),
// 给每个表头添加一个class=virtual 是画虚线的类名。
createElement('span', {
class: ['virtual']
})
]
)
},
// 按下鼠标开始拖动
handleMouseDown(e, column) {
// 判断是鼠标左键
if (e.button === 0 && column.resizable) {
this.dragState.dragging = true
this.dragState.startIndex = parseInt(column.columnKey)
// console.log(`开始移动的位置 ${this.dragState.startIndex}`)
// 给当前要拖动列的th设置class
document.querySelectorAll('.drag_table table thead tr th')[this.dragState.startIndex].className += ' ' + 'dragging_column'
// 给拖动时的虚拟容器添加宽高
const table = document.getElementsByClassName('drag_table')[0]
const virtual = document.getElementsByClassName('virtual')
// 设置新插入的span.virtual的标签 每一列的宽度、高度
for (const item of virtual) {
item.style.height = table.clientHeight - 1 + 'px'
item.style.width = item.parentElement.parentElement.clientWidth + 'px'
}
this.dragState.moveTableOutsideBack = false
}
},
// 拖动中
handleMouseMove(e, column) {
// 判断是鼠标左键
if (e.button === 0 && column.resizable) {
if (this.dragState.dragging) {
const currentIndex = parseInt(column.columnKey) // 拖动的当前列index
// console.log(`移动到了${currentIndex}`)
if (currentIndex - this.dragState.startIndex !== 0) {
this.dragState.direction =
currentIndex - this.dragState.startIndex < 0 ? 'left' : 'right' // 判断拖动方向
} else {
this.dragState.direction = null
}
} else {
return false
}
}
},
// 鼠标放开结束拖动
handleMouseUp(e, column) {
this.dragState.endIndex = parseInt(column.columnKey) // 记录结束列index
// 判断是鼠标左键
if (e.button === 0 && column.resizable) {
// 拖出当前table外之后又拖回来,不再进行易位操作(拖出去时已处理)
if (this.dragState.moveTableOutsideBack) {
return false
} else {
// console.log(`结束移动的位置 ${this.dragState.endIndex}`)
if (this.dragState.startIndex !== this.dragState.endIndex) {
this.dragColumn(this.dragState)
}
this.dragColumn(this.dragState.startIndex, this.dragState.endIndex, this.dragState.direction)
this.finishDragInit()
}
}
},
// 拖动易位
dragColumn(startIndex, endIndex, direction) {
// console.log(`从${startIndex}移动到了${endIndex}`)
// 排除掉鼠标点击table外面,然后拖入进table报错
if (startIndex < 0) {
return
}
// 判断是向左移动还是向右移动
// 把移动的列插在某个列前面或者后面,然后在删除移动的列
if (direction === 'left') {
this.$emit('spliceHead', startIndex, endIndex)
} else {
this.$emit('spliceHeadRight', startIndex, endIndex)
}
},
// 拖动完成后的初始化
finishDragInit() {
// 给当前要拖动列的th取消class
for (var item of document.querySelectorAll('.drag_table table thead tr th')) {
item.className = String(item.className).split('dragging_column').join('')
}
this.$emit('cleanDragState')
// document.removeEventListener('mouseup', this.handleMouseUp)
},
headerCellClassName({
column,
columnIndex
}) {
return columnIndex === this.dragState.afterMoveIndex ? `drag_active_${this.dragState.direction}` : ''
},
// 动态给表头单元格th添加class,实现拖动中的背景
cellClassName({
column,
columnIndex
}) {
return (columnIndex === this.dragState.startIndex ? `dragging_column` : '')
},
getDynamicCellClass(cellData) {
if (cellData.columnName !== undefined) {
const realValue = parseFloat(cellData.value)
const HiHi = cellData.accidentHigh // 事故高
const Hi = cellData.accidentLower // 事故低
const Lo = cellData.runningHigh // 运行高
const LoLo = cellData.runningLower // 运行低
if (realValue < Hi) {
return { LoLo: true }
} else if (realValue > Hi && realValue < LoLo) {
return { Lo: true }
} else if (realValue > LoLo && realValue < Lo) {
return { Normal: true }
} else if (realValue > Lo && realValue < HiHi) {
return { Hi: true }
} else if (realValue > HiHi) {
return { HiHi: true }
} else {
return { Normal: true }
}
}
}
}
}
运行参数的颜色css来设定
.LoLo {
color: var(--LoLo-color);
font-weight: bolder;
font-size: 18px;
}
.Lo {
color: var(--Lo-color);
font-weight: bolder;
font-size: 18px;
}
.Normal {
color: var(--Normal-color);
font-weight: bolder;
font-size: 18px;
}
.Hi {
color: var(--Hi-color);
font-weight: bolder;
font-size: 18px;
}
.HiHi {
color: var(--HiHi-color);
font-weight: bolder;
font-size: 18px;
}
.CommAlarm {
color: var(--comm-alarm-color);
font-weight: bolder;
font-size: 18px;
}
.dd {
animation: shake 1s;
-o-animation: shake 1s;
-webkit-animation: shake 1s;
-moz-animation: shake 1s;
}
@keyframes shake {
0%,100% {-webkit-transform: translateX(0); }
10%,30%,50%,70%, 90% {
-webkit-transform: translateX(-5px);
} 20%,40%,60%,80% {
-webkit-transform: translateX(5px);
}
}
}
而在入口文件index.css中定义颜色
:root {
--LoLo-color: #e1bb36;
--Lo-color: #7dc5eb;
--Normal-color: #5BE126;
--Hi-color: #f7680a;
--HiHi-color: #df1d1e;
--comm-alarm-color: #df1d1e;
--accident-lower: #DAE126;
--accident-high: #E13C26;
--running-low: #26DAE1;
--running-high: #E17126;
--bolt: #89A4C0;
}
min.js 中引入 import '@/styles/index.scss'
这样功能就实现了