Vue+elementUI+sortableJS实现父/子组件值传递及el-table表格行拖拽

一、效果图如下

二、首先要实现拖拽行,需要安装sortableJs插件,执行命令:npm install sortablejs --save

三、共两个代码文件,一个父组件Parent.vue,一个子组件Child.vue,如下所示

a.Parent.vue,主要提供了子组件标签使用,传递到子组件的数据tableData,子组件可调用的方法。

<template>
  <div class="app-container">
    <h1>父组件标题:以下表格为子组件展示</h1>
    <!--需要将tableData数据传递到子组件就需要在这里设置属性绑定
    子组件需要调父组件方法,父组件需要在这里绑定,类似parentMethod,可以设置多个,属性名自定义-->
    <el-child :tableData="tableData" @haveCallBack="haveCallBack" @parentMethod="parentMethod"></el-child>
  </div>
</template>

<script>
  import Child from "./Child";

  export default {
    name: "Parent",
    components: {"el-child": Child},
    data() {
      return {
        tableData: [
          {
            date: "2016-05-02",
            name: "王小虎",
            address: "上海市普陀区金沙江路 1518 弄",
          },
          {
            date: "2016-05-04",
            name: "王小虎",
            address: "上海市普陀区金沙江路 1517 弄",
          },
          {
            date: "2016-05-01",
            name: "王小虎",
            address: "上海市普陀区金沙江路 1519 弄",
          },
          {
            date: "2016-05-03",
            name: "王小虎",
            address: "上海市普陀区金沙江路 1516 弄",
          },
          {
            date: "2016-05-07",
            name: "王y虎",
            address: "上海市普陀区金沙江路 1516 弄",
          },
          {
            date: "2016-05-08",
            name: "王q虎",
            address: "上海市普陀区金沙江路 1516 弄",
          },
          {
            date: "2016-05-09",
            name: "王小p",
            address: "上海市普陀区金沙江路 1516 弄",
          },
        ]
      };
    },
    methods: {
      parentMethod(row) {
        console.log("父组件方法已调用,子组件传递日期打印:" + row.date);
      },
      haveCallBack(row, callback) {
        console.log("父组件方法已调用,子组件传递日期打印:" + row.date);
        callback(row.date);
      }
    }
  }
</script>

b.Child.vue,主要显示表格数据,处理表格拖拽,以及调用父组件方法并获取方法返回值。

<template>
  <div>
    <!--这里row-key必须要加唯一的prop,不加拖拽位置会不对-->
    <el-table :data="tableData" class="t1" row-key="date" style="width: 100%"  :default-sort="{prop:'id',order:'descending'}">
      <!--前端编号显示列,default-sort设置通过该列将数据倒序展示-->
      <el-table-column align="center" label="编号" prop="id" type="index" width="80px" sortable/>
      <el-table-column label="日期" prop="date" width="180"></el-table-column>
      <el-table-column label="姓名" prop="name" width="180"></el-table-column>
      <el-table-column label="地址" prop="address"></el-table-column>
      <el-table-column align="center" class-name="small-padding" label="操作" width="180px">
        <template slot-scope="scope">
          <el-button v-hasPermi="['minigame:level:edit']" icon="el-icon-edit"
                     size="mini"
                     type="text"
                     @click="callParentMethod(scope.row)">调用父组件方法
          </el-button>
          <el-button v-hasPermi="['minigame:level:edit']" icon="el-icon-edit"
                     size="mini"
                     type="text"
                     @click="haveCallBack(scope.row)">调用父组件方法并回调
          </el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>
<script>
  import Sortable from "sortablejs"; // 引入拖拽js 这个是实现拖拽功能的核心,可以通過npm 安裝,文檔鏈接:http://www.sortablejs.com/options.html

  export default {
    name: "Child",
    components: {},
    //父组件传过来的数据属性名
    props: ['tableData'],
    data() {
      return {};
    },
    mounted() {
      //调用拖拽行方法
      this.rowDrop()
    },
    methods: {
      callParentMethod(row) {
        //在子组件调用父组件的方法,需要传参就在后面带
        this.$emit('parentMethod', row)
      },
      haveCallBack(row) {
        this.$emit('haveCallBack', row, rsp => {
          console.log("回调到子组件,打印日期:" + rsp)
        })
      },
      //拖拽行方法
      rowDrop() {
        const tbody = document.querySelector('.t1 tbody')
        Sortable.create(tbody, {
          disabled: false, // 是否开启拖拽
          ghostClass: 'sortable-ghost', //拖拽样式
          animation: 150, // 拖拽延时,效果更好看
          group: { // 是否开启跨表拖拽
            pull: false,
            put: false
          },
          onEnd: (e) => { // 这里主要进行数据的处理,拖拽实际并不会改变绑定数据的顺序,这里需要自己做数据的顺序更改
            let arr = this.tableData; // 获取表数据
            arr.splice(e.newIndex, 0, arr.splice(e.oldIndex, 1)[0]); // 数据处理
            this.$nextTick(function () {
              this.tableData = arr;
            });
          }
        });
      }
    }
  }
</script>
<style scoped>
  .sortable-ghost {
    opacity: 0.4;
    background: #00a7d0;
  }
</style>
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个完整的示例代码,基于Vue2,antd和sortablejs实现了两个表格之间的数据拖拽功能。 ```html <template> <div> <h2>表格1</h2> <a-table :columns="columns" :dataSource="list1" rowKey="id"> <template #name="{text, record}"> <span v-text="text" v-sortable="'table1'"></span> </template> </a-table> <h2>表格2</h2> <a-table :columns="columns" :dataSource="list2" rowKey="id"> <template #name="{text, record}"> <span v-text="text" v-sortable="'table2'"></span> </template> </a-table> </div> </template> <script> import Sortable from 'sortablejs' import { Table } from 'ant-design-vue' export default { components: { 'a-table': Table, }, data() { return { columns: [ { title: '姓名', dataIndex: 'name' }, { title: '年龄', dataIndex: 'age' }, ], list1: [ { id: 1, name: '张三', age: 18 }, { id: 2, name: '李四', age: 20 }, { id: 3, name: '王五', age: 22 }, ], list2: [], } }, mounted() { Sortable.create(this.$el.querySelector('.ant-table-tbody'), { group: { name: 'table1', put: ['table2'], }, animation: 150, fallbackOnBody: true, swapThreshold: 0.65, onEnd: this.onEnd, }) Sortable.create(this.$el.querySelectorAll('.ant-table-tbody')[1], { group: { name: 'table2', put: ['table1'], }, animation: 150, fallbackOnBody: true, swapThreshold: 0.65, onEnd: this.onEnd, }) }, methods: { onEnd(evt) { const { oldIndex, newIndex, item } = evt if (oldIndex !== newIndex) { const table = evt.to.dataset.table if (table === 'table1') { // 从表格1拖拽表格2 this.list2.splice(newIndex, 0, this.list1.splice(oldIndex, 1)[0]) } else { // 从表格2拖拽表格1 this.list1.splice(newIndex, 0, this.list2.splice(oldIndex, 1)[0]) } } }, }, } </script> ``` 在此示例中,我们使用了Ant Design Vue中的`<a-table>`组件来渲染表格,并在模板中使用了Vue的`v-sortable`指令来绑定Sortable实例。在mounted钩函数中,我们为每个表格的tbody元素创建了Sortable实例,并将它们分组为“table1”和“table2”。然后,我们在onEnd方法中处理拖拽完成事件,并根据拖拽的方向和目标表格移动数据。 需要注意的是,在模板中,我们使用了`<span>`元素包装了表格中的文本数据,来实现拖拽时只能拖拽文本数据而不是整个。同时,在Sortable实例的options中,我们设置了`fallbackOnBody`为true,这样拖拽元素在拖拽结束时会回到原来的位置,而不是消失。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值