知海

过渡动画

vue-draggable-plus指南-教程

过渡动画

在拖拽排序场景中,为元素添加过渡动画可以让列表的移动更加平滑,提升交互体验。vue-draggable-plus 支持使用 Vue 内置的 transition 组件来实现过渡效果,并同时覆盖了组件、函数和指令三种使用方式。

组件使用

在组件方式中,将需要过渡动画的内容包裹在 transition 组件内,即可在拖拽过程中自动应用动画。该示例同时展示了列表超出容器时可以滚动拖拽。

vue 复制代码
<template>
  <button @click="handleAdd">Add</button>

  <div class="flex justify-between">
    <VueDraggable
      v-model="list"
      class="flex flex-col gap-2 w-300px bg-gray-500/5 rounded"
      target=".sort-target"
      :scroll="true"
    >
      <TransitionGroup
        type="transition"
        tag="ul"
        name="fade"
        class="sort-target"
      >
        <li
          v-for="(item, index) in list"
          :key="item.id"
          class="h-50px bg-gray-500/5 rounded flex items-center justify-between px-2"
        >
          <IconSort class="handle cursor-move"></IconSort>
          <input type="text" v-model="item.name" />
          <iconClose class="cursor-pointer" @click="remove(index)"></iconClose>
        </li>
      </TransitionGroup>
    </VueDraggable>
    <preview-list :list="list" />
  </div>
</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'
  }
])

function handleAdd() {
  const length = list.value.length + 1
  list.value.push({
    name: `Juan ${length}`,
    id: `${length}`
  })
}

function remove(index: number) {
  list.value.splice(index, 1)
}
</script>

<style>
.fade-move,
.fade-enter-active,
.fade-leave-active {
  transition: all 0.5s cubic-bezier(0.55, 0, 0.1, 1);
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
  transform: scaleY(0.01) translate(30px, 0);
}

.fade-leave-active {
  position: absolute;
}
.sort-target {
  padding: 0 1rem;
}
</style>

函数使用

使用函数方式创建拖拽时,同样可以结合 transition 组件为元素添加过渡动画,具体用法如下方示例所示。

vue 复制代码
<template>
  <button @click="handleAdd">Add</button>

  <div class="flex justify-between">
    <TransitionGroup
      ref="el"
      type="transition"
      tag="ul"
      name="fade"
      class="flex flex-col p-4 w-300px bg-gray-500/5 rounded"
    >
      <li
        v-for="(item, index) in list"
        :key="item.id"
        class="h-50px bg-gray-500/5 rounded flex items-center justify-between px-2 m-0"
      >
        <IconSort class="handle cursor-move"></IconSort>
        <input type="text" v-model="item.name" />
        <iconClose class="cursor-pointer" @click="remove(index)"></iconClose>
      </li>
    </TransitionGroup>
    <preview-list :list="list" />
  </div>
</template>

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

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

const el = ref()

useDraggable(el, list)

function handleAdd() {
  const length = list.value.length + 1
  list.value.push({
    name: `Juan ${length}`,
    id: `${length}`
  })
}

function remove(index: number) {
  list.value.splice(index, 1)
}
</script>

<style>
.fade-move,
.fade-enter-active,
.fade-leave-active {
  transition: all 0.5s cubic-bezier(0.55, 0, 0.1, 1);
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
  transform: scaleY(0.01) translate(30px, 0);
}

.fade-leave-active {
  position: absolute;
}
</style>

指令使用

指令方式下,通过 v-draggable 配合 transition 组件,也能轻松实现带有过渡动画的拖拽效果。

vue 复制代码
<template>
  <button @click="handleAdd">Add</button>

  <div class="flex justify-between">
    <TransitionGroup
      v-draggable="[list, { animation: 150 }]"
      type="transition"
      tag="ul"
      name="fade"
      class="flex flex-col p-4 w-300px bg-gray-500/5 rounded"
    >
      <li
        v-for="(item, index) in list"
        :key="item.id"
        class="h-50px bg-gray-500/5 rounded flex items-center justify-between px-2"
      >
        <IconSort class="handle cursor-move"></IconSort>
        <input type="text" v-model="item.name" />
        <iconClose class="cursor-pointer" @click="remove(index)"></iconClose>
      </li>
    </TransitionGroup>
    <preview-list :list="list" />
  </div>
</template>

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

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

function handleAdd() {
  const length = list.value.length + 1
  list.value.push({
    name: `Juan ${length}`,
    id: `${length}`
  })
}

function remove(index: number) {
  list.value.splice(index, 1)
}
</script>

<style>
.fade-move,
.fade-enter-active,
.fade-leave-active {
  transition: all 0.5s cubic-bezier(0.55, 0, 0.1, 1);
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
  transform: scaleY(0.01) translate(30px, 0);
}

.fade-leave-active {
  position: absolute;
}
</style>

帮助我们改进文档

发现翻译问题或内容错误?请告诉我们。