vue實現拖拽排序效果
更新時間:2022年08月30日 10:03:12 作者:朝陽39
這篇文章主要為大家詳細介紹了vue實現拖拽排序效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實例為大家分享了vue實現拖拽排序效果的具體代碼,供大家參考,具體內容如下
效果預覽
組件 drag.vue
<template> ? <TransitionGroup name="group-list" tag="ul"> ? ? <li ? ? ? v-for="(item, index) in list" ? ? ? :key="item.name" ? ? ? :draggable="item.draggable" ? ? ? :class="[ ? ? ? ? 'list-item', ? ? ? ? { ? ? ? ? ? 'is-dragover': ? ? ? ? ? ? index === dropIndex && item.draggable && config.exchange, ? ? ? ? }, ? ? ? ]" ? ? ? @dragstart="onDragstart($event, index)" ? ? ? @dragenter="onDragenter(index)" ? ? ? @dragover.prevent="onDragover(index)" ? ? ? @dragleave="onDragleave" ? ? ? @dragend="onDragend" ? ? ? @drop="onDrop" ? ? > ? ? ? <slot :item="item" /> ? ? </li> ? </TransitionGroup> </template> <script> export default { ? name: "Draggable", ? props: { ? ? list: { ? ? ? type: Array, ? ? ? default: () => [], ? ? }, ? ? config: { ? ? ? type: Object, ? ? ? default: () => ({ ? ? ? ? name: "", ? ? ? ? push: true, ? ? ? ? pull: true, ? ? ? ? exchange: true, ? ? ? }), ? ? }, ? }, ? data() { ? ? return { ? ? ? dragIndex: null, ? ? ? dropIndex: null, ? ? }; ? }, ? computed: { ? ? isPush() { ? ? ? const { dropIndex, dragIndex } = this; ? ? ? return dropIndex !== null && dragIndex === null; ? ? }, ? ? isExchange() { ? ? ? const { dropIndex, dragIndex } = this; ? ? ? return dragIndex !== null && dropIndex !== null; ? ? }, ? ? pushCbName() { ? ? ? const { ? ? ? ? config: { name }, ? ? ? } = this; ? ? ? return `${name}-push-callback`; ? ? }, ? }, ? methods: { ? ? onDragstart(e, i) { ? ? ? const { ? ? ? ? list, ? ? ? ? config: { name }, ? ? ? ? transferData, ? ? ? } = this; ? ? ? this.dragIndex = i; ? ? ? if (name) { ? ? ? ? transferData({ e, key: name, type: "set", data: list[i] }); ? ? ? } else { ? ? ? ? throw new Error("缺少配置關聯名name"); ? ? ? } ? ? ? this.$emit("drag-start", i); ? ? }, ? ? onDragenter(i) { ? ? ? this.dropIndex = i; ? ? ? this.$emit("drag-enter", i); ? ? }, ? ? onDragover(i) { ? ? ? const { dragIndex, dropIndex } = this; ? ? ? if (i === dragIndex || i === dropIndex) return; ? ? ? this.dropIndex = i; ? ? ? this.$emit("drag-over", i); ? ? }, ? ? onDragleave() { ? ? ? this.dropIndex = null; ? ? }, ? ? onDrop(e) { ? ? ? const { ? ? ? ? list, ? ? ? ? dropIndex, ? ? ? ? dragIndex, ? ? ? ? config: { name, push: enablePush, exchange }, ? ? ? ? isPush, ? ? ? ? isExchange, ? ? ? ? pushCbName, ? ? ? ? storage, ? ? ? ? resetIndex, ? ? ? ? transferData, ? ? ? } = this; ? ? ? if (dropIndex === dragIndex || !exchange) return; ? ? ? if (isPush) { ? ? ? ? if (!enablePush) { ? ? ? ? ? resetIndex(); ? ? ? ? ? return; ? ? ? ? } ? ? ? ? if (name) { ? ? ? ? ? list.splice( ? ? ? ? ? ? dropIndex, ? ? ? ? ? ? 0, ? ? ? ? ? ? transferData({ e, key: name, type: "get" }) ? ? ? ? ? ); ? ? ? ? ? storage("set", pushCbName, true); ? ? ? ? } else { ? ? ? ? ? resetIndex(); ? ? ? ? ? throw new Error("缺少配置關聯屬性name"); ? ? ? ? } ? ? ? ? resetIndex(); ? ? ? ? return; ? ? ? } ? ? ? if (isExchange) { ? ? ? ? const drapItem = list[dragIndex]; ? ? ? ? const dropItem = list[dropIndex]; ? ? ? ? list.splice(dropIndex, 1, drapItem); ? ? ? ? list.splice(dragIndex, 1, dropItem); ? ? ? } ? ? ? resetIndex(); ? ? }, ? ? onDragend() { ? ? ? const { ? ? ? ? list, ? ? ? ? dragIndex, ? ? ? ? config: { pull: enablePull }, ? ? ? ? pushCbName, ? ? ? ? storage, ? ? ? ? resetIndex, ? ? ? } = this; ? ? ? if (enablePull) { ? ? ? ? const isPushSuccess = storage("get", pushCbName); ? ? ? ? if (isPushSuccess) { ? ? ? ? ? list.splice(dragIndex, 1); ? ? ? ? ? storage("remove", pushCbName); ? ? ? ? } ? ? ? } ? ? ? resetIndex(); ? ? ? this.$emit("drag-end"); ? ? }, ? ? storage(type, key, value) { ? ? ? return { ? ? ? ? get() { ? ? ? ? ? return JSON.parse(localStorage.getItem(key)); ? ? ? ? }, ? ? ? ? set() { ? ? ? ? ? localStorage.setItem(key, JSON.stringify(value)); ? ? ? ? }, ? ? ? ? remove() { ? ? ? ? ? localStorage.removeItem(key); ? ? ? ? }, ? ? ? }[type](); ? ? }, ? ? resetIndex() { ? ? ? this.dropIndex = null; ? ? ? this.dragIndex = null; ? ? }, ? ? transferData({ e, key, type, data } = {}) { ? ? ? if (type === "get") { ? ? ? ? return JSON.parse(e.dataTransfer.getData(`${key}-drag-key`)); ? ? ? } ? ? ? if (type === "set") { ? ? ? ? e.dataTransfer.setData(`${key}-drag-key`, JSON.stringify(data)); ? ? ? } ? ? }, ? }, }; </script> <style ?scoped> .list-item { ? list-style: none; ? position: relative; ? margin-bottom: 10px; ? border-radius: 4px; ? padding: 4px; ? background-color: #fff; ? cursor: move; } .list-item.is-dragover::before { ? content: ""; ? position: absolute; ? bottom: -4px; ? left: 0; ? width: 100%; ? height: 4px; ? background-color: #0c6bc9; } .list-item.is-dragover::after { ? content: ""; ? position: absolute; ? bottom: -8px; ? left: -6px; ? border: 3px solid #0c6bc9; ? border-radius: 50%; ? width: 6px; ? height: 6px; ? background-color: #fff; } .group-list-move { ? transition: transform 0.8s; } </style>
使用范例
index.vue
<template> ? <div class="dragBox"> ? ? <Drag style="width: 200px" :list="list1" :config="config1"> ? ? ? <template v-slot="{ item }"> ? ? ? ? <div class="item"> ? ? ? ? ? {{ item.name }} ? ? ? ? </div> ? ? ? </template> ? ? </Drag> ? ? <Drag style="width: 200px" :list="list2" :config="config2"> ? ? ? <template v-slot="{ item }"> ? ? ? ? <div class="item"> ? ? ? ? ? {{ item.name }} ? ? ? ? </div> ? ? ? </template> ? ? </Drag> ? </div> </template> <script> import Drag from "./drag.vue"; export default { ? components: { ? ? Drag, ? }, ? data() { ? ? return { ? ? ? list1: new Array(10).fill(0).map((_, i) => ({ ? ? ? ? name: `列表1 - ${i + 1}`, ? ? ? ? draggable: true, ? ? ? })), ? ? ? config1: { ? ? ? ? name: "test", ? ? ? ? push: true, ? ? ? ? pull: true, ? ? ? ? exchange: true, ? ? ? }, ? ? ? list2: new Array(10).fill(0).map((_, i) => ({ ? ? ? ? name: `列表2 - ${i + 1}`, ? ? ? ? draggable: true, ? ? ? })), ? ? ? config2: { ? ? ? ? name: "test", ? ? ? ? push: true, ? ? ? ? pull: true, ? ? ? ? exchange: true, ? ? ? }, ? ? }; ? }, }; </script> <style ?scoped> .dragBox { ? display: flex; ? justify-content: center; } .item { ? border: 1px solid #ccc; ? width: 200px; ? height: 30px; ? text-align: center; } </style>
參數說明
list: 渲染列表
config: {
name: '', // 跨列表關聯名,跨列表拖拽時必傳
push: true, // 當前列表是否支持從其他列表push元素進來
pull: true, // 將當前列表的某個元素拖拽并添加到其他列表里,該元素是否從當前列表移除
exchange: true, // 當前列表元素之間是否支持交換位置
}
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
您可能感興趣的文章:
- vuedraggable+element ui實現頁面控件拖拽排序效果
- vue拖拽排序插件vuedraggable使用方法詳解
- 利用Vue-draggable組件實現Vue項目中表格內容的拖拽排序
- 基于Vue實現平滑過渡的拖拽排序功能
- vue實現列表拖拽排序的功能
- vue.draggable實現表格拖拽排序效果
- vue 使用 sortable 實現 el-table 拖拽排序功能
- antdesign-vue結合sortablejs實現兩個table相互拖拽排序功能
- Vue?基于?vuedraggable?實現選中、拖拽、排序效果
- vue拖拽組件 vuedraggable API options實現盒子之間相互拖拽排序