实现一个拖拽排序组件:Vue 3 + TypeScript + Tailwind CSS

发布于:2025-04-10 ⋅ 阅读:(40) ⋅ 点赞:(0)

一、项目背景与需求分析

在很多现代的应用中,拖拽排序功能已经成为常见的交互需求。通过拖拽排序,我们可以方便地对列表进行重排,常见于任务管理、文件管理等应用。本文将介绍如何使用 Vue 3 和 TypeScript,结合 Tailwind CSS 构建一个拖拽排序组件。

需求:

  1. 支持对列表中的项进行拖拽排序。
  2. 拖拽结束后,能够更新列表的顺序。
  3. 使用 TypeScript 提供类型安全,使用 Tailwind CSS 实现简洁的样式。

二、搭建基础项目

1. 初始化 Vue 3 项目

首先,使用 Vue CLI 或 Vite 创建一个 Vue 3 项目。如果使用 Vite,可以执行以下命令:

npm create vite@latest drag-sort-app --template vue-ts
cd drag-sort-app
npm install

2. 安装 Tailwind CSS

接着,我们安装 Tailwind CSS,以便在样式部分使用其简洁的类名:

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init

tailwind.config.js 中配置 Tailwind:

module.exports = {
  content: [
    "./index.html",
    "./src/**/*.{vue,js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

然后,在 src/assets/tailwind.css 中添加以下内容:

@tailwind base;
@tailwind components;
@tailwind utilities;

确保在 main.ts 中引入 Tailwind CSS 文件:

import './assets/tailwind.css';

三、设计拖拽排序组件

1. 创建拖拽排序组件

src/components 目录下创建一个 DragSort.vue 组件。这个组件将包含可拖拽的列表项,并通过拖拽操作更新顺序。

<template>
  <div class="container mx-auto p-4">
    <div
      class="bg-white p-4 shadow-md rounded-lg"
      v-for="(item, index) in items"
      :key="item.id"
      class="my-2 p-4 border border-gray-200 rounded-md cursor-pointer"
      :draggable="true"
      @dragstart="handleDragStart($event, index)"
      @dragover="handleDragOver($event)"
      @drop="handleDrop($event, index)"
    >
      {{ item.name }}
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue';

interface Item {
  id: number;
  name: string;
}

export default defineComponent({
  name: 'DragSort',
  setup() {
    const items = ref<Item[]>([
      { id: 1, name: 'Item 1' },
      { id: 2, name: 'Item 2' },
      { id: 3, name: 'Item 3' },
      { id: 4, name: 'Item 4' },
      { id: 5, name: 'Item 5' },
    ]);

    let draggedIndex: number | null = null;

    const handleDragStart = (event: DragEvent, index: number) => {
      draggedIndex = index;
    };

    const handleDragOver = (event: DragEvent) => {
      event.preventDefault();
    };

    const handleDrop = (event: DragEvent, targetIndex: number) => {
      if (draggedIndex === null) return;
      const draggedItem = items.value[draggedIndex];
      items.value.splice(draggedIndex, 1);
      items.value.splice(targetIndex, 0, draggedItem);
      draggedIndex = null;
    };

    return {
      items,
      handleDragStart,
      handleDragOver,
      handleDrop,
    };
  },
});
</script>

<style scoped>
.container {
  max-width: 600px;
}
</style>

2. 说明:

  • draggable 属性使得每个列表项都能被拖拽。
  • @dragstart 事件在拖拽开始时触发,记录当前被拖拽的项的索引。
  • @dragover 事件用于允许拖拽元素与目标元素交互,必须调用 event.preventDefault() 来阻止默认行为。
  • @drop 事件在放下拖拽元素时触发,将拖拽项插入目标位置。

四、完善样式与功能

1. 样式调整

通过 Tailwind CSS 来简化样式设计。我们为每个可拖拽的列表项添加了基础的边框、阴影以及圆角效果。

  • cursor-pointer:鼠标指针样式变为可点击状态。
  • my-2 p-4 border border-gray-200 rounded-md:添加一些间距、边框和圆角效果。

2. 拖拽顺序更新

拖拽排序功能的核心逻辑是在 handleDrop 方法中。通过 splice 方法更新 items 数组的顺序,确保顺序实时更新。

五、进一步优化与拓展

1. 添加排序指示器

可以在拖拽过程中添加一个排序指示器,提示用户拖拽项的位置。通过 @dragenter@dragleave 事件来处理指示器的显示与隐藏。

2. 支持动态数据

该组件目前是基于静态数据实现的,如果需要支持动态数据,可以将数据从父组件传递给 DragSort,并通过 props 和事件来实现数据的更新。


到这里,这篇文章就和大家说再见啦!我的主页里还藏着很多 篇 前端 实战干货,感兴趣的话可以点击头像看看,说不定能找到你需要的解决方案~
创作这篇内容花了很多的功夫。如果它帮你解决了问题,或者带来了启发,欢迎:
点个赞❤️ 让更多人看到优质内容
关注「前端极客探险家」🚀 每周解锁新技巧
收藏文章⭐️ 方便随时查阅
📢 特别提醒:
转载请注明原文链接,商业合作请私信联系
感谢你的阅读!我们下篇文章再见~ 💕

在这里插入图片描述