提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
相信不少小伙伴已经开始使用vue3在项目中实战了,可能会遇到实现一个拖拽排序列表的组件。
如何实现一个好看的拖拽列表呢。
一、演示效果
二、实现步骤
1.安装库
pnpm add sortablejs
pnpm add @types/sortablejs -D // 如果没有使用TS可以不用安装
2.编辑组件
代码如下(示例):
<template>
<div ref="draggableContainer" class="draggableContainer">
<main v-for="item in list" :key="item.value">
<section class="draggable-item">
<section>
<span class="my-handle r-2">::</span>
<span>{{ item.label }}</span>
</section>
</section>
</main>
</div>
</template>
<script lang="ts" setup>
import { onMounted, onUnmounted, ref } from 'vue';
import Sortable from 'sortablejs';
interface Item {
label: string;
value: string; // 可能是会需要value值
}
interface Props {
list: Array<Item>;
options?: Sortable.Options;
}
const draggableContainer = ref<HTMLDivElement | null>(null);
const props = defineProps<Props>();
interface EmitsType {
(e: 'update:list', value: any[]): void;
(e: 'onChangeList', value: any[]): void;
}
const emit = defineEmits<EmitsType>();
const sortable = ref<Sortable | null>(null);
onMounted(() => {
initDraggable();
});
const initDraggable = () => {
if (!draggableContainer.value) {
console.warn('容器不能为空');
return;
}
sortable.value = Sortable.create(draggableContainer.value, {
handle: '.my-handle',
chosenClass: 'chosen',
dragClass: 'drag',
direction: 'horizontal',
forceFallback: true,
animation: 300,
onUpdate(e: any) {
if (e.oldIndex !== undefined && e.newIndex !== undefined) {
// 删除拖拽的元素
const list = [...props.list];
const item = list.splice(e.oldIndex, 1)[0];
// 把删除的元素放到新的位置
list.splice(e.newIndex, 0, item);
emit('update:list', list);
emit('onChangeList', list);
}
},
...props.options
});
};
onUnmounted(() => {
sortable.value?.destroy();
});
</script>
<style lang="scss" scoped>
.draggableContainer {
max-width: 30rem;
background: #ffffff;
color: #495057;
border: 0 none;
border-radius: 6px;
box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
}
.r-2 {
margin-right: 2rem;
}
.draggable-item {
margin: 0;
padding: 0.75rem 1.25rem;
border: 0 none;
color: #495057;
background: transparent;
transition: box-shadow 0.2s;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: space-between;
font-weight: normal;
white-space: nowrap;
position: relative;
overflow: hidden;
}
//.draggable-item:hover {
// background: #e9ecef;
//}
.my-handle {
cursor: move;
cursor: -webkit-grabbing;
}
.drag {
// 正在拖拽中幽灵图的样式
display: none;
cursor: move;
cursor: -webkit-grabbing;
}
.chosen {
cursor: move;
cursor: -webkit-grabbing;
border-radius: 6px;
box-shadow: 0 2px 10px 0 rgb(0 0 0 / 20%);
}
</style>
3.使用组件
<template>
<DraggList v-model:list="list" />
</template>
<script lang="ts" setup>
import DraggList from '/@/components/Draggable/DraggList.vue';
import { ref } from 'vue';
const list = ref([
{ label: '早餐吃些什么呢', value: 'value1' },
{ label: '午餐吃些什么呢', value: 'value2' },
{ label: '晚餐吃些什么呢', value: 'value3' },
{ label: '夜宵吃些什么呢', value: 'value4' }
]);
</script>
总结
以上就是一个拖拽排序列表实现的方法,仅供参考