element-ui 实现table整列的拖动

演示地址

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:0;
            margin:0;
        }
        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 #666;
            z-index: 99;
        }
        .drag_active_right .virtual {
            border-right: 1px dotted #666;
            z-index: 99;
        }
        /*
            给选中要拖动的列添加背景色,如果在完整项目内部的组件,所以这个组件的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: -1, // 拖动起始元素的index
                    endIndex: -1, // 拖动结束元素的index
                    afterMoveIndex: -1, // 拖动后元素的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 === 0 ? ‘el-icon-star-off‘ : $index === 1 ? ‘el-icon-time‘ : $index === 2 ? ‘el-icon-location‘ : ‘‘,
                        }),
                        h(‘span‘, column.label)
                    ]),
                    // 给每个表头添加一个class=virtual 是画虚线的类名。
                    h(‘span‘, {
                        ‘class‘: [‘virtual‘]
                    })
                ])
            },
            // 按下鼠标开始拖动 设置列的背景色
            handleMouseDown(e, column) {
                // 判断是鼠标左键
                if (e.button === 0) {
                    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‘)[0]
                    let virtual = document.getElementsByClassName(‘virtual‘)
                    // 设置新插入的span.virtual的标签 每一列的宽度、高度
                    for (let 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) {
                    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 < 0 ? ‘left‘ : ‘right‘ // 判断拖动方向
                            this.dragState.afterMoveIndex = currentIndex
                        } else {
                            this.dragState.direction = null
                        }
                    } else {
                        return false
                    }
                }
            },
            // 鼠标放开结束拖动
            handleMouseUp(e, column) {
                // 判断是鼠标左键
                if (e.button === 0) {
                    // 拖出当前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 < 0) {
                    return;
                }
                // 判断是向左移动还是向右移动
                // 把移动的列插在某个列前面或者后面,然后在删除移动的列
                if (direction === ‘left‘) {
                    this.tableHeader.splice(endIndex, 0, this.tableHeader[startIndex])
                    this.tableHeader.splice(startIndex + 1, 1)
                } else {
                    this.tableHeader.splice(endIndex + 1, 0, this.tableHeader[startIndex])
                    this.tableHeader.splice(startIndex, 1)
                }
            },
            // 拖动完成后的初始化
            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: -1,
                    endIndex: -1,
                    afterMoveIndex: -1,
                    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(1111111)
                return columnIndex === this.dragState.afterMoveIndex ? `drag_active_${this.dragState.direction}` : ‘‘
            },
            // 动态给表头单元格th添加class,实现拖动中的背景
            cellClassName({
                column,
                columnIndex
            }) {
                console.log(22222)
                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‘
            }, 5000)
        }
    }
    var Ctor = Vue.extend(Main)
    new Ctor().$mount(‘#app‘)
</script>

</html>

原文地址:https://www.cnblogs.com/wangmaoling/p/10525048.html

时间: 2024-11-05 14:42:05

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

table 列可拖动 前端实现

drag.js var h = $('#headTable th').height(); $('.arrow-up').css({ 'margin-top': h }); var flag = false; $('#headTable th').unbind('mousedown'); $('#headTable th').mousedown(function() { let startIndex = $(this).index(); let endIndex; flag = true; $('

vue2.0 + element ui 后台管理系统

vue2.0 和 elementui  搭建的一个后台管理系统 概述: 这是一个用vuejs2.0和element搭建的后台管理界面. 技术栈: vue2.0:渐进式JavaScript框架,易用.灵活.高效,似乎任何规模的应用都适用. element ui:基于vue2.0的ui组件库. vue-router:一般单页面应用spa都要用到的前端路由. vuex:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式. webpack + es6/7 + less mock.js : 相

vue+element UI实现分页组件

1.前言 在web页面中,常常需要将后台查询到的数据以表格形式展示出来,而这些数据量往往会非常庞大,如果将所有要展示的数据一次性请求获取并展示到页面上,那页面长度势必会变得非常的长,很不美观.更重要的是,如果数据量过于大,在页面加载时一次性请求全部数据将会耗费大量网络资源,性能极低.但是,如果我们可以将数据分页展示,这样页面首先不会变的冗长,另外只有用户点击页码才会发出请求并且每次请求的数据量也不会很大,这就极大的节省了网络资源,提高了性能.本文就以vue结合element UI实现一个数据分页

element ui改写实现两棵树

使用element ui组件库实现一个table的两棵树的效果 效果如下,左边树自动展开一级,右边树默认显示楼层,然后可以一个个展开 代码如下 <el-table :data="relativeData" :fit="isFit" height="700px" :row-style="showTr" :row-class-name="tableRowClassName" :header-row-cla

关于element 框架中table表格选中并切换下一页之前选中数据消失的问题

问题描述: 在实际项目中使用element框架的table表格时,发现当前页选中了数据,点击切换下一页时,再选中数据,发现上一页选中的数据消失了.(目的是:要把用户选择的所有数据显示到页面上) 代码如下: <!-- html 代码 --> <table :data="tableData" @selection-change="handleSelectionChange" ref="multipleTable" :row-key=

Vue框架Element UI教程(二)

原文:https://www.jianshu.com/p/1704b5935a8 [时间选择器] Element UI手册:https://cloud.tencent.com/developer/doc/1270 中文文档:http://element-cn.eleme.io/#/zh-CN github地址:https://github.com/ElemeFE/element 前一篇已经安装好了Element UI环境,现在开始来实际操作框架提供的一些组件的运用了. 在准备好以下文章里面的内容

quasar框架引入element ui 组件

在使用quasar 框架时,不能满足部分需求,例如quasar不支持级联组件.table树形数据,因此引入element ui插件 .一直以为在quasar项目中执行:npm i element-ui -S然后在main.js中全局引入:,然而并不是~,这样引入使用element ui组件时会报组件未定义的"错误!",quasar 的全局配置是boot目录下,如下:查看quasar的CLI文档:正确的写法:配置完毕!!! 原文地址:https://blog.51cto.com/1356

vue模块化(echart+element ui)

最近看了下vue的框架,随手做了个项目,记录分享下 技术框架: vue.js + webpack + element ui + echart 首先看下npm package.js 上面的图 主要是配置的是npm 打包命令 和引入vue-route vue的路由文件 和element ui 文件 下面这个是 引入echart.js 文件, 基本资料就这些. 首先我们开始构建一个vue-cli项目 1.首先node环境(这里就不多啰嗦了) 2.执行vue-cli命令 npm install --gl

如何快速选中某单元格所在的整行或整列 Excel教程

我们可以使用快捷键的操作来快速选中B3单元格所在的整行或整列,操作方法如下,请大家参阅! 一.正规的快捷键操作 ①快速选中整行 按下键盘上的 Shift Space 即同时按下键盘上的Shift 空格键,这样,就能快速选中B3所在行的整行了. 操作方法注意,可先按下Shift不放,再按下空格键,这样更容易选中整行. ②快速选中整列 按下键盘上的 Ctrl Space 即同时按下键盘上的Ctrl 空格键,这样,就能快速选中B3所在行的整列了. 操作方法注意,可选按下Ctrl不放,再按下空格键,这样