温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

怎么用vue实现拖拽排序效果

发布时间:2022-08-30 11:29:35 来源:亿速云 阅读:271 作者:iii 栏目:开发技术

本篇内容介绍了“怎么用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  :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实现拖拽排序效果”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

vue
AI