5

拖拽插件sortable.js之el-table表格拖拽效果代码

 2 years ago
source link: https://segmentfault.com/a/1190000041361366
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Sortable.js是一款优秀的js拖拽库,因为是原生js写的,所以性能不错,也支持移动端哦。本文举两个案例来学习一下。

案例一 简单拖拽

关于理解看注释哦,运行的话复制粘贴即可

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <title>sortable.js拖动例子</title>
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, minimal-ui">
    <!-- 引入插件 -->
    <script src="https://www.itxst.com/package/sortable/sortable.min.js"></script>
    <style>
        #wrapBox {
            width: 360px;
            /* 拖动容器的高度,由拖动项的高度撑开 */
            height: auto;
        }

        #wrapBox div {
            padding: 8px;
            background-color: #fdfdfd;
            border: solid 1px #eee;
            margin-bottom: 10px;
            /* 添加鼠标悬浮样式为移动的样式,要不然不好看 */
            cursor: move;
            font-size: 13px;
        }

        /* 设置鼠标按下时候的样式,加了好看些 */
        #wrapBox div:active {
            background-color: #eee;
        }
    </style>
</head>

<body>
    <h2>优先扣款顺序:</h2>
    <!-- 一般来说,拖动的结构就是:外边一个拖动容器,里面是一个又一个的拖动项 -->
    <div id="wrapBox">
        <div data-id="1工商银行">工商银行</div>
        <div data-id="2建设银行">建设银行</div>
        <div data-id="3中国银行">中国银行</div>
        <div data-id="4农业银行">农业银行</div>
        <div data-id="5交通银行">交通银行</div>
    </div>
    <script>
        //第一步,获取拖动容器
        var wrap = document.getElementById('wrapBox');
        //第二步,设置拖动项的拖动规则
        var rules = {
            animation: 500, // 拖动时的元素的位置变化的动画时长,
            //拖动结束后的回调函数
            onEnd: function (event) {
                console.log('参数是拖动事件对象', event);
                //获取拖动后容器中的每一项的位置排序
                var arr = sortable.toArray();
                console.log('位置排序', arr);
            },
        };
        //第三步,初始化 --> 给拖动容器添加拖动规则 
        var sortable = Sortable.create(wrap, rules);
        /**
         * 插件自带的方法:
         *      1. sortable.toArray() 获取序列化后的每个item元素的id属性的数组
         *      2. Sortable.create(wrap, rules) 给拖动容器添加拖动规则
         * */
    </script>
</body>

</html>

案例二 el-table表格拖拽

这里有一个细节,就是表头数据拖动的时候,可能导致渲染数据不对的问题,有的博主是搞两个表头数组数据的,其实也是一种解决问题的方案。不过个人愚见略有麻烦,其实一个表头数组数据即可。只要及时清空,重新赋值即可

这里使用的是vue,所以要下载哦 cnpm install sortablejs --save

代码直接复制粘贴即可运行看效果图了,关于使用请看注释哦

<template>
  <div class="myWrap">
    <el-table
      :data="tableBody"
      border
      row-key="id"
      :header-cell-style="{
        height: '48px',
        background: '#FAFAFA',
        color: '#333333',
        fontWeight: 'bold',
        fontSize: '14px',
      }"
    >
      <!-- 勾选框列 -->
      <el-table-column type="selection" width="48" fixed></el-table-column>
      <!-- 序号列 -->
      <el-table-column label="序号" type="index" width="50" fixed>
      </el-table-column>
      <!-- 表头列 -->
      <el-table-column
        v-for="(item, index) in tableHeader"
        :key="item.index"
        :prop="item.prop"
        :label="item.label"
      >
      </el-table-column>
    </el-table>
    <br />
    <h3>表头数据</h3>
    <pre>{{ tableHeader }}</pre>
    <br />
    <h3>表体数据</h3>
    <pre>{{ tableBody }}</pre>
  </div>
