使用vue.draggable实现两列数组之间的复制拖拽

需要先了解:

Sortable.js插件的配置信息
vue.draggable的clone拷贝实现常用菜单功能
本文参考文章 记录一下vuedraggable clone的坑,获取数据

前排提示: 如果你也遇到了编辑拖拽的单元数据时,原单元数据也跟着发生了变化,可以直接拖到最后看解决方法。

要实现的效果
有两个列表:
列表A为预设的组件,不能添加编辑和删除;
列表B为编辑区域,需要从列表A中拖拽组件,然后修改组件名称等一些信息。
在这里插入图片描述
通过分析需求,我们可以知道:

  1. 列表A和B的group name需相同;
  2. 列表A需要设置:
  • 移动单元时,移动的为该单元副本
  • 不可向列表内拖拽组件
  • 列表页单元不能排序

由此可以得出列表A:

<draggable v-model="defaultFields" :sort="false" :group="{name:'piece',pull:'clone',put:false}">
    <div v-for="item in defaultFields">
        <span class="icon"><i :class="item.icon"></i></span>
        <span class="name">{{item.name}}</span>
    </div>
</draggable>

列表B:

<draggable
   v-model="fields"
   :group="{name:'piece'}"
   animation="200"
   @add="addFlowField"
>
	<div v-for='(item, index) in tableFlow[thisFlow.index].fields' @click='setFieldData(index)'>
	    <!-- 中间代码省略(通过判断item.type来渲染不同的页面样式) -->
	</div>
</draggable>

列表A与B中的数据结构:(两个数组之间的数据结构均大致相同,仅对页面渲染产生影响,并不会影响到拖拽后列表单元的数据)

[
     {
         name:'单行文本',
         description:'',
         type:'string',
         default_value:'',
         form_not_null:0,
         is_search:0,
         // 是否允许使用相册
         is_album:0,
         // 图标
         icon: 'fa fa-pencil-square-o'
     },
     {
         name:'多行文本',
         description:'',
         type:'textarea',
         default_value:'',
         form_not_null:0,
         is_search:0,
         // 是否允许使用相册
         is_album:0,
         // 图标
         icon: 'fa fa-file-text-o'
     },
     // ...省略部分数据
 ]

当从列表A拖拽单元到列表B时,可以达到我们的要求:
在这里插入图片描述
但是当我们需要修改拖拽得到的单元信息时(比如名称),列表A中对应的单元也发生了变化:
在这里插入图片描述
这是因为在拖拽时,vue.draggable只是从列表A复制了对应位置的数据,然后插入到列表B,这个数据的指针(?)并没有发生变化,都是指向列表A中的单元,所以在修改时,就相当于修改了列表A中的单元数据。

解决方法

在复制列表A中的单元时,深拷贝一份数据到列表B,而不是直接复制。
在列表A中添加 :clone 事件,对拖拽的数据进行二手加工:(注意不是 @clone )

<draggable v-model="defaultFields" :sort="false" :group="{name:'piece',pull:'clone',put:false}" :clone="cloneDefaultField">
    <div v-for="item in defaultFields">
        <span class="icon"><i :class="item.icon"></i></span>
        <span class="name">{{item.name}}</span>
    </div>
</draggable>
cloneDefaultField(e){
    return JSON.parse(JSON.stringify(e));
}
  • 15
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值