当前位置:首页 > VUE

vue实现拆分拖拽

2026-02-17 16:41:21VUE

Vue 实现拆分拖拽功能

拆分拖拽通常指将界面元素拆分为多个可拖拽的组件,并允许用户自由组合。以下是基于 Vue 的实现方法:

使用 Vue.Draggable 库

安装依赖:

npm install vuedraggable

基础示例代码:

<template>
  <div>
    <draggable v-model="list" group="components" @end="onDragEnd">
      <div v-for="element in list" :key="element.id">
        {{ element.name }}
      </div>
    </draggable>
  </div>
</template>

<script>
import draggable from 'vuedraggable'
export default {
  components: { draggable },
  data() {
    return {
      list: [
        { id: 1, name: '组件A' },
        { id: 2, name: '组件B' }
      ]
    }
  },
  methods: {
    onDragEnd() {
      console.log('拖拽完成')
    }
  }
}
</script>

实现多区域拖拽

创建多个拖拽区域并允许元素在区域间移动:

<template>
  <div class="container">
    <div class="area">
      <h3>区域1</h3>
      <draggable v-model="area1" group="components">
        <div v-for="item in area1" :key="item.id">
          {{ item.name }}
        </div>
      </draggable>
    </div>

    <div class="area">
      <h3>区域2</h3>
      <draggable v-model="area2" group="components">
        <div v-for="item in area2" :key="item.id">
          {{ item.name }}
        </div>
      </draggable>
    </div>
  </div>
</template>

<script>
import draggable from 'vuedraggable'
export default {
  components: { draggable },
  data() {
    return {
      area1: [
        { id: 1, name: '组件A' },
        { id: 2, name: '组件B' }
      ],
      area2: [
        { id: 3, name: '组件C' }
      ]
    }
  }
}
</script>

<style>
.container {
  display: flex;
}
.area {
  width: 200px;
  margin: 10px;
  padding: 10px;
  border: 1px solid #ddd;
}
</style>

自定义拖拽手柄

添加拖拽手柄而非整个元素可拖拽:

<template>
  <draggable v-model="list" handle=".handle">
    <div v-for="item in list" :key="item.id">
      <span class="handle">≡</span>
      {{ item.name }}
    </div>
  </draggable>
</template>

<script>
import draggable from 'vuedraggable'
export default {
  components: { draggable },
  data() {
    return {
      list: [
        { id: 1, name: '组件A' },
        { id: 2, name: '组件B' }
      ]
    }
  }
}
</script>

<style>
.handle {
  cursor: move;
  margin-right: 10px;
}
</style>

实现嵌套拖拽

支持嵌套结构的拖拽功能:

<template>
  <draggable 
    v-model="treeData" 
    group="nested" 
    @change="log"
    item-key="id">
    <template #item="{element}">
      <div>
        {{ element.name }}
        <nested-draggable 
          v-if="element.children"
          :items="element.children" />
      </div>
    </template>
  </draggable>
</template>

<script>
import draggable from 'vuedraggable'
export default {
  components: {
    draggable,
    'nested-draggable': {
      template: `
        <draggable 
          v-model="internalItems" 
          group="nested" 
          item-key="id">
          <template #item="{element}">
            <div style="margin-left:20px">
              {{ element.name }}
              <nested-draggable 
                v-if="element.children"
                :items="element.children" />
            </div>
          </template>
        </draggable>`,
      components: { draggable },
      props: ['items'],
      computed: {
        internalItems: {
          get() { return this.items },
          set(value) { this.$emit('update:items', value) }
        }
      }
    }
  },
  data() {
    return {
      treeData: [
        {
          id: 1,
          name: '父节点',
          children: [
            { id: 2, name: '子节点1' },
            { id: 3, name: '子节点2' }
          ]
        }
      ]
    }
  },
  methods: {
    log(evt) {
      console.log(evt)
    }
  }
}
</script>

实现拖拽排序与克隆

允许元素克隆而非移动:

vue实现拆分拖拽

<template>
  <div>
    <h3>源列表</h3>
    <draggable 
      v-model="source" 
      :group="{ name: 'components', pull: 'clone', put: false }"
      item-key="id">
      <div v-for="item in source" :key="item.id">
        {{ item.name }}
      </div>
    </draggable>

    <h3>目标列表</h3>
    <draggable 
      v-model="target" 
      group="components"
      item-key="id">
      <div v-for="item in target" :key="item.id">
        {{ item.name }}
      </div>
    </draggable>
  </div>
</template>

<script>
import draggable from 'vuedraggable'
export default {
  components: { draggable },
  data() {
    return {
      source: [
        { id: 1, name: '组件A' },
        { id: 2, name: '组件B' }
      ],
      target: []
    }
  }
}
</script>

注意事项

  1. 确保为每个拖拽元素设置唯一的key值
  2. 复杂场景建议使用Vuex管理状态
  3. 移动端需要额外处理touch事件
  4. 性能优化:大数据量使用虚拟滚动

以上方法可根据实际需求组合使用,实现各种复杂的拆分拖拽场景。

标签: 拖拽vue
分享给朋友:

相关文章

vue实现检测数组

vue实现检测数组

Vue 中检测数组变化的方法 Vue 的响应式系统无法直接检测到数组的某些变化,因为 JavaScript 的限制。以下是一些解决方案: 使用 Vue.set 或 this.$set Vue 提供…

vue实现建模

vue实现建模

Vue 实现建模的方法 在 Vue 中实现建模通常涉及数据绑定、组件化和状态管理。以下是几种常见的方法: 数据驱动建模 Vue 的核心是数据驱动视图。通过定义数据模型,Vue 会自动更新 DOM。例…

vue cli 实现

vue cli 实现

Vue CLI 实现步骤 安装 Vue CLI 确保 Node.js 版本在 8.9 或以上。通过 npm 全局安装 Vue CLI: npm install -g @vue/cli 创建新项目 使…

vue实现甘特图

vue实现甘特图

使用 Vue 实现甘特图 基于开源库(如 vue-ganttastic) 安装依赖库: npm install vue-ganttastic 示例代码: <template> &l…

vue实现按钮

vue实现按钮

Vue 实现按钮的方法 使用原生 HTML 按钮 在 Vue 模板中可以直接使用 HTML 的 <button> 元素,通过 v-on 或 @ 绑定点击事件。 <template&…

vue实现popover

vue实现popover

Vue 实现 Popover 的方法 使用第三方库(如 Element UI、Ant Design Vue) 许多成熟的 UI 库已经内置了 Popover 组件,可以直接调用。 Element U…