演示地址

1. 先动态渲染表头,给每一个表头添加一个class=virtual 的画虚线的类名,同时给每个表头加上鼠标点击、拖动、抬起事件:mousedown->mousemove->mouseup.

2. 点击时确定点击的哪个,拖动的时候确定拖动的方向,抬起的时候确定放在的位置。

3. 改变数据实现拖动完成效果。

<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1.0, user-scalable=no" />
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>自定义表头样式和整列的拖动</title>
<link rel="stylesheet" href="https://unpkg.com/element-ui@2.3.7/lib/theme-chalk/index.css">
<script src="https://cdn.bootcss.com/vue/2.5.2/vue.min.js"></script>
<script src="https://unpkg.com/element-ui@2.3.7/lib/index.js"></script>
<style>
*{
padding:;
margin:;
}
body {
padding:50px;
overflow-x: hidden;
}
.thead-cell{
position: relative;
}
.drag_table th {
cursor: move;
}
.virtual {
position: fixed;
display: block;
margin-top: -35px;
margin-left: -11px;
}
.drag_active_left .virtual {
border-left: 1px dotted #;
z-index: ;
}
.drag_active_right .virtual {
border-right: 1px dotted #;
z-index: ;
}
/*
给选中要拖动的列添加背景色,如果在完整项目内部的组件,所以这个组件的style,不能加scoped,否则添加不上样式
如果使用了sass或者less,可以加scoped 然后在用特殊手法处理样式
*/
.dragging_column {
background-color: #f3f3f3 !important;
} </style>
</head> <body>
<div id="app">
<p style="text-align:center;font-size:20px;margin-bottom:50px;">自定义表头样式和整列的拖动</p>
<div @mouseleave="moveTableOutside">
<el-table class="drag_table" :data="tableData" border stripe :cell-class-name="cellClassName" :header-cell-class-name="headerCellClassName">
<el-table-column v-for="(col, index) in tableHeader" :key="index" :prop="col.prop" :label="col.label" :column-key="index.toString()" :render-header="renderHeader">
</el-table-column>
</el-table>
</div>
</div>
</body>
<script>
var Main = {
data() {
return {
tableData: [{
name: '王小虎',
date: '2016-05-02',
address: '上海市普陀区金沙江路 1518 弄'
}, {
name: '王老五',
date: '2016-05-04',
address: '上海市普陀区金沙江路 1517 弄'
}, {
name: '王大锤',
date: '2016-05-01',
address: '上海市普陀区金沙江路 1519 弄'
}, {
name: '王小龙',
date: '2016-05-03',
address: '上海市普陀区金沙江路 1516 弄'
}],
tableHeader: [{
prop: 'name',
label: '姓名'
}, {
prop: 'date',
label: '时间'
}, {
prop: 'address',
label: '地址'
}],
dragState: {
startIndex: -, // 拖动起始元素的index
endIndex: -, // 拖动结束元素的index
afterMoveIndex: -, // 拖动后元素的index
dragging: false, // 是否正在拖动
direction: null, // 拖动方向
moveTableOutsideBack: false // 拖出到table外之后又拖回来
}
}
},
methods: {
// drag_table在渲染表头时调用
renderHeader(h, {
column,
$index
}) {
// 这里可以根据$index的值来对自身需求进行修改,
return h('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)
}
}
}, [
h('span', [
// 给每个表头添加icon 可以不需要
h('span', {
class: $index === ? 'el-icon-star-off' : $index === ? 'el-icon-time' : $index === ? 'el-icon-location' : '',
}),
h('span', column.label)
]),
// 给每个表头添加一个class=virtual 是画虚线的类名。
h('span', {
'class': ['virtual']
})
])
},
// 按下鼠标开始拖动 设置列的背景色
handleMouseDown(e, column) {
// 判断是鼠标左键
if (e.button === ) {
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';
// 给拖动时的虚拟容器添加宽高
let table = document.getElementsByClassName('drag_table')[]
let virtual = document.getElementsByClassName('virtual')
// 设置新插入的span.virtual的标签 每一列的宽度、高度
for (let item of virtual) {
item.style.height = table.clientHeight - + 'px'
item.style.width = item.parentElement.parentElement.clientWidth + 'px'
}
this.dragState.moveTableOutsideBack = false
}
},
// 拖动中
handleMouseMove(e, column) {
// 判断是鼠标左键
if (e.button === ) {
if (this.dragState.dragging) {
let currentIndex = parseInt(column.columnKey) // 拖动的当前列index
console.log(`移动到了${currentIndex}`)
if (currentIndex !== this.dragState.startIndex) {
this.dragState.direction = currentIndex - this.dragState.startIndex < ? 'left' : 'right' // 判断拖动方向
this.dragState.afterMoveIndex = currentIndex
} else {
this.dragState.direction = null
}
} else {
return false
}
}
},
// 鼠标放开结束拖动
handleMouseUp(e, column) {
// 判断是鼠标左键
if (e.button === ) {
// 拖出当前table外之后又拖回来,不再进行易位操作(拖出去时已处理)
if (this.dragState.moveTableOutsideBack) {
return false
} else {
this.dragState.endIndex = parseInt(column.columnKey) // 记录结束列index
console.log(`结束移动的位置 ${this.dragState.endIndex}`)
if (this.dragState.startIndex !== this.dragState.endIndex) {
this.dragColumn(this.dragState)
}
this.finishDragInit()
}
}
},
// 拖动到当前table之外的处理
moveTableOutside() {
if (this.dragState.dragging) {
this.dragState.endIndex = this.dragState.startIndex
console.log(`已移动到table外,结束移动的位置 ${this.dragState.endIndex}`)
if (this.dragState.startIndex !== this.dragState.endIndex) {
this.dragColumn(this.dragState)
}
this.finishDragInit()
this.dragState.moveTableOutsideBack = true
}
},
// 拖动易位
dragColumn({
startIndex,
endIndex,
direction
}) {
console.log(`从${startIndex}移动到了${endIndex}`)
// 排除掉鼠标点击table外面,然后拖入进table报错
if (startIndex < ) {
return;
}
// 判断是向左移动还是向右移动
// 把移动的列插在某个列前面或者后面,然后在删除移动的列
if (direction === 'left') {
this.tableHeader.splice(endIndex, , this.tableHeader[startIndex])
this.tableHeader.splice(startIndex + , )
} else {
this.tableHeader.splice(endIndex + , , this.tableHeader[startIndex])
this.tableHeader.splice(startIndex, )
}
},
// 拖动完成后的初始化
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.dragState = {
startIndex: -,
endIndex: -,
afterMoveIndex: -,
dragging: false,
direction: null,
moveTableOutsideBack: false
}
},
// 动态给表头单元格添加 class,实现拖动中的虚线效果
/*
这个监听在table渲染的时候会执行一遍。
然后还会有两个条件会触发执行:
1. 绑定的数据发生变化的时候(即为表格内容变化就触发)。header变化触发header-cell-class-name,表格数据变化触发cell-class-name.
2. return返回值 如果绑定了data,如果此data变化也会触发执行。相当于对这个data进行了监听随之触发这个方法。
*/

