Vue实现高效拖拽效果 vue-Draggable

Vue.Draggable是基于Sortable.js的Vue组件,提供直观的拖拽排序功能,支持列表项拖拽、跨列表拖拽、动画效果等特性

安装

npm install vuedraggable

组件引用

javascript 复制代码
import draggable from 'vuedraggable'

export default {
    components: {
        draggable
    }
}

1.基础拖拽排序

javascript 复制代码
<template>
  <draggable v-model="list">
    <div v-for="item in list" :key="item.id">{{ item.name }}</div>
  </draggable>
</template>
<script>
import draggable from 'vuedraggable';
export default {
  components: { draggable },
  data() {
    return {
      list: [
        { id: 1, name: 'Item 1' },
        { id: 2, name: 'Item 2' },
      ]
    };
  }
};
</script>

2.跨列表拖拽

javascript 复制代码
<template>
  <div class="container">
    <draggable v-model="listA" group="shared">
      <div v-for="item in listA" :key="item.id">{{ item.name }}</div>
    </draggable>
    <draggable v-model="listB" group="shared">
      <div v-for="item in listB" :key="item.id">{{ item.name }}</div>
    </draggable>
  </div>
</template>
<script>
export default {
  data() {
    return {
      listA: [{ id: 1, name: 'A1' }],
      listB: [{ id: 2, name: 'B1' }]
    };
  }
};
</script>
<style>
.container { display: flex; justify-content: space-around; }
</style>

核心参数配置

常用参数

|------------|---------------|----------------|-------------------------------------------------------|
| 参数名 | 类型 | 默认值 | 说明 |
| v-model | Array | - | 绑定数据源,拖拽后自动更新 |
| group | String/Object | - | 跨列表拖拽组名,如{ name: 'shared', pull: 'clone', put: false} |
| animation | Number | 0 | 拖拽动画时长(毫秒) |
| ghostClass | String | sortable-ghost | 拖拽占位元素样式类 |
| sort | Blooean | false | 是否允许排序 |
| disabled | Blooean | fasle | 是否禁用拖拽功能 |
| handle | | | 指定拖动手柄的CSS选择器,只有点击该元素才能拖动列表项 |
| filter | | | 指定不允许拖动的元素CSS选择器 |

事件系统

|-------|-------------------------|------------|
| 事件名 | 回调参数 | 说明 |
| start | {to,from,item,oldIndex} | 拖拽开始时触发 |
| end | {to,from,newIndex} | 拖拽结束时触发 |
| add | {to,item,newIndex} | 元素添加到列表时触发 |

3.条件拖拽

javascript 复制代码
<template>
  <draggable v-model="list" :move="checkMove">
    <div v-for="item in list" :key="item.id">{{ item.name }}</div>
  </draggable>
</template>
<script>
export default {
  data() {
    return {
      list: [
        { id: 1, name: 'Allowed', allowed: true },
        { id: 2, name: 'Blocked', allowed: false }
      ]
    };
  },
  methods: {
    checkMove(evt) {
      return evt.draggedContext.element.allowed;
    }
  }
};
</script>

4.嵌套拖拽

javascript 复制代码
<template>
  <draggable v-model="treeData" group="tree">
    <div v-for="node in treeData" :key="node.id">
      {{ node.name }}
      <draggable v-if="node.children" v-model="node.children" group="tree">
        <div v-for="child in node.children" :key="child.id">{{ child.name }}</div>
      </draggable>
    </div>
  </draggable>
</template>
<script>
export default {
  data() {
    return {
      treeData: [
        {
          id: 1,
          name: 'Parent',
          children: [
            { id: 2, name: 'Child 1' },
            { id: 3, name: 'Child 2' }
          ]
        }
      ]
    };
  }
};
</script>

注意事项

1.唯一key:确保列表使用唯一标识作为key,避免索引作为key导致的渲染问题

2.性能优化:大数据列表禁用动画(no-transition-on-drag)或使用virtual-scroll

3.样式冲突:若自定义样式不生效,使用::v-deep穿透作用域CSS

相关推荐
用户033307413952 小时前
TypeScript using 与 AsyncDisposableStack:在真实服务端代码中协调多资源清理
前端
web3d5202 小时前
Vue3 地图白屏排查清单:容器、弹窗与 ol-viewport 重复创建
vue.js·gis
daisychey2 小时前
用 Playwright 做多平台内容分发,我踩过的 8 个坑
前端
IT_陈寒3 小时前
为什么你应该学习JavaScript?
前端·人工智能·后端
大龄秃头程序员3 小时前
iOS冷启动监控Demo
前端
光影少年3 小时前
为什么 JavaScript 中 0.1 + 0.2 !== 0.3,如何让其相等?
前端·javascript·算法
掘金酱4 小时前
[稀土掘金 × 火山引擎] AI用量周榜冲刺赛|获奖名单公示
前端·人工智能·后端
泡泡oO4 小时前
“如果你还在用Superpowers,那我不要和你说话”
前端·后端·全栈
维克兜率天4 小时前
趋势过滤:避免被“假突破“反复打脸
前端
8年区块链老兵4 小时前
一篇文章教会你:用区块高度读懂比特币链上的每一笔交易
前端