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都能实现高级的自动加载动画

相关推荐
木亦Sam8 分钟前
响应式网页设计中媒体查询的进阶运用
前端·响应式设计
diemeng111912 分钟前
2024系统编程语言风云变幻:Rust持续领跑,Zig与Ada异军突起
开发语言·前端·后端·rust
烂蜻蜓13 分钟前
Uniapp 中布局魔法:display 属性
前端·javascript·css·vue.js·uni-app·html
视觉CG31 分钟前
【Viewer.js】vue3封装图片查看器
开发语言·javascript·vue.js
java1234_小锋43 分钟前
一周学会Flask3 Python Web开发-redirect重定向
前端·python·flask·flask3
GDAL1 小时前
UniApp SelectorQuery 讲解
vue.js
琑951 小时前
nextjs项目搭建——头部导航
开发语言·前端·javascript
Aphelios3801 小时前
Linux 下 VIM 编辑器学习记录:从基础到进阶(下)
java·linux·学习·编辑器·vim
light多学一点1 小时前
视频的分片上传
前端
Best_Me071 小时前
【CVPR2024-工业异常检测】PromptAD:与只有正常样本的少样本异常检测的学习提示
人工智能·学习·算法·计算机视觉