headerCellClassName({
column,
columnIndex
}) {
console.log()
return columnIndex === this.dragState.afterMoveIndex ? `drag_active_${this.dragState.direction}` : ''
},
// 动态给表头单元格th添加class,实现拖动中的背景
cellClassName({
column,
columnIndex
}) {
console.log()
return (columnIndex === this.dragState.startIndex ? `dragging_column` : '')
},
},
mounted() {
var that = this;
setTimeout(function() {
// that.tableHeader[0].label = 'wwwwww';
// that.tableData[0].name = 'wwwwww';
// console.log()
// console.log(document.querySelectorAll('.drag_table .el-table_2_column_4')[0])
// document.querySelectorAll('.drag_table table thead tr th')[0].className += ' ' + 'dragging_column';
// that.dragState.startIndex = '1'
}, )
}
}
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')
</script> </html>

element-ui 实现table整列的拖动的更多相关文章

  1. 怎么样使element ui 的table某列变色

    第一步.在el-table里面加上:row-style="rowClass" <el-table :data="targetCarList" border ...

  2. (Element UI 组件 Table)去除单元格底部的横线

    Element UI 组件 Table 有一个属性 border,添加它可以增加纵向边框,但是无法控制横线边框,因此即使是最简单的 el-table,也会包含一个底部横线. 这个底部横线其实是一个 b ...

  3. Element UI的Table用法

    Table 表格 用于展示多条结构类似的数据,可对数据进行排序.筛选.对比或其他自定义操作. ¶基础表格 基 2016-05-02 王小虎 上海市普陀区金沙江路 1518 弄 2016-05-04 王 ...

  4. Element Ui中table实现表格编辑效果

    主要以css实现 .tb-edit .el-input, .tb-edit .el-input-number, .tb-edit .el-select { display: none; width: ...

  5. element ui 合计/table show-summary

    在el-table 上面加上show-summary就可以对table的数据进行合计 但是上次出现了合计栏有的为空,有的合计不对的情况,如果出现的是空,那么说明你渲染的数据有undefine(即后台返 ...

  6. element ui里面table分页,页数从0开始的怎么做?

    需求: 后台请求的接口是从0页开始的,但是pagination是从1开始的,就是在点击pagination的第1页是后台转0 1首先在data里面定义为1,其他地方也是定义1 return { for ...

  7. element ui的table的头部自定义

    <el-table-column label="级别" min-width="120" prop="clueLevel" align= ...

  8. 普通element ui table组件的使用

    1.使用基础的element ui 的table的基础使用 首先,使用前要先引用element库到项目中,可以直接引入element的js和css或者在vue项目下按需加载不同的组件 废话不多说,直接 ...

  9. Element UI表格组件技巧:如何简洁实现跨页勾选、跨页统计功能

    业务场景 在使用Element UI的Table组件时,常常面对这样的业务需求: 表格数据的每一项都要提供勾选框,当切换分页时,能够记忆所有页面勾选的数据,以实现批量提交不同页面勾选数据的功能.并且, ...

随机推荐

  1. MongoDB 博客截图之二

    使用内置帮助help() 基本命令示例 来源:MongoDB基本管理命令 - 千与的专栏 - 博客频道 - CSDN.NET

  2. 把pcl的VTK显示融合到MFC(代码找原作者)

    转自PCL中国,原文链接:http://www.pclcn.org/bbs/forum.php?mod=viewthread&tid=223&extra=page%3D1 本人做了少量 ...

  3. Spring中xml文档的schema约束

    最开始使用Spring框架的时候,对于其配置文件xml,只是网上得知其使用方法,而不明其意.最近想着寻根问底的探究一下.以下是本文主要内容: 1.配置文件示例.   <?xml version= ...

  4. 路飞学城Python-Day181

    Evernote Export Nginx默认网站 当Nginx配置文件中有且仅有一个Server的时候,该Server就被Nginx认为是默认网站,所有发给Nginx服务器80端口的数据都会默认给s ...

  5. When you hit a wall, just kick it in.

    Teach Yourself Programming in Ten Years. ----- Peter Norvig Teach Yourself Programming in Ten Years  ...

  6. python中的网页标签等字符处理

    # -*- coding: utf-8-*- import re ##过滤HTML中的标签 #将HTML中标签等信息去掉 #@param htmlstr HTML字符串. def filter_tag ...

  7. CENTOS 7发送邮件测试

    centos7作为126邮箱客户端发送邮件测试. 首先安装客户端软件: yum install sendmail mailx -y 配置邮箱设置: 开启smtp发件协议 配置授权码,写入配置文件. 追 ...

  8. 深入了解Python--元组

    1. 对原元组进行插入 2. 元组的嵌套使用 3. for循环使用嵌套元组实例 4. 命名元组避免对分片混淆

  9. RobotFrameWork+APPIUM实现对安卓APK的自动化测试----第六篇【AppiumLibrary等待函数介绍】

    http://blog.csdn.net/deadgrape/article/details/50622441 废话不多说,少年们请看下面. Wait Until Page Contains text ...

  10. 对Java线程安全与不安全的理解

    当我们查看JDK API的时候,总会发现一些类说明写着,线程安全或者线程不安全,比如说到StringBuilder中,有这么一句,"将StringBuilder 的实例用于多个线程是不安全的 ...