一、核心实现代码
<template>
<div>
<!-- 动态列表容器 -->
<ul ref="sortableList">
<li
v-for="(item, index) in list"
:key="item.id" <!-- id值必须唯一,动态新增的id值注意唯一性 -->
class="sortable-item"
>
{{ index + 1 }}. {{ item.name }}
</li>
</ul>
<!-- 显示排序结果 -->
<div>当前顺序:{{ sortedIds }}</div>
</div>
</template>
<script>
import Sortable from 'sortablejs';
export default {
data() {
return {
// 初始数据(可替换为接口获取)
list: [
{ id: 1, name: '苹果' },
{ id: 2, name: '香蕉' },
{ id: 3, name: '橘子' }
]
};
},
computed: {
// 实时获取排序后的ID序列
sortedIds() {
return this.list.map(item => item.id).join(', ');
}
},
mounted() {
this.initSortable();
},
methods: {
initSortable() {
const el = this.$refs.sortableList;
Sortable.create(el, {
animation: 150,
ghostClass: 'sortable-ghost',
onEnd: (evt) => {
// 处理数据顺序变化
this.handleSort(evt.oldIndex, evt.newIndex);
}
});
},
handleSort(oldIndex, newIndex) {
// 使用Vue的数组方法保持响应式
const movedItem = this.list.splice(oldIndex, 1)[0];
this.list.splice(newIndex, 0, movedItem);
//此时this.list列表,已是拖拽后的排序顺序,可直接提交后端,按此排序
console.log('排序后的列表', this.list);
// 提交最新数据
this.submitOrder();
},
submitOrder() {
// 发送到后端(示例)
const payload = {
sortedIds: this.sortedIds,
fullData: this.list
};
console.log('提交数据:', payload);
// 实际调用API示例
// this.$http.post('/api/update-order', payload);
}
}
};
</script>
<style>
.sortable-item {
padding: 10px;
margin: 5px;
border: 1px solid #ddd;
cursor: move;
transition: all 0.3s;
}
.sortable-ghost {
opacity: 0.6;
background: #f0f9ff;
}
</style>
二、关键实现原理
1.动态列表绑定
- 通过 v-for 渲染动态数据
- :key 必须使用唯一标识(如 item.id)
2.Sortable 初始化
- 在 mounted 生命周期初始化
- 绑定到 ref 引用的容器元素
2.数据同步机制
- 在 onEnd 事件中通过 splice 操作数组
- 使用 Vue 的数组变异方法保持响应式