sortablejs插件在el-table中的运用

sortablejs插件在el-table中的运用sortablejs插件在el-table中的运用概述需求有一个Table表格,由于数据是根据自增的ID进行排序显示的,有时了调整顺序会在数据库中直接操作数据表,来达到调整数据顺序的目的,因为为了实现在页面实现较为简单的拖拽排序,因此展开讨论。最后sortablejs插件可以满足需求并可以快捷的实现功能。参看资料:官网:http://www.sortablejs.com/中文文档:https://www.itxst.com/sortablejs/neuinffi.html1、安装sorta

sortablejs插件在el-table中的运用

概述需求

有一个Table表格,由于数据是根据自增的ID进行排序显示的,有时了调整顺序会在数据库中直接操作数据表,来达到调整数据顺序的目的,因为为了实现在页面实现较为简单的拖拽排序,因此展开讨论。

最后sortablejs插件可以满足需求并可以快捷的实现功能。

参看资料:

官网:http://www.sortablejs.com/

中文文档:https://www.itxst.com/sortablejs/neuinffi.html

1、安装sortablejs插件

首先引入依赖,并重启项目

npm install sortablejs --save

2、实现效果

首先看下实现的效果如下:
1、这是原来的顺序:[1, 2, 3, 4]
请添加图片描述
2、通过鼠标拖拉即可改变位置: [4, 3, 1, 2]
请添加图片描述

3、编写vue页面(文末有完整页面)

3.1、在需要编写排序的页面引入sortablejs依赖
import Sortable from 'sortablejs';
3.2、编写el-table并定义ref=“tableRef” ,ref可以理解为id
<template>
  <div class="index">
    <el-row>
      <el-col>
        <el-table :data="tableData" ref="tableRef"
                  size="small" border stripe>
          <el-table-column align="center" label="模板ID" prop="id"></el-table-column>
          <el-table-column align="center" label="模板信息" prop="mc"></el-table-column>
        </el-table>
      </el-col>
    </el-row>

    <el-row style="margin-top: 20px">
      <el-col :offset="17" :span="6">
        <el-button-group>
          <el-button size="small" type="primary" @click="save">保存</el-button>
        </el-button-group>
      </el-col>
    </el-row>
  </div>
</template>
3.3、初始化页面

tableData: 页面初始化数据
newIndexList:复制初始化table的id,后续顺序调整将会直接对其操作。

export default { 
   
  name: "index",
  components: { 
   
    Sortable
  },
  data() { 
   
    return { 
   
      // 表单数据
      tableData: [
        { 
   
          id: 1,
          mc: "模板一"
        },{ 
   
          id: 2,
          mc: "模板二"
        },{ 
   
          id: 3,
          mc: "模板三"
        },{ 
   
          id: 4,
          mc: "模板四"
        }],
      // 排序后的数据列表
      newIndexList: [],
    }
  },
  mounted() { 
   
    // 复制原Table的id按循序存储newIndexList中,
    // 每一次调整位置会对newIndexList进行位置调整。
    this.tableData.forEach( item => { 
   
      this.newIndexList.push(item.id);
    });
    //阻止火狐拖拽新建新页面
    document.body.addEventListener("drop", (event) => { 
   
      event.preventDefault();
      event.stopPropagation();
    }, false);
    this.initSortableList();
  },
  methods: { 
   
    // 更新排序
    initSortableList(){ 
   
      let el = this.$refs.tableRef.$el.querySelector('.el-table__body-wrapper tbody');
      //设置配置
      let _this = this
      Sortable .create(el, { 
   
        animation: 150,
        sort: true,
        draggable: '.el-table__row', // 设置可拖拽行的类名(el-table自带的类名)
        forceFallback: true,
        onEnd({ 
    newIndex, oldIndex}) { 
   
          let currRow = _this.newIndexList.splice(oldIndex, 1)[0];
          _this.newIndexList.splice(newIndex, 0, currRow);
        }
      })
    },
  }
}
3.4、核心部分编写排序规则

每一次鼠标拖拽Table的某一行进行排序都会执行onEnd()方法。

newIndex:行数据移动到的新位置,起始角标为0。
oldIndex: 行数据原始的位置。

举个例子:将第四行移动到第一行,执行的顺序如下:
1、首先根据取得oldIndex=3,取得第四列的id
2、将第四列的Id插入newIndex=0的位置,而后其余的数据一次后排。
3、id的变化流程为 [1, 2, 3, 4] -> [4, 1, 2, 3]

    // 更新排序
    initSortableList(){ 
   
      let el = this.$refs.tableRef.$el.querySelector('.el-table__body-wrapper tbody');
      //设置配置
      let _this = this
      Sortable .create(el, { 
   
        animation: 150,
        sort: true,
        draggable: '.el-table__row', // 设置可拖拽行的类名(el-table自带的类名)
        forceFallback: true,
        onEnd({ 
    newIndex, oldIndex}) { 
   
          let currRow = _this.newIndexList.splice(oldIndex, 1)[0];
          _this.newIndexList.splice(newIndex, 0, currRow);
        }
      })
    },
3.5、保存设置参数

执行保存操作时,我们需要将排序没有改变的行数据去除掉。以上截图为例; 显然此次排序每一行的顺序都发生了变化,所以需要修改。

tableData.id          newIndexList
     1                             4
     2                             3
     3                             1
     4                             2

