当前位置:网站首页>如何玩转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
边栏推荐
- Details of dapr implementing distributed stateful service
- WeihanLi.Npoi 1.11.0/1.12.0 Release Notes
- Why do private enterprises do party building? ——Special subject study of geek state holding Party branch
- Jmeter——ForEach Controller&Loop Controller
- PHP应用对接Justswap专用开发包【JustSwap.PHP】
- OPTIMIZER_ Trace details
- EOS创始人BM: UE,UBI,URI有什么区别?
- Existence judgment in structured data
- 熬夜总结了报表自动化、数据可视化和挖掘的要点,和你想的不一样
- 做外包真的很难,身为外包的我也无奈叹息。
猜你喜欢
Elasticsearch database | elasticsearch-7.5.0 application construction
Face to face Manual Chapter 16: explanation and implementation of fair lock of code peasant association lock and reentrantlock
Just now, I popularized two unique skills of login to Xuemei
条码生成软件如何隐藏部分条码文字
Calculation script for time series data
How long does it take you to work out an object-oriented programming interview question from Ali school?
中小微企业选择共享办公室怎么样?
Subordination judgment in structured data
PLC模拟量输入和数字量输入是什么
從小公司進入大廠,我都做對了哪些事?
随机推荐
Cos start source code and creator
人工智能学什么课程?它将替代人类工作?
[performance optimization] Nani? Memory overflow again?! It's time to sum up the wave!!
全球疫情加速互联网企业转型,区块链会是解药吗?
Synchronous configuration from git to consult with git 2consul
Using Es5 to realize the class of ES6
Real time data synchronization scheme based on Flink SQL CDC
合约交易系统开发|智能合约交易平台搭建
Troubleshooting and summary of JVM Metaspace memory overflow
【新閣教育】窮學上位機系列——搭建STEP7模擬環境
比特币一度突破14000美元,即将面临美国大选考验
03_ Detailed explanation and test of installation and configuration of Ubuntu Samba
如果前端不使用SPA又能怎样?- Hacker News
Details of dapr implementing distributed stateful service
Filecoin最新动态 完成重大升级 已实现四大项目进展!
《Google軟體測試之道》 第一章google軟體測試介紹
Vuejs development specification
In depth understanding of the construction of Intelligent Recommendation System
快快使用ModelArts,零基礎小白也能玩轉AI!
How do the general bottom buried points do?