Vue Element Sortablejs实现表格列的拖拽案例详解

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>

到此这篇关于Vue Element Sortablejs实现表格列的拖拽案例详解的文章就介绍到这了,更多相关Vue Element Sortablejs实现表格列的拖拽内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Vue+Element的后台管理框架的整合实践

    目录 Vue+ElementUI的后台管理框架 那什么是ElementUI? vue-element-admin 是一个后台前端解决方案 路由和配置左侧菜单 新开发的一个后台管理系统.在框架上,领导要用AdminLTE这套模板.这个其实很简单,把该引入的样式和js文件引入就可以了.这里就不多赘述了.可以参考官网:https://adminlte.io/ 效果图,如下: AdminLTE这个模板,还是很方便的.有兴趣的大家可以自行去琢磨.我只是把这个模板内嵌到新系统中去,也就没多去研究了. Adm

  • vue+element实现动态换肤的示例代码

    有时候一个项目的主题并不能满足所有人的审美,这时候换肤功能就很友好,本项目基于vue+element实现后台管理项目的换肤功能 1.创建换肤组件 <template> <el-color-picker class="theme-picker" popper-class="theme-picker-dropdown" v-model="theme" :predefine="predefineColors" &g

  • 使用Element+vue实现开始与结束时间限制

    本文实例为大家分享了用Element+vue实现开始与结束时间限制的具体代码,供大家参考,具体内容如下 效果 <el-form-item label="开始时间"> <el-date-picker v-model="startDate" type="datetime" placeholder="选择日期" format="yyyy-MM-dd HH:mm:ss" value-format=

  • antdesign-vue结合sortablejs实现两个table相互拖拽排序功能

    实现效果 本来想在网上看看有没有基于antdesign做的,然后发现是真的少啊!废话不多说,先上图: sortablejs介绍 首先先来认识一下这个插件: sortablejs 大家可以去细读一下它的api文档: 这边我就着重介绍一下我用到的api. 1.group可以传入对象,参数值为name,pull,put, name:如果是要两个列表下进行拖动的话,name的值必须为一样: pull:pull用来定义从这个列表容器移动出去的设置,true/false/'clone'/function t

  • Vue Element Sortablejs实现表格列的拖拽案例详解

    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-ta

  • vue+element树组件 实现树懒加载的过程详解

    一.页面样式 二.数据库 三.前端页面代码 <template> <el-tree :props="props" :load="loadNode" lazy show-checkbox> </el-tree> </template> <script> export default { data () { return { props: { label: 'name', children: 'zones',

  • vue 绑定对象,数组之数据无法动态渲染案例详解

    项目场景: 黑马vue项目管理实战,获取商品分类,展开栏的标签页中修改修改数据属性 问题描述: 在本该点击+new tag这个标签页时弹出一个input框让用户输入需要添加的属性 结果点击时却不能立马渲染 async getParametersList() { this.cat_id = this.currentSelect[this.currentSelect.length - 1]; const { data: res } = await this.$http.get( `categorie

  • Vue在echarts tooltip中添加点击事件案例详解

    目录 需求 解决方法 1.设置tooltip 2.定义hookToolTip变量 3.在methods中添加方法 4.完整代码 需求 需要在echarts tooltip点击学校的名称,跳转到详情页面:项目是从上海市---> 某个区----> 具体的学校(在最后一级的tooltip中绑定一个点击事件)  项目是用vue和echarts实现的,echarts是新版本(^5.0.2),并不能把点击事件绑定在window上 解决方法 1.设置tooltip enterable: true, //允许

  • C#组件FormDragger窗体拖拽器详解

    适用:.net2.0+ winform项目 介绍: 类似QQ.迅雷等讲究UI体验的软件,都支持在窗口内多处地方拖动窗口,而不必老实巴交的去顶部标题栏拖,这个组件就是让winform也能这样随性拖拽,随性度或更甚.先看效果: 可拖拽的地方包括不限于: 窗体.Panel.GroupBox.TabControl等容器控件的空白区: 菜单栏.工具栏.状态栏等bar的空白区,以及无效项目: Label.PictureBox.ProgressBar等通常不与鼠标交互的控件: 一切无效控件(Enabled为f

  • JavaScript使用面向对象实现的拖拽功能详解

    本文实例讲述了JavaScript使用面向对象实现的拖拽功能.分享给大家供大家参考,具体如下: 面向对象有个前提: 前提:所有东西都必须包含在onload里 改写:不能有函数嵌套,可以有全局变量 过程,如下 onload改成构造函数, 全局变量改成属性(通过this) 函数改写成方法 <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/

  • JavaScript鼠标拖拽事件详解

    本文实例为大家分享了js鼠标拖拽事件的详细实现代码,供大家参考,具体内容如下 图片如下: css代码 <style> *{ margin:0; padding:0; } #box{ width: 200px; height: 200px; background: url("./img/aio.png") no-repeat; background-size: cover; position: absolute;/*定位元素 父级元素window就是初始包含块*/ top:0

  • React结合Drag API实现拖拽示例详解

    目录 认识拖拽 被拖拽元素 可释放目标 生命周期 拖拽操作中的数据传输 代码实现 如何标记当前拖拽的元素? 在画布中拖动 数据结构 总结 认识拖拽 鼠标拖拽是一个常见的交互场景,在这个熟悉的过程将会发生哪些事件? 拖拽事件指用户通过鼠标(或其他指针设备)将元素移到一个新的位置上.拖拽过程涉及两个对象:被拖拽元素(上图中 A )和可释放目标(上图中 B ) 被拖拽元素 默认情况下,图片.链接和文本是可拖动的.HTML5 在所有 HTML 元素上规定了一个 draggable 属性, 表示元素是否可

  • Vue向下滚动加载更多数据scroll案例详解

    vue-infinite-scroll 安装 npm install vue-infinite-scroll --save 尽管官方也推荐了几种载入方式,但"最vue"的方式肯定是在main.js中加入 import infiniteScroll from 'vue-infinite-scroll' Vue.use(infiniteScroll) 实现范例 官方给的代码范例是假设你在根组件写代码,实际上我们肯定是在子组件里写代码,所以代码也需要略作修改,下方只列有用的代码片段: <

  • 封装Vue Element的table表格组件的示例详解

    在封装Vue组件时,我依旧会交叉使用函数式组件的方式来实现.关于函数式组件,我们可以把它想像成组件里的一个函数,入参是渲染上下文(render context),返回值是渲染好的HTML(VNode).它比较适用于外层组件仅仅是对内层组件的一次逻辑封装,而渲染的模板结构变化扩展不多的情况,且它一定是无状态.无实例的,无状态就意味着它没有created.mounted.updated等Vue的生命周期函数,无实例就意味着它没有响应式数据data和this上下文. 我们先来一个简单的Vue函数式组件

随机推荐