</template>
<script>
// 引入sortablejs插件,拖拽主要靠的是这个插件
import Sortable from "sortablejs";
export default {
  data() {
    return {
      // 表头数据
      tableHeader: [
        {
          label: "姓名",
          prop: "name",
        },
        {
          label: "年龄",
          prop: "age",
        },
        {
          label: "家乡",
          prop: "home",
        },
        {
          label: "爱好",
          prop: "hobby",
        },
      ],
      // 表体数据
      tableBody: [
        {
          id: "1",
          name: "孙悟空",
          age: 500,
          home: "花果山",
          hobby: "吃桃子",
        },
        {
          id: "2",
          name: "猪八戒",
          age: 88,
          home: "高老庄",
          hobby: "吃包子",
        },
        {
          id: "3",
          name: "沙和尚",
          age: 1000,
          home: "通天河",
          hobby: "游泳",
        },
        {
          id: "4",
          name: "唐僧",
          age: 99999,
          home: "东土大唐",
          hobby: "念经",
        },
      ],
    };
  },
  mounted() {
    // 列的拖拽初始化
    this.columnDropInit();
    // 行的拖拽初始化
    this.rowDropInit();
  },
  methods: {
    //列拖拽
    columnDropInit() {
      // 第一步,获取列容器
      const wrapperColumn = document.querySelector(
        ".el-table__header-wrapper tr"
      );
      // 第二步,给列容器指定对应拖拽规则
      this.sortable = Sortable.create(wrapperColumn, {
        animation: 500,
        delay: 0,
        onEnd: (event) => {
          console.log(
            "拖拽完成以后发现表头数据并没有改变,所以需要我们手动更新表头数据",
            this.tableHeader
          );
          console.log(
            "根据旧索引和新索引去更新,其实就是交换位置",
            event.oldIndex,
            event.newIndex
          );

          // 接下来做索引的交换
          let tempHableHeader = [...this.tableHeader]; // 先存一份临时变量表头数据
          let temp; // 临时变量用于交换
          temp = tempHableHeader[event.oldIndex - 2]; // 注意这里-2是因为,我在表格的前面加了两列(勾选框列,和序号列)
          tempHableHeader[event.oldIndex - 2] =
            tempHableHeader[event.newIndex - 2]; // 如果没有这两列,序号就是正常对应的,就不用减2
          tempHableHeader[event.newIndex - 2] = temp;

          // 重要的事情说三遍!!!
          // 这里一定要先把表头数据清空,然后再下一轮中去赋值,否则会渲染错误
          // 这里一定要先把表头数据清空,然后再下一轮中去赋值,否则会渲染错误
          // 这里一定要先把表头数据清空,然后再下一轮中去赋值,否则会渲染错误
          this.tableHeader = []; // 大家可以注掉试试哦
          this.$nextTick(() => {
            this.tableHeader = tempHableHeader;
          });
        },
      });
    },
    // 行拖拽
    // 个人认为行拖拽不用加,因为加了以后,就不能双击选行单元格的文字了,当然还是要听产品大佬安排
    rowDropInit() {
      // 第一步,获取行容器
      const wrapperRow = document.querySelector(
        ".el-table__body-wrapper tbody"
      );
      const that = this; // 存一份指向
      // 第二步,给行容器指定对应拖拽规则
      Sortable.create(wrapperRow, {
        onEnd({ newIndex, oldIndex }) {
          // 这里是区分上面的列拖拽的另外一种写法

          // 首先删除原来的那一项,并且保存一份原来的那一项,因为splice返回的是一个数组,数组中的第一项就是删掉的那一项
          const currRow = that.tableBody.splice(oldIndex, 1)[0];
          // 然后把这一项加入到新位置上
          that.tableBody.splice(newIndex, 0, currRow);
        },
      });
    },
  },
};
</script>
<style lang='less' scoped>
.myWrap {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  padding: 25px;
  /deep/ .el-table {
    .el-table__header-wrapper {
      tr {
        th {
          // 设置拖动样式,好看一些
          cursor: move;
        }
      }
    }
  }
}
</style>

好记性不如烂笔头,记录一下吧 ^_^

最后附上官网:http://www.sortablejs.com/

https://www.itxst.com/sortabl...


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK