element中使用sortablejs进行行列拖拽及封装

1、依赖 sortablejs 下载
npm install sortable.js --save
2、mounted中调用行列拖拽方法
  mounted() {
    this.rowDrop()
    this.columnDrop()
  },

行拖拽方法

 rowDrop() {
      const tbody = document.querySelector('.el-table__body-wrapper tbody')
      Sortable.create(tbody, {
        animation: 150,
        ghostClass: 'blue-background-class',
        onEnd: ({ newIndex, oldIndex }) => {
          const currRow = this.tableData.splice(oldIndex, 1)[0]
          this.tableData.splice(newIndex, 0, currRow)
        }
      })
    },

列拖拽方法

    columnDrop() {
      const wrapperTr = document.querySelector('.el-table__header-wrapper tr')
      this.sortable = Sortable.create(wrapperTr, {
        animation: 180,
        delay: 0,
        onEnd: (evt) => {
          if (evt.oldIndex === evt.newIndex) return
          const oldItem = this.tableTitle[evt.oldIndex - 1]
          const newItem = this.tableTitle[evt.newIndex - 1]
          this.$set(this.tableTitle, evt.newIndex - 1, oldItem)
          this.$set(this.tableTitle, evt.oldIndex - 1, newItem)
        }
      })
    }

tableData:接口返回的表格数据
tableTitle:表头数据
列拖拽是索引-1是因为el-table中有固定表格选项一列

注意:el-table中需绑定row-key为唯一值

遍历显示el-table-column时绑定的key不能为固定索引,否则列拖动时会照成数据渲染有误(表头名称与表格内数据不一致)。可绑定为随机数 :key=“index+‘’+Math.random()”。

完整代码
<template>
  <div>
    <el-table :data="tableData" row-key="key1" border stripe>
      <el-table-column fixed="left" type="selection" width="55" />
      <template v-for="(item,index) in tableTitle">
        <el-table-column
          :key="index+''+Math.random()"
          align="center"
          :min-width="(item.title.length + 10 ) * 12"
          sortable="custom"
          :prop="item.key"
          :label="item.title"
        />
      </template>
    </el-table>
  </div>
</template>
<script>
import { getDosageTable } from '@/api/index.js'
import Sortable from 'sortablejs'
export default {
  data() {
    return {
      tableTitle: [
        { title: '表头1', key: 'key1' },
        { title: '表头2', key: 'key2' },
        { title: '表头3', key: 'key3' }
      ],
      tableData: []
    }
  },
  mounted() {
    this.rowDrop()
    this.columnDrop()
  },
  created() {
    this.getTableDataFn()
  },
  methods: {
    getTableDataFn() {
      getDosageTable().then(res => {
        if (res.success) this.tableData = res.data
      })
    },
   // 行拖拽
    rowDrop() {
      const tbody = document.querySelector('.el-table__body-wrapper tbody')
      Sortable.create(tbody, {
        animation: 150,
        ghostClass: 'blue-background-class',
        onEnd: ({ newIndex, oldIndex }) => {
          const currRow = this.tableData.splice(oldIndex, 1)[0]
          this.tableData.splice(newIndex, 0, currRow)
        }
      })
    },
    // 列拖拽
    columnDrop() {
      const wrapperTr = document.querySelector('.el-table__header-wrapper tr')
      this.sortable = Sortable.create(wrapperTr, {
        animation: 180,
        delay: 0,
        onEnd: (evt) => {
          if (evt.oldIndex === evt.newIndex) return
          const oldItem = this.tableTitle[evt.oldIndex - 1]
          const newItem = this.tableTitle[evt.newIndex - 1]
          this.$set(this.tableTitle, evt.newIndex - 1, oldItem)
          this.$set(this.tableTitle, evt.oldIndex - 1, newItem)
        }
      })
    }
  }
}
</script>
后续优化

项目中一般会有多处表格需要进行行列拖拽,此时可以将行列拖拽方法封装到混入文件中,减少代码量提高利用率。
引入及使用步骤
1、引入 import { sortablejs } from ‘@/mixins/commonUtils/sortablejs’
2、激活 mixins: [sortablejs]
3、初始化方法

    mounted() {
        this.$rowDrop()
        this.$columnDrop()
    },

4、table表格需设置 row-key属性,值唯一
5、el-table-column中key值动态绑定( :key=“${index}_${columnDropDataMixins}” )
完整封装方法如下:

import Sortable from 'sortablejs'
export const sortablejs = {
  data() {
    return {
      columnDropDataMixins: 0
    }
  },
  created() {
  },
  methods: {
    // 行拖拽
    $rowDrop() {
      const tbody = document.querySelector('.el-table__body-wrapper tbody')
      Sortable.create(tbody, {
        animation: 150,
        ghostClass: 'blue-background-class',
        onEnd: ({ newIndex, oldIndex }) => {
          const currRow = this.tableData && this.tableData.splice(oldIndex, 1)[0]
          this.tableData && this.tableData.splice(newIndex, 0, currRow)
        }
      })
    },
    // 列拖拽
    $columnDrop(FixedColumn = 0) { // FixedColumn,table表格固定列数
      const wrapperTr = document.querySelector('.el-table__header-wrapper tr')
      this.sortable = Sortable.create(wrapperTr, {
        animation: 180,
        delay: 0,
        onEnd: (evt) => {
          if (evt.oldIndex === evt.newIndex) return
          const oldItem = this.tableTitle[evt.oldIndex - FixedColumn]
          const newItem = this.tableTitle[evt.newIndex - FixedColumn]
          this.$set(this.tableTitle, evt.newIndex - FixedColumn, oldItem)
          this.$set(this.tableTitle, evt.oldIndex - FixedColumn, newItem)
          this.columnDropDataMixins++ // 拖拽列后动态更新
        }
      })
    }
  }
}

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

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的示例,演示如何使用 Vue3 和 Element Plus 封装一个弹窗组件: ```html <template> <el-dialog :title="title" :visible.sync="visible" :width="width" :before-close="beforeClose" > <slot></slot> <div slot="footer" class="dialog-footer"> <el-button @click="visible = false">取消</el-button> <el-button type="primary" @click="confirm">确定</el-button> </div> </el-dialog> </template> <script> import { defineComponent } from 'vue' import { ElDialog, ElButton } from 'element-plus' export default defineComponent({ name: 'MyDialog', components: { ElDialog, ElButton }, props: { title: { type: String, default: '提示' }, visible: { type: Boolean, default: false }, width: { type: String, default: '30%' }, beforeClose: Function, }, methods: { confirm() { // 触发确认事件,并关闭弹窗 this.$emit('confirm') this.visible = false }, }, }) </script> <style> /* 可选:自定义弹窗样式 */ .dialog-footer { padding: 10px 20px; text-align: right; background-color: #f5f7fa; border-top: 1px solid #ebeef5; } </style> ``` 使用方法: ```html <template> <div> <el-button @click="showDialog">打开弹窗</el-button> <my-dialog :visible.sync="dialogVisible" @confirm="handleConfirm" > <!-- 弹窗内容 --> <p>这是一个弹窗</p> </my-dialog> </div> </template> <script> import { defineComponent, ref } from 'vue' import MyDialog from '@/components/MyDialog.vue' export default defineComponent({ components: { MyDialog }, setup() { const dialogVisible = ref(false) const showDialog = () => { dialogVisible.value = true } const handleConfirm = () => { // 处理确认事件 console.log('确认') } return { dialogVisible, showDialog, handleConfirm } }, }) </script> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值