vue可拖拽排序列表组件
先看效果:
dragable-lists.vue组件源码:
<template><div class="drag-lists" ref="drag-lists"><slot /><!-- 占位dom --><div class="perch" ref="perchRef"></div></div>
</template><script>
export default {props: {direction: {default: 'y' // 可选值x:横向, y:纵向}},data() {return {isDrag: false, // 是否拖拽index: '', // 拖拽的列表indexperchEl: null, // 占位div的domparentEl: null, // 列表父domlistsEl: null, // 列表dom集合pointerPosition: {left: '',top: ''}, // 鼠标点击的点相对于当前dom的左和上偏移量dragListOldStyle: '', // list的原始style// 被拖拽div的宽高dragListElBaseProp: {width: '',height: ''}}},computed: {// 被拖拽domdragListEl() {return this.listsEl[this.index]}},mounted() {this.init()},methods: {init() {document.addEventListener('mousedown', this.mouseDown)document.addEventListener('mousemove', this.mouseMove)document.addEventListener('mouseup', this.mouseUp)this.parentEl = this.$refs['drag-lists']this.listsEl = this.$slots.default.map((i) => i.elm) // 获取到slot插槽列表dom集合this.perchEl = this.$refs['perchRef']// 每个list加mouseenter事件(排序的逻辑)this.listsEl.forEach((el) => {el.addEventListener('mouseenter', () => {if (this.isDrag) {const lists = [...this.parentEl.children]const imgIndex = lists.findIndex((item) => el === item)const perchIndex = lists.findIndex((item) => this.perchEl === item)if (perchIndex < imgIndex) {this.parentEl.insertBefore(el, this.perchEl)} else {this.parentEl.insertBefore(this.perchEl, el)}}})})},mouseDown(e) {this.isDrag = trueconst { pageX: X, pageY: Y } = ethis.index = e.target.dataset.indexif (this.index && this.isDrag) {this.getDragListBaseProp()this.dragListOldStyle = this.dragListEl.getAttribute('style') || '' // 记录下被拖拽dom的style样式,方便mouseup时恢复// 设置占位dom的影响宽高的定位的样式和被拖拽dom的保持一致const { width, height, offsetLeft, offsetTop, margin, padding } = this.dragListElBasePropthis.perchEl.style.width = width + 'px'this.perchEl.style.height = height + 'px'this.perchEl.style.margin = marginthis.perchEl.style.padding = paddingthis.perchEl.style.display = 'block' // 占位div显示this.parentEl.insertBefore(this.perchEl, this.dragListEl) // 在拖拽div前插入占位divthis.pointerPosition = {left: X - offsetLeft,top: Y - offsetTop}this.move(this.dragListEl, X - this.pointerPosition.left, Y - this.pointerPosition.top) // 移动被拖拽的div}},mouseMove(e) {const { pageX: X, pageY: Y } = eif (this.index && this.isDrag) {this.move(this.dragListEl, X - this.pointerPosition.left, Y - this.pointerPosition.top) // 移动被拖拽的div}},mouseUp() {this.isDrag = falsethis.perchEl.style.display = 'none'if (this.dragListEl) {if (this.dragListOldStyle) {this.dragListEl.setAttribute('style', this.dragListOldStyle)} else {this.dragListEl.removeAttribute('style')}this.parentEl.insertBefore(this.dragListEl, this.perchEl)}},// 移动函数move(el, x, y) {// 如果移动模式是横向,则垂直方向偏移量固定为0if (this.direction === 'x') {y = 0}// 如果移动模式是纵向,则水平方向偏移量固定为0if (this.direction === 'y') {x = 0}// 设置宽高是position为absolute时,防止flex等布局下宽高获取不到的问题const { width, height } = this.dragListElBasePropel.setAttribute('style',`position: absolute;width: ${width}px;height: ${height}px;left: ${x}px;top: ${y}px;pointer-events: none;border-radius: 5px;background: #999;opacity: 0.7;${this.dragListOldStyle}`)},// 获取被拖拽dom在拖拽前的宽高,左上偏移量,margin,paddinggetDragListBaseProp() {const dom = this.dragListElconst margin = dom.currentStyle ? dom.currentStyle['margin'] : getComputedStyle(dom, null)['margin']const padding = dom.currentStyle ? dom.currentStyle['padding'] : getComputedStyle(dom, null)['padding']const { width, height } = dom.getBoundingClientRect()const { offsetLeft, offsetTop } = domthis.dragListElBaseProp = { width, height, offsetLeft, offsetTop, margin, padding }}}
}
</script>
<style lang="scss" scoped>
.drag-lists {position: relative;.perch {display: none;}
}
</style>
使用方法:
<template><div class="main"><dragableLists direction="x" style="display: flex"><div class="list" :data-index="index" v-for="(item, index) in lists" :key="index">{{ item.name }}</div></dragableLists></div>
</template><script>
import dragableLists from '@/components/dragable-lists.vue'
export default {components: { dragableLists },data() {return {lists: [{ name: '第一行' }, { name: '第二行第二行第二行第二行第二行' }, { name: '第三行' }]}}
}
</script>
<style lang="scss" scoped>
.main {width: 800px;
}
.list {padding: 20px;margin: 20px;background: #eee;flex: 1;text-align: center;
}
</style>
---------------
如果是移动端,需要把mousedown、mouseUp替换为touchstart、touchend,mouseenter、mousemove替换为touchmove,并且事件的参数e要取值e.touches[0]
vue可拖拽排序列表组件相关推荐
- vue.js 拖拽排序_快速轻巧的Vue.js拖放可排序库
vue.js 拖拽排序 vue-smooth-dnd (vue-smooth-dnd) A fast and lightweight drag&drop, sortable library f ...
- 树形可拖拽排序配置组件
效果 使用场景 vue2下自定义表格表头配置: 列排序,显示/隐藏等.确保表头以配置项的形式加载,这样表格才能对修改后的配置作响应 思路 1.表格使用render函数加载(如有疑问可私信),通过类似如 ...
- vue拖拽排序 组件
vue拖拽排序 组件 npm install vuedraggable -S vue.draggable中文文档 组件代码 <template><div><div cla ...
- vue可视化拖拽组件模板_基于 Vue 丝滑般拖拽排序组件VueSlicksort
今天给大家分享一个功能超强的自由拖拽排序组件VueSlicksort. vue-slicksort 一款功能强大的可拖拽的vue.js组件.拥有丝滑般拖拽动画效果,支持水平/垂直/网格拖拽排序.还可以 ...
- ant vue 树形菜单横向显示_丝滑般 Vue 拖拽排序树形表格组件Vue-DragTreeTable
今天给小伙伴们分享一款纵享丝滑般体验的Vue拖拽树形表格DragTreeTable. vue-drag-tree-table 基于vue.js实现可拖拽排序的树形表格组件.支持拖拽排序.固定表头.拖拽 ...
- html5 list 拖拽排序,vue实现可拖拽排序的列表
在做友情链接管理功能的时候,考虑到有个对友情链接排序的需求,开始的时候 我是在这个list 里边加了rank字段,用户需要手动输入rank ,点击保存后,后台通过用户输入的rank序号进行排序,这显然 ...
- vue中实现拖拽排序
原生拖拽 API 实现拖拽 设置元素 dragable 将元素的 dragable 属性设置 为 true (文本 图片 链接 的draggable 属性默认为 true)则元素可拖放 <div ...
- html列表拖拽排序插件,JS拖拽排序插件Sortable.js用法实例分析
本文实例讲述了JS拖拽排序插件Sortable.js用法.分享给大家供大家参考,具体如下: 最近由于项目功能设计的原因,需要对table中的行实现拖拽排序功能,找来找去发现Sortable.js能很好 ...
- Vue 实现拖拽模块(二)自定义拖拽组件位置
上文介绍了 拖拽添加组件 的简单实现,本文将继续给大家分享如何自定义拖拽组件位置的简单实现,文中通过示例代码介绍,感兴趣的小伙伴们可以了解一下 本文主要介绍了 Vue自定义拖拽组件位置的简单实现,具体 ...
最新文章
- 日本未来投资重点领域是物联网和人工智能应用
- 【网络安全】2022年第一次靶场渗透实战学习
- 处理上百万条的数据库如何提高处理查询速度
- ZigBee网络架构详解
- c/c++面试试题(一)
- Opencl 并行求和
- 小学生四则运算JAVA
- ae中心点重置工具_如何使用AE制作文字破碎动画?制作ae破碎文字特效教程分享...
- Java-第三章-从键盘输入整数判断是3和5的倍数!
- 利用 Python 插件 xlwings 读写 Excel
- Windows server 2012体验之活动目录回收站
- python中常用的函数有哪些_python里常用的函数类型
- 一个好的系统就这么粗俗
- linux opendir,linux opendir和readdir的使用
- 【虚拟机\UBunTu】E45: 已设定选项 ‘readonly‘ (请加 ! 强制执行)
- [转载]国内物联网平台初探(三):QQ物联智能硬件开放平台
- Linux线程性能分析和CPU亲和力
- 大厂app出海攻略|一个方法让app推广变现能力双效提升
- Android读取联系人的姓名及电话号码
- 计算机教师格言座右铭,教师格言座右铭100句