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

文章目录

一、项目背景与需求分析

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

需求:

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

二、搭建基础项目

1. 初始化 Vue 3 项目

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

bash 复制代码
npm create vite@latest drag-sort-app --template vue-ts
cd drag-sort-app
npm install

2. 安装 Tailwind CSS

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

bash 复制代码
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init

在 tailwind.config.js 中配置 Tailwind:

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

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

css 复制代码
@tailwind base;
@tailwind components;
@tailwind utilities;

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

typescript 复制代码
import './assets/tailwind.css';

三、设计拖拽排序组件

1. 创建拖拽排序组件

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

javascript 复制代码
<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 和事件来实现数据的更新。


到这里,这篇文章就和大家说再见啦!我的主页里还藏着很多 篇 前端 实战干货,感兴趣的话可以点击头像看看,说不定能找到你需要的解决方案~

创作这篇内容花了很多的功夫。如果它帮你解决了问题,或者带来了启发,欢迎:

点个赞❤️ 让更多人看到优质内容

关注「前端极客探险家」🚀 每周解锁新技巧

收藏文章⭐️ 方便随时查阅

📢 特别提醒:

转载请注明原文链接,商业合作请私信联系

感谢你的阅读!我们下篇文章再见~ 💕

相关推荐
易朵朵12 小时前
CSS 格式化上下文
css·vue.js
雪芽蓝域zzs14 小时前
第6节:远程搜索弹窗(remote 模式),弹窗滚动加载分页
vue.js·elementui
Highcharts.js15 小时前
图表开发实战总结| 7 条“黄金法则”与“性能铁律”
前端·javascript·vue.js·编辑器·时序数据库·highcharts
zhousenshan15 小时前
TypeScript 入门到精通
typescript
花旗蜕变17 小时前
前端转 NestJS 全栈实践:从表单页面到微信业务系统
前端·typescript·nestjs
Wx-bishekaifayuan17 小时前
springboot陨石鉴收系统96265-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·python·spring·课程设计
COOLMO研究AI18 小时前
企业官网服务页的信息架构怎么设计:从用户问题到语义化 HTML
前端·css·html
FYKJ_201018 小时前
springboot家政服务平台66766-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·mysql·spark·课程设计
艺杯羹18 小时前
Anthropic突袭发布Claude Code Mods!用TypeScript编写智能体中间件:告别AI误删与失控
人工智能·typescript·系统架构
墨鱼老师19 小时前
Go+Gin+Vue 毕设项目:Gin 框架搭建后端基础接口实战
vue.js·golang·go·gin·前后端分离·计算机毕业设计·go 后端