vue3学习记录-TransitionGroup

vue3学习记录-TransitionGroup

  • 1.概念
  • 2.基本使用
    • [2.1 进入 / 离开动画](#2.1 进入 / 离开动画)
    • [2.2 移动动画](#2.2 移动动画)
    • [2.3 和第三方库搭配](#2.3 和第三方库搭配)
    • [2.4 appear 高级的自动加载动画](#2.4 appear 高级的自动加载动画)

1.概念

TransitionGroup 是一个内置组件,用于对 v-for 列表中的元素或组件的插入、移除和顺序改变添加动画效果。

和 Transition的区别:

默认情况下,它不会渲染一个容器元素。但你可以通过传入 tag prop 来指定一个元素作为容器元素来渲染。

过渡模式在这里不可用,因为我们不再是在互斥的元素之间进行切换。

列表中的每个元素都必须有一个独一无二的 key attribute。

CSS 过渡 class 会被应用在列表内的元素上,而不是容器元素上。

TransitionGroup 比Transition多了两个prop,一个是tag,如果如果未定义,则渲染为片段 (fragment),如果定义了,例如tag="div",v-for的上一层,TransitionGroup 会被渲染成div。另一个prop是moveClass,用于自定义过渡期间被应用的 CSS class。,在模板中使用 kebab-case,例如 move-class="xxx"。

2.基本使用

2.1 进入 / 离开动画

javascript 复制代码
<script setup>

import { ref } from 'vue';
const list = ref([1, 2, 3, 4, 5])

const add = () => {
  list.value.push(Math.floor(Math.random() * 10) + 1);
}

const remove = () => {
  list.value.pop();
}
</script>

<template>
  <el-button @click="add">add</el-button>
  <el-button @click="remove">remove</el-button>
  <transition-group tag="div" class="list">
    <div v-for="item in list" class="item" :key="item">{{ item }}</div>
  </transition-group>
</template>

<style scoped>
.list {
  display: flex;
  width: 30px;
  flex-wrap: wrap;

  .item {
    width: 20px;
    margin: 5px;
    height: 20px;
    text-align: center;
  }
}

.list-enter-active,
.list-leave-active {
  transition: all 0.5s ease;
}
.list-enter-from,
.list-leave-to {
  opacity: 0;
  transform: translateX(30px);
}

.v-enter-active,
.v-leave-active {
  transition: all 0.5s ease;
}
.v-enter-from,
.v-leave-to {
  opacity: 0;
  transform: translateX(30px);
}
</style>

默认情况下, 不会渲染一个容器 DOM 元素,但是可以通过 tag prop 启用。

注意,每个 transition-group 的子节点必须有独立的 key,动画才能正常工作。

支持通过 CSS transform 控制移动效果。当一个子节点在屏幕上的位置在更新之后发生变化时,它会被添加一个使其位移的 CSS class (基于 name attribute 推导,或使用 move-class prop 显式配置)。如果使其位移的 class 被添加时 CSS 的 transform 属性是"可过渡的",那么该元素会基于 FLIP 技巧平滑地到达动画终点。

如果两个都没定义的话,就是默认的例子中的.v-enter-active,.v-leave-active,.v-enter-from,.v-leave-to CSSclasss。

2.2 移动动画

上面的会有个问题,发现在随机移动的时候没有动画。

我们可以通过添加一些额外的 CSS 规则来解决这个问题:

javascript 复制代码
.list-move, /* 对移动中的元素应用的过渡 */
.list-enter-active,
.list-leave-active {
  transition: all 0.5s ease;
}

.list-enter-from,
.list-leave-to {
  opacity: 0;
  transform: translateX(30px);
}

/* 确保将离开的元素从布局流中删除
  以便能够正确地计算移动的动画。 */
.list-leave-active {
  position: absolute;
}

效果:

2.3 和第三方库搭配

javascript 复制代码
<script setup>
import gsap from 'gsap';
import { ref,reactive,watch } from 'vue';
const num = reactive({
  current: 1,
  show: 1
})
 watch(() => num.current, (val) => {
  gsap.to(
    num,
    {
      duration: 1,
      show:val
    }
  )
})

</script>

<template>
  <el-input-number
    v-model="num.current"
    :min="1"
    controls-position="right"
    :step="20"
  />
  <p>{{ num.show.toFixed(0) }}</p>
</template>

效果:

transition的appear和js钩子也都适用transition-group的

2.4 appear 高级的自动加载动画

一直在想用appear属性能实现高级的自动加载动画吗

javascript 复制代码
<script setup>
import { ref, onMounted } from 'vue';
import gsap from 'gsap';

// 模拟数据列表
const items = ref([
  { id: 1, title: 'Item 1' },
  { id: 2, title: 'Item 2' },
  { id: 3, title: 'Item 3' },
  { id: 4, title: 'Item 4' },
  { id: 5, title: 'Item 5' },
]);

// 控制是否显示列表
const showList = ref(false);

// GSAP 动画函数
const onBeforeEnter = (el) => {
  gsap.set(el, {
    opacity: 0,
    y: 50,
    scale: 0.8,
  });
};

const onEnter = (el, done) => {
  gsap.to(el, {
    opacity: 1,
    y: 0,
    scale: 1,
    duration: 0.6,
    ease: 'back.out(1.7)',
    onComplete: done,
  });
};

const onAfterEnter = (el) => {
  gsap.to(el, {
    scale: 1.05,
    duration: 0.2,
    yoyo: true,
    repeat: 1,
  });
};

// 组件挂载后显示列表
onMounted(() => {
  setTimeout(() => {
    showList.value = true;
  }, 500); // 延迟 500ms 显示列表
});
</script>

<template>
  <div class="container">
    <transition-group appear @before-enter="onBeforeEnter" @enter="onEnter" @after-enter="onAfterEnter">
      <div v-if="showList" v-for="item in items" :key="item.id" class="item">
        {{ item.title }}
      </div>
    </transition-group>
  </div>
</template>

<style scoped>
.container {
  max-width: 600px;
  margin: 0 auto;
  padding: 20px;
}

.item {
  background-color: #f0f0f0;
  border-radius: 8px;
  padding: 15px;
  margin-bottom: 10px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
</style>

效果 :

其实好像用不用appear都能实现高级的自动加载动画

相关推荐
careybobo1 小时前
海康摄像头通过Web插件进行预览播放和控制
前端
杉之2 小时前
常见前端GET请求以及对应的Spring后端接收接口写法
java·前端·后端·spring·vue
喝拿铁写前端2 小时前
字段聚类,到底有什么用?——从系统混乱到结构认知的第一步
前端
再学一点就睡3 小时前
大文件上传之切片上传以及开发全流程之前端篇
前端·javascript
木木黄木木4 小时前
html5炫酷图片悬停效果实现详解
前端·html·html5
zhuyixiangyyds4 小时前
day21和day22学习Pandas库
笔记·学习·pandas
每次的天空4 小时前
Android学习总结之算法篇四(字符串)
android·学习·算法
请来次降维打击!!!4 小时前
优选算法系列(5.位运算)
java·前端·c++·算法
難釋懷5 小时前
JavaScript基础-移动端常见特效
开发语言·前端·javascript
背影疾风5 小时前
C++学习之路:指针基础
c++·学习