效果预览

组件 drag.vue

<template><TransitionGroup name="group-list" tag="ul"><liv-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, // 当前列表元素之间是否支持交换位置
}

vue拖拽排序(原创组件)相关推荐

  1. vue拖拽排序 组件

    vue拖拽排序 组件 npm install vuedraggable -S vue.draggable中文文档 组件代码 <template><div><div cla ...

  2. ant vue 树形菜单横向显示_丝滑般 Vue 拖拽排序树形表格组件Vue-DragTreeTable

    今天给小伙伴们分享一款纵享丝滑般体验的Vue拖拽树形表格DragTreeTable. vue-drag-tree-table 基于vue.js实现可拖拽排序的树形表格组件.支持拖拽排序.固定表头.拖拽 ...

  3. html5+vue无法拖拽,Vue拖拽排序插件Vuedraggable使用方法详解_心善_前端开发者

    大家好,最近做的项目要用到拖拽排序,我现在的项目是 首先在 npm install vuedraggable -S 下载下来后,引入插件,在你的vue文件的script标签里面这样引入 import ...

  4. android gridview拖动排序,Asp.net GridView 拖拽排序    原创(欢迎拍砖,敬请嘴下留情!)...

    原理:客户端排序(或者说组织新的排序顺序),Ajax 更新服务器端数据. 客户端用jquery插件sortable实现拖拽排序,保存之前检索顺序变化了的数据,并组织成Json数据,用AJax传送到服务 ...

  5. vue可拖拽排序列表组件

    先看效果: dragable-lists.vue组件源码: <template><div class="drag-lists" ref="drag-li ...

  6. 树形可拖拽排序配置组件

    效果 使用场景 vue2下自定义表格表头配置: 列排序,显示/隐藏等.确保表头以配置项的形式加载,这样表格才能对修改后的配置作响应 思路 1.表格使用render函数加载(如有疑问可私信),通过类似如 ...

  7. vue可视化拖拽组件模板_基于 Vue 丝滑般拖拽排序组件VueSlicksort

    今天给大家分享一个功能超强的自由拖拽排序组件VueSlicksort. vue-slicksort 一款功能强大的可拖拽的vue.js组件.拥有丝滑般拖拽动画效果,支持水平/垂直/网格拖拽排序.还可以 ...

  8. html5 list 拖拽排序,vue实现可拖拽排序的列表

    在做友情链接管理功能的时候,考虑到有个对友情链接排序的需求,开始的时候 我是在这个list 里边加了rank字段,用户需要手动输入rank ,点击保存后,后台通过用户输入的rank序号进行排序,这显然 ...

  9. vue.js 拖拽排序_快速轻巧的Vue.js拖放可排序库

    vue.js 拖拽排序 vue-smooth-dnd (vue-smooth-dnd) A fast and lightweight drag&drop, sortable library f ...

最新文章

  1. 一天1300 Star量,GitHub上新官方命令行工具
  2. 模拟上帝之手的对抗博弈——GAN背后的数学原理
  3. 编写下载服务器。 第五部分:油门下载速度
  4. 【习题 5-8 UVA - 230】Borrowers
  5. Android实例-手机安全卫士(三十六)-根据Service是否开启确定CheckBox选中状态
  6. C#LeetCode刷题之#867-转置矩阵(Transpose Matrix)
  7. 最常用计算机语音,计算机常用词汇--语言及服务器篇
  8. 从零开始一起学习SLAM | 相机成像模型
  9. n的阶乘末尾含0的个数
  10. html制作象棋教程入门教程,canvas 纯js 绘制中国象棋棋盘
  11. Java集成socket.io
  12. Spring Interceptor vs Filter 拦截器和过滤器区别
  13. python程序流程控制_Python流程控制语句详解
  14. 【父亲节故事】32岁入门学习编程的父亲给我的启示
  15. 一份超详细的UI设计规范全攻略
  16. 还记得那一场说开始就开始的恋爱吗?
  17. 操作系统期末大题复习
  18. 给Ubuntu系统清理垃圾
  19. 「Python条件结构」if…else实现计算税后工资
  20. hive sql中传date 指定后的“%Y-%m-%d“格式,需要加引号

热门文章

  1. 启动docker中的compose.yml
  2. 渗透测试之Webshell
  3. 流失预警模型:神经网络
  4. 如何在excel表格中批量添加内容?
  5. 语音识别维特比解码_3-GMM-HMMs语音识别系统-解码篇
  6. gitlab如何创建用户并登录
  7. 中国建筑科学大会暨绿色智慧建筑博览会开幕!奥的斯新一代Gen3智慧电梯中国首发;格兰富、紫荆花重磅亮相 | 美通社头条...
  8. 4399疯狂小人战斗中的一个**的操作
  9. MySQL数据批量删除语句
  10. Linux 4.1最新内核usb与hid驱动分析记录