vue2 draggable拖拽组件的使用及注意事项

文章介绍了在Vue项目中使用vuedraggable插件实现拖拽功能的方法,包括安装、引入、v-model绑定、group设置、tag、animation属性和add事件。同时,文中提到了两个关键问题:一是需设置拖拽容器的高度,二是拖拽克隆时要避免直接赋值导致的数据同步。解决方案是设置容器高度和使用深拷贝避免属性值冲突。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

记录draggable拖拽组件的使用方法以及遇到的问题。

参考文章draggable拖拽组件使用

参考文章Vue项目拖拽插件 ---- vuedraggable的安装与使用

  • 效果图

 vue.draggable中文api地址https://www.itxst.com/vue-draggable/tutorial.html

  •  安装
npm install vuedraggable
  • 引入与使用
<template>
  <div class="cardDrag-container common-container">
    <div class="cardDrag-content">
      <div class="left-drag-container">
        <draggable
          tag="ul"
          class="cardDrag-list-wrap"
          v-model="leftComponentsList"
          :group="groupLeft"
          animation="300"
        >
          <li
            class="cardDrag-list"
            v-for="item in leftComponentsList"
            :key="item.id"
          >
            <div class="cardDrag">
              <svg-icon class="svg-width" :iconClass="item.icon"></svg-icon>
              <label>{{item.name}}</label>
            </div>
          </li>
        </draggable>
      </div>
      <div class="right-drag-container">
        <draggable
          tag="ul"
          class="cardDrag-list-wrap"
          v-model="rightComponentsList"
          :group="groupRight"
          animation="300"
          @add="handleAdd"
        >
          <li
            class="cardDrag-list"
            v-for="item in rightComponentsList"
            :key="item.id"
          >
            <div class="cardDrag cardBackground" :style="computedStyle">
              <div class="card-box">
                <svg-icon class="svg-width" :iconClass="item.icon"></svg-icon>
                <label>{{item.name}}({{item.orderId}})</label>
              </div>
            </div>
          </li>
        </draggable>
      </div>
    </div>
  </div>
</template>
<script>
import draggable from 'vuedraggable'
import _ from 'lodash'
export default {
  name: 'index',
  components: {
    draggable,
  },
  data(){
    return{
      leftComponentsList:[
        { id: 1, orderId: 1, name: '电商购物评价', icon: 'dianshanggouwupingjia' },
        { id: 2, orderId: 2, name: '波特五利', icon: 'bote5li' },
        { id: 3, orderId: 3, name: '提炼产品卖点', icon: 'tilianchanpinmaidian' },
        { id: 4, orderId: 4, name: '写周报', icon: 'xiezhoubao' },
      ],
    rightComponentsList:[
        { id: 11, orderId: 109, name: '产品卖货笔记', icon: 'chanpinmaihuobiji' },
        { id: 12, orderId: 110, name: '优化简历', icon: 'youhuajianli' },
        { id: 13, orderId: 111, name: '数据分析', icon: 'shujufenxi' },
        { id: 14, orderId: 112, name: '用户画像', icon: 'xieyonghuhuaxiang' },
      ],
      groupLeft:{
        name: 'itxst',
        pull: 'clone',  // 拖出
        put: false,   // 拖入
      },
      groupRight:{
        name: 'itxst',
        pull: false,  // 拖出
        put: true,   // 拖入
      },
    }
  },

}
</script>

v-model绑定拖拽的数组。

下面说明一下用到的属性及事件。

  • group

拖拽分组,多组之间相互拖拽,可以实现不同数组之间相互拖拽。例如group都为itxst的分组可以相互拖拽。

//设置方式一,直接设置组名
group:'itxst'
//设置方式,object,也可以通过自定义函数function实现复杂的逻辑
group:{
    name:'itxst',//组名为itxst
    pull: true|false| 'clone'|array|function,//是否允许拖出当前组
    put:true|false|array|function,//是否允许拖入当前组
}
  • tag

draggable 标签在渲染后展现出来的标签类型,默认渲染成div。

  • animation

拖拽时的动画时间,单位:ms。

  • add

添加单元时的回调函数。

