【vue3 + element plus 】拖动排序实现(只能拖拽一次的问题、拖动后的位置不准确问题)

1.使用sortablejs插件

用于el-table列表拖动排序

import Sortable from 'sortablejs' // 拖拽插件
mounted() { this.rowDrop() },
swap(arr, from, to) {
// 在这方法中按需求修改排序规则即可
   if (from < 0 || from >= arr.length || to < 0 || to >= arr.length) return
   const temp = arr[from]
   arr[from] = arr[to]
   arr[to] = temp
   return arr
},
rowDrop() {
  const that = this
  const tbody = document.querySelector('.el-table__body-wrapper tbody')
    Sortable.create(tbody, {
      animation: 100,
      delay: 100,
      handle: '.move',
      onEnd ({ newIndex, oldIndex }) {
         let tableData = that.tableData
         that.tableData = []
         tableData = that.swap(tableData, oldIndex, newIndex)
         that.tableData = tableData
      }
    })
},
<el-table row-key="id" :data="tableData" border style="width: 100%">
	<el-table-column prop="content" label="活动内容" align="center" />
	<el-table-column label="操作" align="center">
        <template v-slot="{ row }">
           <div><el-icon class="move"><Sort /></el-icon></div>
         </template>
     </el-table-column>
</el-table>

踩过的坑:
that.tableData = [] 因为重新渲染后,附加的拖拽事件丢失,所以需要置空来解决table只能拖拽一次的问题
row-key="id" 缺失会导致拖动后的位置不准确
class="move" 绑定触发拖动事件

2.使用sortablejs-vue3插件

npm库地址

用于普通标签、图标等拖动排序

import { Sortable } from 'sortablejs-vue3'

const options = {
  ghostClass: 'ghost',
  dragClass: 'drag'
},
const itemKey = Math.random()

const swap = (arr, from, to) = {
  // 在这方法中按需求修改排序规则即可
  if (from < 0 || from >= arr.length || to < 0 || to >= arr.length) return
  const temp = arr[from]
  if (from > to) { for (let i = from; i >= to; i--) { arr[i] = arr[i-1] } }
  if (from < to) { for (let i = from; i <= to; i++) { arr[i] = arr[i+1] } }
  arr[to] = temp
  return arr
},
const tagChange = (e) = {
  this.itemKey = Math.random()
  this.list= this.swap(this.list, e.oldIndex, e.newIndex)
},
const removeUser = (index) = {
  this.list.splice(index, 1)
},

<Sortable
   :key="itemKey"
   :list="list"
   :options="options"
   item-key="key"
   tag="div"
   @end="tagChange"
>
   <template #item="{ element, index }">
      <div class="item">
         <el-tag closable @close="removeUser(index)">
            <span>{{element.name}}</span>
         </el-tag>
      </div>
    </template>
</Sortable>

代码仅供参考

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现多个card组件之间的拖动和数据交换效果,可以使用Vue3的Composition API和element-plus提供的draggable指令。以下是一个简单的实现过程: 1. 安装element-plus和vuedraggable插件 ``` npm install element-plus vuedraggable --save ``` 2. 在main.js中导入element-plus和vuedraggable ```javascript import { createApp } from 'vue' import App from './App.vue' import ElementPlus from 'element-plus' import 'element-plus/lib/theme-chalk/index.css' import draggable from 'vuedraggable' const app = createApp(App) app.use(ElementPlus) app.component('draggable', draggable) app.mount('#app') ``` 3. 在组件中使用draggable指令实现拖动效果 ```html <template> <div> <draggable v-model="cards" :options="{animation: 200}"> <div v-for="(card, index) in cards" :key="card.id"> <el-card class="card"> <div>{{ card.content }}</div> </el-card> </div> </draggable> </div> </template> <script> import { reactive } from 'vue' export default { setup() { const cards = reactive([ { id: 1, content: 'Card 1' }, { id: 2, content: 'Card 2' }, { id: 3, content: 'Card 3' }, { id: 4, content: 'Card 4' } ]) return { cards } } } </script> <style> .card { margin-bottom: 10px; } </style> ``` 4. 在draggable指令上添加事件监听,实现数据交换效果 ```html <template> <div> <draggable v-model="cards" :options="{animation: 200}" @end="onDragEnd"> <div v-for="(card, index) in cards" :key="card.id"> <el-card class="card"> <div>{{ card.content }}</div> </el-card> </div> </draggable> </div> </template> <script> import { reactive } from 'vue' export default { setup() { const cards = reactive([ { id: 1, content: 'Card 1' }, { id: 2, content: 'Card 2' }, { id: 3, content: 'Card 3' }, { id: 4, content: 'Card 4' } ]) const onDragEnd = ({ newIndex, oldIndex }) => { const movedCard = cards.splice(oldIndex, 1)[0] cards.splice(newIndex, 0, movedCard) } return { cards, onDragEnd } } } </script> <style> .card { margin-bottom: 10px; } </style> ``` 在onDragEnd函数中,首先通过splice方法将移动的卡片从原位置删除,再通过splice方法将卡片插入到新位置,从而实现数据交换效果。 以上就是在vue3,element-plus开发环境下实现多个card组件之间拖动,并达到数据交换效果的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值