vue-draggable-plus与arco design结合

74 阅读1分钟

vue-draggable-plus是在SortableJS基础之上,与Vue3结合实现螺柱爱列表的方案。与SortableJS相比,可以指定元素选择器,选择拖拽的根元素,方便与各类框架结合
与列表页结合是其基本功能,不在赘述,这里主要介绍vue-draggable-plus与arco design的a-tabs组件结合,实现Tab页的拖拽。

<template>
  <VueDraggable
    v-model="tabs"
    target=".tabs .arco-tabs-nav-tab-list"
    :animation="150"
    filter=".no-drag"
    direction="horizontal"
    @start="onStart"
    @end="onEnd"
    >
    <a-tabs
      v-model:active-key="activeKey"
      class=".tabs"
      type="card-gutter"
      >
      <a-tab-pane
        v-for="t of tabs"
        :key="t.key"
        :title="t.title"
      >
        <span>{{t.value}}</span>
      </a-tab-pane>    
    </a-tabs>
  </VueDraggable>  
</template>

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

  // 拖拽开始
let selectedTab // 选择的tab的数据
const onStart = (event: SortableEvent) => {
  const { oldIndex } = event
  selectedTab = tabs.value.find((item, index) => index === oldIndex)
  // 拖拽时,去掉arco design的tab hover默认效果
  Array.from(event.target.children).forEach((child: Element) => {
    child.classList.add('no-hover')
  })
  event.target.addEventListener('mouseenter', (e) => e.stopImmediatePropagation())
  event.target.addEventListener('mouseleave', (e) => e.stopImmediatePropagation())
}
// 拖拽结束
const onEnd = async (event: SortableEvent) => {
  const { newIndex } = event
  if (selectedTab && newIndex) {
    const params: SortCategory = {
      id: selectedTab.id,
      sort: newIndex
    }
    await sortTabs(params)
    getTabs() // 刷新分类
    // 拖拽时,去掉arco design的tab hover默认效果
    Array.from(event.target.children).forEach((child: Element) => {
      child.classList.remove('no-hover')
    })
    event.target.addEventListener('mouseenter', (e) => e.stopImmediatePropagation())
    event.target.addEventListener('mouseleave', (e) => e.stopImmediatePropagation())
  }
}
</script>

<style>
  :deep(.arco-tabs-nav-type-card-gutter .no-hover.arco-tabs-tab:hover) {
  /* 取消 hover 效果 */
  background-color: #fafafa;
  /* 恢复为默认背景色 */
  pointer-events: none;
}
</style>