当前位置:网站首页>如何玩转sortablejs-vuedraggable实现表单嵌套拖拽功能
如何玩转sortablejs-vuedraggable实现表单嵌套拖拽功能
2020-11-06 20:37:00 【叫我詹躲躲】
最近几天在研究有关vue实现拖拽的功能,不过跟一般的拖拽排序有点不同,这个需求可能出现多行多列嵌套的表单元素,数据也是递归形式的出现。我也是在vuedraggable的基础上扩展实现的,如何想了解更多的拖拽排序功能可以参考https://sortablejs.github.io/Vue.Draggable/#/simple
需要实现的功能
- 表单元素可能出现嵌套,数据出现树形结构
- 实现拖拽功能,表单元素可以移动到空的列里面,但是表单元素内容的不能来回拖拽排序
- 行与行之间可以拖动排序,列与列直接不能移动排序,能移动的只是字段数据也就是表单元素
- 右边列表里的字段可以拖拽添加到左边的空白没内容的列里面
用的技术点
- vue组件递归实现
- vuedraggable拖拽排序
- vuedraggable的例子Functional third party,主要是元素移动
- vuedraggable实现拖拽复制功能
- vuetify :vue ui组件,这里面主要用了它的删格系统和vcard卡片
实现功能的部分代码
Drag组件也是要递归的组件代码
<template>
<draggable
v-model="datas"
tag="v-layout"
class="row wrap fill-height align-center sortable-list"
style="background: grey;"
>
<v-flex
v-for="row in datas"
:key="row.index"
class="sorttable"
xs12
my-2
style="background: red"
>
<div class="row wrap justify-space-around">
<v-flex
v-for="item in row.items"
:key="item.id"
xs4
pa-3
class="row-v"
>
<!-- 加判断如果item存在rows数组,则递归继续执行这个组件-->
<template v-if="item.rows && Array.isArray(item.rows)">
<drag :data="item.rows" />
</template>
<draggable
v-else
:list="item.data"
tag="div"
:group="{ name: 'row'}"
:move="getData"
:animation="100"
:empty-insert-threshold="60"
@change="log"
>
<v-card
v-for="item2 in item.data"
:key="item2.title"
style="height: 100px;"
>
{
{
item2.title }}
</v-card>
</draggable>
</v-flex>
</div>
</v-flex>
</draggable>
</template>
<script>
import draggable from 'vuedraggable'
import Vue from 'vue'
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css'
Vue.use(Vuetify)
export default {
name: 'Drag',
order: 17,
components: {
draggable
},
props: {
data: {
type: Array,
default () {
return []
}
}
},
data () {
return {
datas: this.data,
controlOnStart: true
}
},
methods: {
// 限制移动的方法
getData (e, d) {
if (e.relatedContext.list.length > 0) {
return false
}
},
log: function (evt) {
// window.console.log(evt)
// console.log(this.data)
if (Object.keys(evt)[0] === 'added') {
this.arrLoop(this.data, evt.added.element)
}
},
addHandler (e, d) {
// console.log(e)
},
endHandler (e, b) {
console.log(b)
},
// 递归实现遍历数据
arrLoop (arr, ele) {
arr.forEach(item => {
const itemArr = item.data
if (itemArr && itemArr.length > 1) {
for (let i = 0; i < itemArr.length; i++) {
if (itemArr[i].title === ele.title) {
itemArr.splice(i, 1)
}
}
}
if (item.items && item.items.length) {
this.arrLoop(item.items, ele)
}
})
}
}
}
</script>
<style>
.buttons {
margin-top: 35px;
}
.row-v {
/* height: 150px; width: 200px; */
width: 33%;
height: 100px;
display: inline-block;
background: blue;
border: 1px solid #ebebeb;
}
.row {
margin-left: 0;
margin-right: 0;
}
.ghost {
opacity: 0.5;
background: #c8ebfb;
}
</style>
注意:实现递归一定定义Drag组件的name值,要不就容易报错
emptyInsertThreshold:拖动时,鼠标必须与空的可排序对象之间的距离(以像素为单位),以便将拖动元素插入到该可排序对象中。默认为5。设置为0禁用此功能。这个参数要适当的设置,如果是默认值,当列为空的时候,很难把元素拖进去,这个也是一个比较难解决的点,因为需要把右边字段元素拖动到左边空列中,或者左边的元素移动到空的列里。
move对应方法getData的方法主要实现如果relatedContext.list.length 大于0,则取消移动功能。
Drag的数据:
rows: [
{
index: 1,
items: [
{
id: 1,
data: [{
title: 'item 1'
}]
},
{
id: 11,
data: [{
title: 'item 11'
}]
},
{
id: 12,
data: [
]
}
]
},
{
index: 2,
items: [
{
id: 0,
rows: [
{
index: 1,
items: [
{
id: 2,
data: [{
title: 'item 211'
}]
},
{
id: 3,
data: [{
title: 'item 212'
}]
}
]
},
{
index: 2,
items: [
{
id: 4,
data: [
{
title: 'item 222'
}
]
}
]
}
]
},
{
id: 5,
data: [{
title: 'item 3'
}]
}
]
},
{
index: 3,
items: [
{
id: 6,
data: [{
title: 'item 4'
}]
},
{
id: 7,
data: [{
title: 'item 5'
}]
},
{
id: 8,
data: []
}
]
}
]
右边列表的组件代码:
<template>
<div>
<div
v-for="item in datas"
:key="item.id"
class="item-box"
>
<h2>{
{
item.title }}</h2>
<div class="item-con">
<draggable
class="dragArea list-group"
:list="item.items"
:group="{ name: 'row', pull: 'clone', put: false }"
:clone="cloneDog"
>
<span
v-for="item2 in item.items"
:key="item2.id"
>
{
{
item2.title }}
</span>
</draggable>
</div>
</div>
</div>
</template>
<script>
import draggable from 'vuedraggable'
export default {
name: 'Drag',
components: {
draggable
},
props: {
data: {
type: Array,
default () {
return []
}
}
},
data () {
return {
datas: [
{
id: 1,
title: '标题1',
items: [
{
id: 11,
title: 'item 11'
},
{
id: 12,
title: 'item 12'
}
]
},
{
id: 2,
title: '标题2',
items: [
{
id: 21,
title: 'item 21'
},
{
id: 22,
title: 'item 22'
}
]
}
]
}
},
methods: {
cloneDog (ele) {
// console.log(ele)
let b = this.arrLoop(this.rows, ele)
if (!b) {
return ele
}
},
arrLoop (arr, ele) {
for (let i = 0; i < arr.length; i++) {
if (arr[i].id === ele.id) {
return true
}
if (arr[i].items && arr[i].items.length) {
return this.arrLoop(arr[i].items, ele)
}
}
}
}
}
</script>
<style lang="scss" scoped>
.list-group{
span {
display: inline-block;
padding: 0 12px;
border-radius: 4px;
border: 1px solid #ebebeb;
line-height: 32px;
height: 32px;
background: #f5f5f5;
margin-right: 15px;
}
}
</style>
clone的cloneDog方法实现复制功能,首先递归循环数据判断是需要复制的元素在左边的列表中是否存在,若是存在,则取消复制,不存在,则复制。
效果如下图:
总结
这篇文章分享的主要技术点就是vuedraggable拖拽排序和复制、嵌套拖拽排序功能、vue组件递归功能。
版权声明
本文为[叫我詹躲躲]所创,转载请带上原文链接,感谢
https://my.oschina.net/u/3995971/blog/4558947
边栏推荐
- Menu permission control configuration of hub plug-in for azure Devops extension
- Listening to silent words: hand in hand teaching you sign language recognition with modelarts
- 如何将数据变成资产?吸引数据科学家
- Technical director, to just graduated programmers a word - do a good job in small things, can achieve great things
- 选择站群服务器的有哪些标准呢?
- Skywalking series blog 5-apm-customize-enhance-plugin
- High availability cluster deployment of jumpserver: (6) deployment of SSH agent module Koko and implementation of system service management
- 技術總監,送給剛畢業的程式設計師們一句話——做好小事,才能成就大事
- 业内首发车道级导航背后——详解高精定位技术演进与场景应用
- Don't go! Here is a note: picture and text to explain AQS, let's have a look at the source code of AQS (long text)
猜你喜欢
采购供应商系统是什么?采购供应商管理平台解决方案
“颜值经济”的野望:华熙生物净利率六连降,收购案遭上交所问询
Swagger 3.0 天天刷屏,真的香嗎?
Filecoin最新动态 完成重大升级 已实现四大项目进展!
Don't go! Here is a note: picture and text to explain AQS, let's have a look at the source code of AQS (long text)
Existence judgment in structured data
Use of vuepress
Cos start source code and creator
Python自动化测试学习哪些知识?
Computer TCP / IP interview 10 even asked, how many can you withstand?
随机推荐
03_ Detailed explanation and test of installation and configuration of Ubuntu Samba
GUI 引擎评价指标
人工智能学什么课程?它将替代人类工作?
快快使用ModelArts,零基礎小白也能玩轉AI!
iptables基礎原理和使用簡介
DTU连接经常遇到的问题有哪些
Sort the array in ascending order according to the frequency
Existence judgment in structured data
“颜值经济”的野望:华熙生物净利率六连降,收购案遭上交所问询
Face to face Manual Chapter 16: explanation and implementation of fair lock of code peasant association lock and reentrantlock
How to select the evaluation index of classification model
Listening to silent words: hand in hand teaching you sign language recognition with modelarts
制造和新的自动化技术是什么?
网络安全工程师演示:原来***是这样获取你的计算机管理员权限的!【维持】
從小公司進入大廠,我都做對了哪些事?
Filecoin的经济模型与未来价值是如何支撑FIL币价格破千的
Details of dapr implementing distributed stateful service
TRON智能钱包PHP开发包【零TRX归集】
阿里云Q2营收破纪录背后,云的打开方式正在重塑
C++和C++程序员快要被市场淘汰了