使用 VueDraggable 创建可拖拽列表的全面指南

在现代Web应用程序中,拖拽功能不仅增加了用户体验的互动性,还可以使页面元素的重新排序变得更加直观和有效。Vue.js 生态系统中的 vuedraggable 组件提供了一种简单而强大的方法来实现这一功能,结合了 Vue.js 和 Sortable.js 的优势,使得创建拖拽功能变得异常容易。本文将介绍如何使用 vuedraggable 实现单列拖拽、多列拖拽、表格拖拽,并解决拖入空数组时可能遇到的问题。

1. 安装和基本用法

首先,确保你的项目已经安装了 Vue.js 和 npm 包管理器。然后,安装 vuedraggable

npm install vuedraggable

2. 单列拖拽示例

单列拖拽适用于简单的列表,比如一个垂直排列的项目列表。以下是一个基本的示例:

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

<script>
import draggable from 'vuedraggable';

export default {
  components: {
    draggable,
  },
  data() {
    return {
      list: [
        { id: 1, name: 'Item 1' },
        { id: 2, name: 'Item 2' },
        { id: 3, name: 'Item 3' },
        // Add more items as needed
      ],
    };
  },
};
</script>

<style>
.drag-container {
  display: flex;
  flex-direction: column;
  margin: 10px 0;
}
</style>

在上面的例子中,draggable 组件被用来包裹一个由 v-for 渲染出的项目列表。用户可以通过拖拽重新排列 list 数组中的项目,而 v-model="list" 实现了列表数据的双向绑定,保持了数据的同步更新。

3. 多列拖拽示例

多列拖拽界面,其中有多个列,每列包含不同的项目。下面是一个简单的多列拖拽示例:

<template>
  <!--使用draggable组件-->
  <div class="itxst">
    <div class="col">
      <div class="title">把下面元素拖拽到B组试试看</div>
      <draggable
        v-model="arr1"
        group="site"
        animation="300"
        dragClass="dragClass"
        ghostClass="ghostClass"
        chosenClass="chosenClass"
        @start="onStart"
        @end="onEnd"
      >
        <transition-group :style="style">
          <div class="item" v-for="item in arr1" :key="item.id">
            {{ item.name }}
          </div>
        </transition-group>
      </draggable>
    </div>
    <div class="col">
      <div class="title">B组(本组是个空数组)</div>
      <draggable
        v-model="arr2"
        group="site"
        animation="100"
        dragClass="dragClass"
        ghostClass="ghostClass"
        chosenClass="chosenClass"
        @start="onStart"
        @end="onEnd"
      >
        <transition-group :style="style">
          <div class="item" v-for="item in arr2" :key="item.id">
            {{ item.name }}
          </div>
        </transition-group>
      </draggable>
    </div>
  </div>
</template>

<script>
import draggable from "vuedraggable";

export default {
  components: {
    draggable,
  },
  data() {
    return {
      drag: false,
      arr1: [
        { id: 1, name: "www.itxst.com" },
        { id: 2, name: "www.jd.com" },
        { id: 3, name: "www.baidu.com" },
        { id: 4, name: "www.taobao.com" },
      ],
      arr2: [],
      //空数组之在的样式,设置了这个样式才能拖入
      style: "min-height:120px;display: block;",
    };
  },
  methods: {
    onStart() {
      this.drag = true;
    },
    onEnd() {
      this.drag = false;
    },
  },
  watch:{
    arr1(val){
      console.log('🚀 ~ arr1 ~ val:', ...val)
    },
    arr2(val){
      console.log('🚀 ~ arr2 ~ val:', ...val)
    }
  }
};
</script>

<style>
.chosenClass {
  /* background-color: red !important; */
  opacity: 1 !important;
}

.dragClass {
  /* background-color: blueviolet !important; */
  opacity: 1 !important;
  box-shadow: none !important;
  outline: none !important;
  background-image: none !important;
}

.itxst {
  margin: 10px;
}

.title {
  padding: 6px 12px;
}

.col {
  width: 40%;
  flex: 1;
  padding: 10px;
  border: solid 1px #eee;
  border-radius: 5px;
  float: left;
}

.col + .col {
  margin-left: 10px;
}
.item {
  padding: 6px 12px;
  margin: 0px 10px 0px 10px;
  border: solid 1px #eee;
  background-color: #f1f1f1;
}

.item:hover {
  background-color: #fdfdfd;
  cursor: pointer;
}

.item + .item {
  border-top: none;
  margin-top: 6px;
}
</style>

4. 表格拖拽示例

有时候我们需要在表格中进行拖拽排序,例如调整表格中行的顺序。vuedraggable 也能很好地处理这种情况:

<template>
  <table class="table">
    <tbody>
      <draggable v-model="rows" tag="tbody">
        <tr v-for="row in rows" :key="row.id">
          <td>{{ row.id }}</td>
          <td>{{ row.name }}</td>
        </tr>
      </draggable>
    </tbody>
  </table>
</template>

<script>
import draggable from 'vuedraggable';

export default {
  components: {
    draggable,
  },
  data() {
    return {
      rows: [
        { id: 1, name: 'Row 1' },
        { id: 2, name: 'Row 2' },
        { id: 3, name: 'Row 3' },
        // Add more rows as needed
      ],
    };
  },
};
</script>

<style>
.table {
  width: 100%;
  border-collapse: collapse;
}

.table td, .table th {
  border: 1px solid #ddd;
  padding: 8px;
  text-align: left;
}

.table th {
  background-color: #f2f2f2;
}
</style>

在这个例子中,draggable 组件直接包裹了 tbody,并且使用 tag="tbody" 属性指定了要拖动的元素标签类型。这样做可以保证在表格中拖拽行时,DOM 结构保持正确。

5. 拖入空数组的问题

使用 vuedraggable 时,有时会遇到将项目拖入一个空数组的情况。默认情况下,vuedraggable 并不会自动添加项目到空数组中,这可能会导致一些预期之外的行为。解决这个问题的一个方法是,在 draggable 组件中使用 clone 属性。例如:

<draggable v-model="list" :clone="cloneItem" class="drag-container">
  <!-- List items -->
</draggable>

在 Vue 实例中,需要定义 cloneItem 方法:

methods: {
  cloneItem(item) {
    return { ...item }; // Clone the item to avoid mutating original data
  },
}

这样做可以确保当用户将项目拖入空数组时,会自动克隆原始项目,从而避免直接修改源数据,同时也保证了正常的拖拽行为。

结论

通过 vuedraggable,我们可以轻松实现单列拖拽、多列拖拽和表格拖拽等功能,大大提升了用户界面的互动性和用户体验。同时,注意处理拖入空数组的问题也是使用这个组件时需要注意的一点。希望本文能帮助你更好地理解和使用 vuedraggable 组件,为你的 Vue.js 应用程序增添更多交互功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值