指尖上的记忆指尖上的记忆
首页
  • 基础
  • Laravel框架
  • Symfony框架
  • 基础
  • Gin框架
  • 基础
  • Spring框架
  • 命令
  • Nginx
  • Ai
  • Deploy
  • Docker
  • K8s
  • Micro
  • RabbitMQ
  • Mysql
  • PostgreSsql
  • Redis
  • MongoDb
  • Html
  • Js
  • 前端
  • 后端
  • Git
  • 知识扫盲
  • Golang
🌟 gitHub
首页
  • 基础
  • Laravel框架
  • Symfony框架
  • 基础
  • Gin框架
  • 基础
  • Spring框架
  • 命令
  • Nginx
  • Ai
  • Deploy
  • Docker
  • K8s
  • Micro
  • RabbitMQ
  • Mysql
  • PostgreSsql
  • Redis
  • MongoDb
  • Html
  • Js
  • 前端
  • 后端
  • Git
  • 知识扫盲
  • Golang
🌟 gitHub

vue3之拖拽插件:

安装: npm install vue-draggable-plus
使用:
<template>
    <VueDraggable ref="el" v-model="list">
      <div v-for="item in list" :key="item.id">
        {{ item.name }}
      </div>
    </VueDraggable>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { VueDraggable } from 'vue-draggable-plus'

const list = ref([
  {
    name: 'Joao',
    id: 1
  },
  {
    name: 'Jean',
    id: 2
  },
  {
    name: 'Johanna',
    id: 3
  },
  {
    name: 'Juan',
    id: 4
  }
])
</script>

这个插件非常好用,只要包裹住目标内容,即可实现拖拽功能

排序事件:

import {
  VueDraggable,
  type DraggableEvent,
  type SortableEvent,
} from "vue-draggable-plus";

const onSort = async (event: SortableEvent) => {
  const draggableEvent = event as DraggableEvent;
  console.log("event id is:", draggableEvent.data.id);
  console.log("event sort is:", draggableEvent.newIndex);
};


<VueDraggable
            v-model="sessionList"
            class="mb-8 flex flex-col gap-xl"
            @sort="onSort"
>

vue-draggable-plus可以定义拖拽点,而不必整个页面生效:

https://vue-draggable-plus.pages.dev/demo/handle/
  
也可以做表格拖拽:
https://vue-draggable-plus.pages.dev/demo/target-container/
  
典型 issue:
https://github.com/Alfred-Skyblue/vue-draggable-plus/issues/86

如果想实现表格的部分列拖拽,而不是所有列,可以按照如下方式处理:

允许部分td 拖拽,而不必整行都拖拽
import { VueDraggable } from "vue-draggable-plus";
  
<VueDraggable
  v-model="addonsList"
  target=".handle-addons"
  filter=".unable-drag"
>
  <AppTable class="w-full">
    <thead>
      <tr class="h-12">
        <AppTableHeading
          class="w-[35rem]"
          title="Name"
        />
        <AppTableHeading
          class="w-[12.5rem]"
          title="Price (CHF)"
        />
        <AppTableHeading
          class="w-[12.5rem]"
          title="Issued"
        />
        <AppTableHeading
          class="w-[28rem]"
          title="Available to"
        />
        <AppTableHeading
          class="w-[12.5rem]"
          title="Action"
        />
      </tr>
    </thead>
    <tbody class="handle-addons text-xs">
      <tr
        v-for="addons in addonsList"
        :key="`${addons.name}_${addons.id}`"
        class="select-text"
      >
        <td>
          {{ addons.name }}
        </td>
        <td class="unable-drag">
          {{ addons.price }}
        </td>
        <td class="unable-drag">{{ addons.issued }}</td>
        <td class="unable-drag">
          {{ addons.availableTo }}
        </td>
        <td class="unable-drag">
          <EventSettingsRegistrationTicketsAction
            :id="addons.id"
            @edit="showEditAddons"
            @delete="showDeleteAddons"
          />
        </td>
      </tr>
    </tbody>
  </AppTable>
</VueDraggable>
  
主要是通过 filter 属性定义的class来排除; 同时给每个tr添加 class="select-text" , 这样可以选中td中的文字,否则选不了,但是和 filter 一起使用的时候,会发现,只有可 drag 的元素才能被选中,被过滤的还是不能被选中,非常蛋疼.
  
关于 vue-draggable-plus 插件的几个属性,可以参考,虽然不是一个包,但是都用了sortable.js:
https://github.com/SortableJS/Sortable  //这里面也有介绍
  
结论:
1>无论哪种drag插件,最后都是 sortable.js, 并且 vuedraggable@next 是 sortable.js的 vue3实现方式, 这个 vue-draggable-plus 文档说 sortable.js不支持vue3是错误的
2>select-text 属性还是没有在 不是drag 元素上实现,怎么测试都不行

原生的drag库:

https://interactjs.io/