您好,登錄后才能下訂單哦!
本篇內容介紹了“怎么用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 :list="list1" :config="config1"> <template v-slot="{ item }"> <div class="item"> {{ item.name }} </div> </template> </Drag> <Drag :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, // 當前列表元素之間是否支持交換位置
}
“怎么用vue實現拖拽排序效果”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。