vue中的transition学习
文章讲解不清楚的地方请直接查看官方文档
transition组件思维导图
个人做复习使用 如有错误请指正

Vue 提供了两个内置组件 transition和transitionGroup
transition
会在一个元素或组件进入和离开 DOM 时应用动画。他可以将进入和离开的动画应用通过默认插槽传递给它的元素或者组件上
注意:该组件仅支持单个元素或者单个组件作为插槽的内容,单个组件中也应该只有一个根元素
transitionGroup
会在一个 v-for 列表中的元素或组件被插入,移动,或移除时应用动画
组件
进入或者离开可以由以下条件触发
- v-if
- v-show
- 可以切换的
组件
当一个组件中的元素被插入或移除时,会发生下面这些事情:
-
Vue 会自动检测目标元素是否应用了 CSS 过渡或动画。如果是,则一些 CSS 过渡 class 会在适当的时机被添加和移除。
-
如果有作为监听器的 JavaScript 钩子,这些钩子函数会在适当时机被调用。
-
如果没有探测到 CSS 过渡或动画、也没有提供 JavaScript 钩子,那么 DOM 的插入、删除操作将在浏览器的下一个动画帧后执行。

v-enter-active 和 v-leave-active 给我们提供了为进入和离开动画指定不同速度曲线的能力
v-enter-from 和v-leave-to会作为一对来使用指定opacity:0
为过渡效果命名
<Transition name="fade">...
</Transition>
.fade-enter-active,
.fade-leave-active {transition: opacity 0.5s ease;
}.fade-enter-from,
.fade-leave-to {opacity: 0;
}
CSS的animation
原生的CSS动画和css transition区别是
*-enter-from不是在dom插入后移除,而是在animationend方法触发后移除
对于大多数的 CSS 动画,我们可以简单地在 *-enter-active 和 *-leave-active class 下声明它们
<Transition name="bounce"><p v-if="show" style="text-align: center;">Hello here is some bouncy text!</p>
</Transition>
.bounce-enter-active {animation: bounce-in 0.5s;
}
.bounce-leave-active {animation: bounce-in 0.5s reverse;
}
@keyframes bounce-in {0% {transform: scale(0);}50% {transform: scale(1.25);}100% {transform: scale(1);}
}
自定义过渡 class
- enter-from-class
- enter-active-class
- enter-to-class
- leave-from-class
- leave-active-class
- leave-to-class
传入的class会默认覆盖阶段的class类名,这种在使用第三方库Animation.css的时候很有用
<!-- 假设你已经在页面中引入了 Animate.css -->
<Transitionname="custom-classes"enter-active-class="animate__animated animate__tada"leave-active-class="animate__animated animate__bounceOutRight"
><p v-if="show">hello</p>
</Transition>
同时使用 transition 和 animation
Vue 需要附加事件监听器,以便知道过渡何时结束。可以是 transitionend 或 animationend,这取决于你所应用的 CSS 规则。如果你仅仅使用二者的其中之一,Vue 可以自动探测到正确的类型。
如果Vue 触发了一个 CSS 动画,同时鼠标悬停触发另一个 CSS 过渡。此时你需要显式地传入 type prop 来声明,告诉 Vue 需要关心哪种类型,传入的值是 animation 或 transition:
<Transition type="animation">...</Transition>
深层级过渡与显式过渡时长
默认情况下,
在这种情况下,你可以通过向
<Transition :duration="550">...</Transition>
例如
官方示例
性能考量
(这里让我想到了重排和重绘)
以下是自己理解 可以查看官方解释
1、opacity和transform动画不会引起DOM结构的变动
2、现在浏览器transform动画大多数是用GPU硬件加速
3、但是例如height和margin属性会引起CSS布局变动,因此执行他们的动画效果会更加昂贵所以要谨慎使用
查询哪些动画会触发CSS布局变动: CSS-Triggers
JS钩子
<Transition@before-enter="onBeforeEnter"@enter="onEnter"@after-enter="onAfterEnter"@enter-cancelled="onEnterCancelled"@before-leave="onBeforeLeave"@leave="onLeave"@after-leave="onAfterLeave"@leave-cancelled="onLeaveCancelled"
><!-- ... -->
</Transition>
export default {// ...methods: {// 在元素被插入到 DOM 之前被调用// 用这个来设置元素的 "enter-from" 状态onBeforeEnter(el) {},// 在元素被插入到 DOM 之后的下一帧被调用// 用这个来开始进入动画onEnter(el, done) {// 调用回调函数 done 表示过渡结束// 如果与 CSS 结合使用,则这个回调是可选参数done()},// 当进入过渡完成时调用。onAfterEnter(el) {},onEnterCancelled(el) {},// 在 leave 钩子之前调用// 大多数时候,你应该只会用到 leave 钩子onBeforeLeave(el) {},// 在离开过渡开始时调用// 用这个来开始离开动画onLeave(el, done) {// 调用回调函数 done 表示过渡结束// 如果与 CSS 结合使用,则这个回调是可选参数done()},// 在离开过渡完成、// 且元素已从 DOM 中移除时调用onAfterLeave(el) {},// 仅在 v-show 过渡中可用onLeaveCancelled(el) {}}
}
| 钩子函数名称 | 调用时机 |
|---|---|
| before-enter | 元素被插入DOM之前调用 |
| enter | 插入DOM之后调用在浏览器下一个动画帧执行 |
| after-enter,cancel-enter | 动画进入过渡完成执行 |
| before-leave | |
| leave | 在动画离开过渡开始时调用 |
| after-leave | 在动画离开过渡完成时调用 |
| cancel-leave | 只有在v-show的时候使用 |
这些钩子可以与 CSS 过渡或动画结合使用,也可以单独使用。
在使用仅由 JavaScript 执行的动画时,最好是添加一个 :css=“false” prop。这显式地向 Vue 表明可以跳过对 CSS 过渡的自动探测。除了性能稍好一些之外,还可以防止 CSS 规则意外地干扰过渡效果。
这里官网也给我们建议了几个动画库
GreenSock 库 Anime.js Motion One
官网用 GreenSock示例
官网示例
可复用动画效果
使用插槽
<!-- MyTransition.vue -->
<script>
// JavaScript 钩子逻辑...
</script><template><!-- 包装内置的 Transition 组件 --><Transitionname="my-transition"@enter="onEnter"@leave="onLeave"><slot></slot> <!-- 向内传递插槽内容 --></Transition>
</template><style>
/*必要的 CSS...注意:避免在这里使用