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& ...
随机推荐
- Spring源码:Bean生命周期(五)
前言 在上一篇文章中,我们深入探讨了 Spring 框架中 Bean 的实例化过程,该过程包括从 Bean 定义中加载当前类.寻找所有实现了 InstantiationAwareBeanPostPro ...
- TestForPicGo
如果显示,则为成功 否则,失败 同时为CN-BLOG的vscode插件进行测试
- Odoo 13之十三 :开发之创建网站前端功能
Odoo 13开发之创建网站前端功能 Odoo 起初是一个后台系统,但很快就有了前端界面的需求.早期基于后台界面的门户界面不够灵活并且对移动端不友好.为解决这一问题,Odoo 引入了新的网站功能,为系 ...
- Outlook无法启动一直显示“正在启动”的解决方法
缘起 今天早上打开电脑以后,就打开Outlook2016了,一直显示这个界面: 我没在意就干别的事了, 可以半个小时过去了,还是这个界面,我慌了. 解决方法 安全模式打开Outlook 按WIN + ...
- 经纬度坐标为中心点生成米距离长度半径的圆形面,含java js源码+在线绘制,代码简单零依赖
目录 java版源码 js版源码 在线绘制预览效果 关于计算的精确度 前些时间在更新我的坐标边界查询工具的时候,需要用到经纬度坐标点的距离计算,和以坐标点为中心生成一个指定距离为半径的圆,搜了一下没有 ...
- 驱动开发:内核RIP劫持实现DLL注入
本章将探索内核级DLL模块注入实现原理,DLL模块注入在应用层中通常会使用CreateRemoteThread直接开启远程线程执行即可,驱动级别的注入有多种实现原理,而其中最简单的一种实现方式则是通过 ...
- zabbix 监控nginx
nginx内置了一个status状态的功能,通过配置可以看到nginx的运行情况,status显示的内容包括当前连接数,处于活动状态的连接数,已经处理的请求数等等,可以利用这个功能编写zabbix监控 ...
- C#语言async, await 简单介绍与实例(入门级)
本文介绍异步编程的基本思想和语法.在程序处理里,程序基本上有两种处理方式:同步和异步.对于有些新手,甚至认为"同步"是同时进行的意思,这显然是错误的. 同步的基本意思是:程序一个个 ...
- C++ Tips of the Week-01 string_view
1: string_view ref https://abseil.io/tips/1 函数参数需要是一个字符串的时候,通常的实现有以下几种: // C Convention void TakesCh ...
- #mac安装Homebrew报错问题:curl: (7) Failed to connect to raw.githubusercontent.com port 443: Connection refused
我们在打开https://brew.sh/index_zh-cn官网的时候都会给你下面这段代码,粘贴复制就可以安装: /bin/bash -c "$(curl -fsSL https://r ...