文章目录
- 一、Transition介绍
- 二、在什么情况会出现过渡?
- 三、默认过渡类名
- 四、自定义过渡类名
- 五、过渡模式
- 六、过渡时间
- 七、深层元素的过渡
- 八、过渡的钩子函数
- 九、封装过渡效果
- 十、transition-group使用
一、Transition介绍
Vue 提供了两个内置组件,可以帮助你制作基于状态变化的过渡和动画:
<Transition>
会在一个元素或组件进入和离开 DOM 时应用动画。<TransitionGroup>
会在一个 v-for 列表中的元素或组件被插入,移动,或移除时应用动画。
简单地说,就是当元素发生变化,比如消失、显示时,添加动画让它更自然过渡。它是vue内置组件,不需要引入注册就可以直接使用。
二、在什么情况会出现过渡?
- v-if切换
- v-show切换
- 动态组件component切换
- 改变特殊的key属性
前几个比较好理解,最后一个用到了key值变化导致元素强制更新。下面例子的key值变化,vue会认为这里产生了一个新元素,之前的会被删除,从而导致过渡。
<script setup> import { ref } from 'vue' const keyValue = ref(1) </script> <template> <button @click="() =>keyValue = Math.random()">Toggle</button> <Transition > <p :key="keyValue">hello</p> </Transition> </template> <style> .v-enter-active, .v-leave-active { transition: opacity 0.5s ease; } .v-enter-from, .v-leave-to { opacity: 0; } </style>
复制
三、默认过渡类名
如果不给命名的话,添加动画效果的默认类名前缀是v-
transition提供六个钩子函数,提供给我们在不同时机编写相应的动画效果。以下是此六个钩子函数执行时机
- v-enter:进入过渡开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
- v-enter-active:进入过渡生效时的状态。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
- v-enter-to:进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。
- v-leave: 离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除
- v-leave-active:离开过渡生效时的状态。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
- v-leave-to:离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除
四、自定义过渡类名
通过name
可以自定义<Transition>
的过渡类名。
<Transition name="a"> ... </Transition>
复制
.a-enter-active, .a-leave-active { transition: opacity 0.5s ease; } .a-enter-from, .a-leave-to { opacity: 0; }
复制
注意:里面只能有一个根组件,但使用v-if、v-else、v-else-if切换显示是可以的。
如果想对列表中的元素设置过渡,可以使用
五、过渡模式
可以设置属性mode
为out-in
或in-out
in-out
表示当前元素先进行过渡,完成之后新元素过渡进入。
通常我们更多的会使用out-in
,让当前元素先离开,然后再进行新元素的进入 。
<transition mode="out-in"> </transition>
复制
六、过渡时间
duration属性设置过渡持续的时间,单位是毫秒。
<Transition :duration="550">...</Transition>
复制
七、深层元素的过渡
可以给深层级的元素设置过渡效果。
<Transition name="fade"> <div v-if="show" class="outer"> <div class="inner"> Hello </div> </div> </Transition>
复制
/* 应用于嵌套元素的规则 */ .fade-enter-active .inner, .fade-leave-active .inner { transition: all 0.3s ease-in-out; } .fade-enter-from .inner, .fade-leave-to .inner { transform: translateX(30px); opacity: 0; }
复制
八、过渡的钩子函数
js写法很少用,不如css写法,js和css还可以结合使用,当然如果你不想结合使用,设置一下:css=“false” 即可
<template> <div> <transition :css="false" @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter" @enter-cancelled="enterCancelled" @before-leave="beforeLeave" @leave="leave" @after-leave="afterLeave" @leave-cancelled="leaveCancelled" > <p v-if="show">hello</p> </transition> <button @click="show = !show">切换</button> </div> </template> <script> export default { name: 'ItemTwo', data() { return {show:false} }, methods: { // 进入 beforeEnter(el){ //el就是标签对象,可对标签对象进行操作 }, // 当与 CSS 结合使用时 // 回调函数 done 是可选的 enter(el, done){ el.style.color="green" //done()代表着完成,不执行这个done函数,那么它就不会执行下一个afterEnter钩子函数 }, afterEnter(el) { }, //取消过渡执行这个钩子 enterCancelled(el){ }, // 离开钩子函数就不详细写了 beforeLeave(){}, leave(){}, afterLeave(){}, leaveCancelled(){} }, } </script>
复制
九、封装过渡效果
<!-- MyTransition.vue --> <script> // JavaScript 钩子逻辑... </script> <template> <!-- 包装内置的 Transition 组件 --> <Transition name="my-transition" @enter="onEnter" @leave="onLeave"> <slot></slot> <!-- 向内传递插槽内容 --> </Transition> </template> <style> </style>
复制
注意: 该组件样式不要添加scoped
, 不然插槽内没有过渡效果。
<MyTransition> <div v-if="show">Hello</div> </MyTransition>
复制
十、transition-group使用
对列表进行过渡渲染时,就必须使用transition-group元素包裹。点击列表中内容,按照以下动画移除,示例如下
<template> <div class="main_css"> <transition-group name="slide"> <li v-for="(item,i) in list" :key="item.id" @click="del(i)"> {{ item.id }} --- {{ item.name }} </li> </transition-group> </div> </template> <script> export default { name: 'transitionGroupTest', data () { return { list: [{ id: 1, name: '红烧鱼' }, { id: 2, name: '炒土豆' }, { id: 3, name: '烧茄子' } ] } }, methods: { del (i) { this.list.splice(i, 1) } } } </script> <style scoped> .main_css { margin-left: 50px; margin-top: 50px; } .slide-enter-active { transition: all .5s linear; } .slide-leave-active { transition: all .1s linear; } .slide-enter { transform: translateX(-100%); opacity: 0; } .slide-leave-to { transform: translateX(110%); opacity: 0; } </style>
复制