Vue【原创】可拖动列表 darg-list
可拖动排序的列表 drag-list,这个比较简单易懂,拿例子直接运行看效果就好了。
组件代码:


1 <template>
2 <ul class="list" ref="parentNode" @dragstart="onDragStart" @dragover="onDragOver" @dragend="onDragEnd">
3 <li class="list-item" v-for="(item, index) in dataProvider" :key="item[valueKey]" :id="item[valueKey]"
4 :draggable="draggable">
5 <slot :item="item" :index="index">
6 <div>{{ item }}</div>
7 </slot>
8 </li>
9 </ul>
10 </template>
11
12 <script>
13 const _LI_ = 'LI';
14
15 export default {
16 name: 'LiloDragList',
17 props: {
18 dataProvider: {
19 type: Array,
20 default () {
21 return {}
22 }
23 },
24 draggable: {
25 type: Boolean,
26 default: true
27 },
28 valueKey: {
29 type: String,
30 default: 'id'
31 }
32 },
33 data() {
34 return {
35 draging: null,
36 target: null
37 };
38 },
39 mounted() {
40 document.body.ondrop = event => {
41 event.preventDefault();
42 event.stopPropagation();
43 };
44 },
45 methods: {
46 onDragStart(event) {
47 // console.log('drag start');
48 this.draging = event.target;
49 },
50 onDragOver(event) {
51 // console.log(event.target.nodeName);
52 this.target = event.target;
53 let targetTop = event.target.getBoundingClientRect().top;
54 let dragingTop = this.draging.getBoundingClientRect().top;
55 if (this.target.nodeName === _LI_ && this.target !== this.draging) {
56 if (this.target) {
57 if (this.target.animated) {
58 return;
59 }
60 }
61
62 if (this._index(this.draging) < this._index(this.target)) {
63 this.target.parentNode.insertBefore(this.draging, this.target.nextSibling);
64 } else {
65 this.target.parentNode.insertBefore(this.draging, this.target);
66 }
67 this._anim(targetTop, this.target);
68 this._anim(dragingTop, this.draging);
69 }
70 },
71 _anim(startPos, dom) {
72 let offset = startPos - dom.getBoundingClientRect().top;
73 dom.style.transition = 'none';
74 dom.style.transform = `translateY(${offset}px)`;
75
76 //触发重绘
77 dom.offsetWidth;
78 dom.style.transition = 'transform .3s';
79 dom.style.transform = ``;
80 //触发重绘
81 // setTimeout(()=>{
82 // dom.style.transition="transform .3s";
83 // dom.style.transform=``;
84 // },0)
85 clearTimeout(dom.animated);
86
87 dom.animated = setTimeout(() => {
88 dom.style.transition = '';
89 dom.style.transform = ``;
90 dom.animated = false;
91 }, 300);
92 },
93 onDragEnd(event) {
94 // console.log('drag end');
95 let temp = Array.from(this.$refs.parentNode.childNodes);
96 let currentNodes = temp.filter(node => {
97 return node.nodeName === _LI_
98 })
99 let list = currentNodes.map((i, index) => {
100 let item = this.dataProvider.find(c => {
101 const unikey = i.getAttribute(this.valueKey);
102 const flag = c[this.valueKey] === unikey;
103 return flag;
104 });
105 return item;
106 });
107
108 this.$emit('sorted', list);
109 },
110 _index(el) {
111 let domData = Array.from(this.$refs.parentNode.childNodes);
112 return domData.findIndex(i => i.innerText == el.innerText);
113 }
114 }
115 };
116 </script>
117
118 <style lang="scss" scoped>
119 .list {
120 padding-inline-start: 0;
121
122 .list-item {
123 transition: 0.3s all ease-in;
124 padding: 12px;
125 border-bottom: 1px solid #dbdbdb;
126 list-style: none;
127 margin: 0px;
128
129 &:hover {
130 background-color: #dbdbdb;
131 }
132 }
133 }
134 </style>
调用案例:
1 <template>
2 <div class="drag-list">
3 <lilo-drag-list :dataProvider="dataProvider" draggable :valueKey="valueKey" @sorted="sorted">
4 <template slot-scope='{ item, index }'>
5 <div>
6 <span class="list-item">index:{{ index }}</span>
7 <span class="list-item">id:{{ item.id }}</span>
8 <span class="list-item">name:{{ item.name }}</span>
9 <span class="list-item">address:{{ item.address }}</span>
10 </div>
11 </template>
12 </lilo-drag-list>
13 </div>
14 </template>
15
16 <script>
17 export default {
18 data() {
19 return {
20 draggable: true, //是否可拖动,默认为true
21 valueKey: 'id', //数据项的唯一标识
22 dataProvider: [
23 { id: 'S001', name: '张三', address: '湖北省武汉市江岸区百步亭花园现代城3区' },
24 { id: 'S002', name: '李四', address: '湖北省武汉市江岸区百步亭花园现代城3区' },
25 { id: 'S003', name: '王五', address: '湖北省武汉市江岸区百步亭花园现代城3区' },
26 { id: 'S004', name: '张飞', address: '湖北省武汉市江岸区百步亭花园现代城3区' },
27 { id: 'S005', name: '关羽', address: '湖北省武汉市江岸区百步亭花园现代城3区' },
28 { id: 'S006', name: '嬴政', address: '湖北省武汉市江岸区百步亭花园现代城3区' },
29 { id: 'S007', name: '廉颇', address: '湖北省武汉市江岸区百步亭花园现代城3区' },
30 { id: 'S008', name: '蒙恬', address: '湖北省武汉市江岸区百步亭花园现代城3区' },
31 { id: 'S009', name: '韩非', address: '湖北省武汉市江岸区百步亭花园现代城3区' }
32 ]
33 }
34 },
35 methods: {
36 sorted(list) { //拖动完成之后触发
37 console.log(list) //改变后的数组顺序
38 console.log(this.dataProvider) //原数据顺序不会被改变
39 }
40 }
41 }
42 </script>
43
44 <style lang="scss" scoped>
45 .drag-list {
46 padding: 10px;
47 .list-item {
48 margin: 0 5px;
49 }
50 }
51 </style>
Vue【原创】可拖动列表 darg-list的更多相关文章
- vue+mousemove实现拖动,鼠标移动过快拖动就失效
今天用vue+原生js的mousemove事件,写了个拖动,发现只能慢慢拖动才行,鼠标只要移动快了,就失效,不能拖动了: 搞了半天在,总算解决了,但是问题的深层原理还没搞清楚,知道的大侠可以留言分享, ...
- vue实现购物清单列表添加删除
vue实现购物清单列表添加删除 一.总结 一句话总结: 基础的v-model操作,以及数组的添加(push)删除(splice)操作 1.checkbox可以绑定数组,也可以直接绑定值? 绑定数组就是 ...
- vue指令实现拖动的高级写法
不熟悉vue自定义指令看这里: https://cn.vuejs.org/v2/guide/custom-directive.html vue指令实现拖动方法很方便也挺简单,但是网上大部分的教程代码, ...
- Android 可拖动列表项的ListView
需求分析 一个界面内两个ListView 我关注的栏目列表 上面的要长按后可拖动排序 点击减号后列表项消失 下面列表增加一行 同时存储相应字符串到本地作为标记 未关注栏目列表 普通ListView 点 ...
- vue v-nav指令属性列表
v-nav指令属性列表 属性名 属性描述 类型 必选 默认 title 导航栏标题 String No 空字符串 showBackButton 是否显示(左边的)返回按钮 Boolean No fal ...
- VUE通过id从列表页跳转到相对的详情页
新闻列表页面: 在这里我用a标签进行跳转,在vue里面可以这样写<router-link></router-link> 1 <router-link :to=" ...
- vue里面的v-for列表循环
列表渲染 v-for v-for可以把数据中的一个数组对应为一组元素v-for 指令需要以 item in items 形式的特殊语法, items 是源数据数组并且 item 是数组元素迭代的别名. ...
- Vue基础进阶 之 列表过渡
在前面的博客我们一直在操作单个元素的过渡,如果是对多个元素过渡,例如列表,这时就要用到<transition-group>这个组件了: 如何使用:将要操作的列表元素放在<transi ...
- vue 自学笔记(5) 列表渲染
列表渲染 一:v-for 指令 当我们涉及到列表渲染数据的时候,不可能做一个重复的工作去不停的一个一个的渲染每一项列表.并且列表数据的表现,比如从后端请求过来的数据,不可能是一个一个的单独的 JSON ...
- 【前端】Vue.js实现网格列表布局转换
网格列表布局转换 实现效果: 实现代码及注释: <!DOCTYPE html> <html> <head> <title>布局转换</title& ...
随机推荐
- 又一个开源便斩获 7k star 的新模型「GitHub 热点速览」
Star 并不能代表什么,但是绝对能表示一个项目的受欢迎程度.就像刚开源一周就有 7k+ star 的新模型,输入文本 / 图像就能获得 3D 对象.除了这个新模型,本周还有一款新的 Web 3D 渲 ...
- 如何让ChatGPT生成Midjourney提示词
导读:最近AI绘画非常的火,今天我们看ChatGPT如何生成Midjourney提示词,让AI教AI做事. 本文字数:900,阅读时长大约:3分钟 正如 Midjourney 的官方网站报道的那样 ...
- 06、HSMS协议介绍
本章的内容主要参考了 SECS半导体设备通讯-2 HSMS通信标准 ,外加上自己看的一些其他的文档.也加上了一些自己的理解,特此记录.若有侵权,请联系删除,谢谢. 再次特别感谢 SECS半导体设备通讯 ...
- ChatGLM 拉取清华git项目
windows使用nvdia显卡运行ChatGLM 1. 安装nvidia显卡驱动 https://developer.nvidia.com/cuda-11-8-0-download-archive? ...
- 没用,随便写的(Dec_8_2022)
import numpy as np from PIL import Image import pandas as pd import matplotlib.pyplot as plt # 第一个 # ...
- iOS 单元测试之常用框架 OCMock 详解
一.单元测试 1.1 单元测试的必要性 测试驱动开发并不是一个很新鲜的概念了.在日常开发中,很多时候需要测试,但是这种输出是必须在点击一系列按钮之后才能在屏幕上显示出来的东西.测试的时候,往往是用模拟 ...
- 洛谷 P5979 [PA2014] Druzyny
简要题意 有 \(n\) 个人,把他们划分成尽可能多的区间,其中第 \(i\) 个人要求它所在的区间长度大于等于 \(c_i\),小于等于 \(d_i\),求最多的区间数量以及如此划分的方案数. 数据 ...
- 前端vue uni-app多图片上传组件,支持单个文件,多个文件上传 步骤条step使用
快速实现多图片上传组件,支持单个文件,多个文件上传 步骤条step使用; 下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=1274 ...
- LLM技术在自然语言处理中的实践与改进
目录 <LLM技术在自然语言处理中的实践与改进> 引言 自然语言处理 (NLP) 是人工智能领域的一个重要分支,它研究如何将计算机程序与人类语言进行交互,从而理解.分析.生成和翻译文本.近 ...
- 记一次字符串末尾空白丢失的排查 → MySQL 是会玩的!
开心一刻 今天答应准时回家和老婆一起吃晚饭,但临时有事加了会班,回家晚了点 回到家,本以为老婆会很生气,但老婆却立即从厨房端出了热着的饭菜 老婆:还没吃饭吧,去洗下,来吃饭吧 我洗好,坐下吃饭,内心感 ...