期望状态
列表拖动排序
分析:
draggable 实现拖拽排序
实现逻辑:列表项拖拽到可放置目标时,将该拖拽的元素从原位置删除,再将拖拽的元素插入到当前可放置目标的位置
- 利用Vue的内置组件TransitionGroup,添加动画效果
- 列表项添加draggable属性,并设置为true
- 列表项添加事件dragstart、dragenter、dragend、dragover。
- 在dragenter事件中,需要传入列表项的下表,实时进行元素的排序。排序的核心逻辑在dragenter函数中
解决方案:
<template>
<div class="customColumnRight">
<TransitionGroup name="list" tag="div" class="container flex-column">
<div :class="['item flex f-col-center f-row-between']"
v-for="(item, i) in selectArrSort" :key="item.fieldCode" draggable="true" @dragstart="dragstart($event, i)"
@dragenter="dragenter($event, i)" @dragend="dragend" @dragover="dragover">
<div>
<i class="iconfont icon-huadong-14px"></i>
<span>{{ item.name}}</span>
</div>
</div>
</TransitionGroup>
</div>
</template>
<script setup lang="ts">
import { computed, ref, watch } from 'vue'
let dragIndex = 0// 拖拽的元素索引值
const state = ref<any[]>([
{ name: 'a', id: 1 },
{ name: 'b', id: 2 },
{ name: 'c', id: 3 },
{ name: 'd', id: 4 },
{ name: 'e', id: 5 },
])
const dragstart = (e: any, index: any) => {
e.stopPropagation()
dragIndex = index
setTimeout(() => {
e.target.classList.add('moveing')
}, 0)
}
let isDrag = false//判断是否拖拽过
const dragenter = (e: any, index: any) => {
e.preventDefault()
// 拖拽到原位置时不触发
if (dragIndex !== index) {
const source = state.value[dragIndex]
state.value.splice(dragIndex, 1)
state.value.splice(index, 0, source)
// 更新节点位置
dragIndex = index
isDrag = true
}
}
const dragover = (e: any) => {
e.preventDefault()
e.dataTransfer.dropEffect = 'move'
}
const dragend = (e: any) => {
e.target.classList.remove('moveing')
}
</script>
完结,撒花花~~