下面列出在使用draggable过程中发现的两个问题。

  • 注意事项一

需要设置拖拽容器的高度,否则,当容器内没有小块时,高度为0,再想拖拽小块进入该容器就拖不进去了。

<style lang="scss">
.left-drag-container div span{
  display: inline-block;
  width: 100% !important;
  height: calc(100vh - 180px) !important;
}

.right-drag-container div span{
  display: inline-block;
  width: 100% !important;
  height: calc(100vh - 180px) !important;
}
</style>
  • 注意事项二

在这里,左边的容器拖出时是clone模式,连续拖拽同一个到右边容器时,控制台提示报错,并且组件展示的内容都一样,组件的属性值也被修改成相同的值。

页面的展示内容

此时的代码是这么写的

    handleAdd(e){
      const newIndex = e.newIndex
      const newCard = this.rightComponentsList[newIndex]
      newCard.id = this.randomNumber()
      newCard.orderId = this.cardId
      this.cardId = this.cardId + 1
      this.$set(this.rightComponentsList,newIndex,newCard)
    },

可以看到页面上,新拖拽的三个组件显示的orderId是一样的,后来发现造成这个错误是因为,在右边容器添加组件,取该组件的属性时使用的是简单赋值,在拖拽新的组件时,修改了同组件的属性值。

代码做如下修改

    handleAdd(e){
      const newIndex = e.newIndex
      // 深拷贝
      const newCard = _.cloneDeep(this.rightComponentsList[newIndex])  
      newCard.id = this.randomNumber()
      newCard.orderId = this.cardId
      this.cardId = this.cardId + 1
      this.$set(this.rightComponentsList,newIndex,newCard)
    },

 以上就是在使用过程中发现的问题啦~

Vue 项目中结合 `el-table` 组件与 `vue-draggable-plus` 实现可拖拽的表格,是一种较为灵活的方式来增强用户交互体验。以下是一个详细的实现步骤: ### 安装依赖 首先确保安装了必要的依赖包,包括 `element-plus` 和 `vue-draggable-plus`。 ```bash npm install element-plus vue-draggable-plus --save ``` 如果使用的是 Vue 2,则应选择兼容 Vue 2 的版本;如果是 Vue 3,则可以直接使用最新版。 ### 引入组件 在你的 Vue 文件中引入所需的组件,并注册它们。 ```javascript import { defineComponent } from 'vue'; import { ElTable, ElTableColumn } from 'element-plus'; import Draggable from 'vue-draggable-plus'; export default defineComponent({ components: { ElTable, ElTableColumn, Draggable } }); ``` ### 模板部分 在模板中使用 `<draggable>` 包裹 `<el-table>`,并设置相关属性来启用拖拽功能。 ```html <template> <draggable :list="tableData" @end="onDragEnd"> <el-table :data="tableData" style="width: 100%"> <el-table-column prop="date" label="日期" width="150"></el-table-column> <el-table-column prop="name" label="姓名" width="200"></el-table-column> <el-table-column prop="address" label="地址"></el-table-column> </el-table> </draggable> </template> ``` ### 数据与方法 定义数据和拖拽结束后的回调函数。 ```javascript export default defineComponent({ setup() { const tableData = ref([ { date: '2024-07-01', name: '张三', address: '北京市' }, { date: '2024-07-02', name: '李四', address: '上海市' }, { date: '2024-07-03', name: '王五', address: '广州市' } ]); const onDragEnd = () => { // 可以在这里执行保存顺序或其他逻辑 console.log('拖拽结束,当前顺序:', tableData.value); }; return { tableData, onDragEnd }; } }); ``` ### 样式调整(可选) 为了更好的用户体验,可以为拖拽元素添加一些过渡效果或样式。 ```css .draggable-move { transition: transform 0.3s; } ``` ### 注意事项 - 确保 `vue-draggable-plus` 的版本与你的 Vue 版本兼容。 - 如果表格数据是通过 API 获取的,请确保在数据加载完成后才进行拖拽操作。 - 对于树形结构的数据,需要额外处理层级关系,确保拖拽后仍能正确显示树形结构 [^3]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值