基于上面数据分布格式,我们可以明白,以newIndexList为条件修改成tableData.id的值。

[
  { 
   
    "key": 4,
    "value": 1
  },{ 
   
    "key": 3,
    "value": 2
  },{ 
   
    "key": 1,
    "value": 3
  },{ 
   
    "key": 2,
    "value": 4
  }
]

如果字段id都是匹配,则说明没有进行位置调整,则不需要提交。

    //保存编辑完顺序后的数组
    save(){ 
   
      //1、封装需要更新的id <key, value> key: 原来id, value:新的id
      // 等位对比,查看templateList和newIndexList每一项ID是否对应。
      let sortList = [];
      this.tableData.forEach( (item, index) => { 
   
        if(item.id !== this.newIndexList[index]){ 
   
          sortList.push({ 
   
            key: this.newIndexList[index],
            value: item.id + 10000
          });
        }
      });
      //2、如果循序没有改变,则执行退出
      if(!sortList.length){ 
   
        return;
      }
      //3、tableData数据顺序发生变化,则提交到数据库。
    },

也许你会发现item.id + 10000这个有意思的地方,因为我们在更新排序时,修改的是主键,所以会存在主键冲突,所以先增加10000,修改完成后根据已经修改的id在执行自减10000操作,这样就可以实现主键ID的交换了。

vue代码如下:

 <template>
  <div class="index">
    <el-row>
      <el-col>
        <el-table :data="tableData" ref="tableRef" size="small" border stripe>
          <el-table-column align="center" label="模板ID" prop="id"></el-table-column>
          <el-table-column align="center" label="模板信息" prop="mc"></el-table-column>
        </el-table>
      </el-col>
    </el-row>

    <el-row style="margin-top: 20px">
      <el-col :offset="17" :span="6">
        <el-button-group>
          <el-button size="small" type="primary" @click="save">保存</el-button>
        </el-button-group>
      </el-col>
    </el-row>
  </div>
</template>
<script> import Sortable from 'sortablejs'; export default { 
      name: "index", components: { 
      Sortable }, data() { 
      return { 
      // 表单数据 tableData: [ { 
      id: 1, mc: "模板一" },{ 
      id: 2, mc: "模板二" },{ 
      id: 3, mc: "模板三" },{ 
      id: 4, mc: "模板四" }], // 排序后的数据列表 newIndexList: [], } }, mounted() { 
      // 复制原Table的id按循序存储newIndexList中, // 每一次调整位置会对newIndexList进行位置调整。 this.tableData.forEach( item => { 
      this.newIndexList.push(item.id); }); //阻止火狐拖拽新建新页面 document.body.addEventListener("drop", (event) => { 
      event.preventDefault(); event.stopPropagation(); }, false); this.initSortableList(); }, methods: { 
      // 更新排序 initSortableList(){ 
      let el = this.$refs.tableRef.$el.querySelector('.el-table__body-wrapper tbody'); //设置配置 let _this = this Sortable .create(el, { 
      animation: 150, sort: true, draggable: '.el-table__row', // 设置可拖拽行的类名(el-table自带的类名) forceFallback: true, onEnd({ 
      newIndex, oldIndex}) { 
      let currRow = _this.newIndexList.splice(oldIndex, 1)[0]; _this.newIndexList.splice(newIndex, 0, currRow); } }) }, //保存编辑完顺序后的数组 save(){ 
      //1、封装需要更新的id <key, value> key: 原来id, value:新的id // 等位对比,查看templateList和newIndexList每一项ID是否对应。 let sortList = []; this.tableData.forEach( (item, index) => { 
      if(item.id !== this.newIndexList[index]){ 
      sortList.push({ 
      key: this.newIndexList[index], value: item.id + 10000 }); } }); //2、如果循序没有改变,则执行退出 if(!sortList.length){ 
      return; } //3、tableData数据顺序发生变化,则提交到数据库。 }, }, } </script>
<style scoped> </style>

4、如何保存数据库呢

4.1、假设数据表结构如下:
CREATE TABLE demo (
	id BIGINT PRIMARY KEY auto_increment COMMENT '模板id序',
    mc VARCHAR ( 100 ) COMMENT '模板名称' 
);
4.2、使用MyBatis实现数据表ID的更新

使用的MyBatis框架,通过动态SQL实现功能。
这里需要分两步走:
第一步:将排序后的id 加上 10000并修改原来的 id。注意:这个10000的一定是你的表数据自增无法达到的数据才可以,否则会出现主键冲突(vue前端已经实现自增了,这里无需任何操作)。

UPDATE DEMO
        SET ID =
        <foreach collection="list" item="item" open="(CASE" close="END)">
            WHEN ID = #{item.key} THEN #{item.value}
        </foreach>
        WHERE ID IN
        <foreach collection="list" item="item" open="(" close=")" separator=",">
            #{item.key}
        </foreach>

第二步:将修改的ID主键数值减10000

UPDATE DEMO
        SET ID =
        <foreach collection="list" item="item" open="(CASE" close="END)">
            WHEN ID = #{item.value} THEN #{item.value} - 10000
        </foreach>
        WHERE ID IN
        <foreach collection="list" item="item" open="(" close=")" separator=",">
            #{item.value}
        </foreach>

这样便捷的排序就实现了。

希望文章能对您所有帮助,如果您觉得不错的话,点个赞呗!

今天的文章sortablejs插件在el-table中的运用分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/30594.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注