Vue3使用transition组件改变DOM属性的方式小结
作者:超捻
想要制作基于状态变化的过渡,使用vue内置组件、Class、动画库来快速实现;
<Transition>会在单个元素或组件进入和离开 DOM 时应用动画;
<TransitionGroup>会在一个 v-for 列表中的元素或组件被插入,移动,或移除时应用动画;
下面使用Vue3的代码对DOM的width、height属性进行过渡的不同实现方式
1、<transition> 标签
使用 name
属性 来定义class 来实现DOM的属性的过渡
<template> <div> <button @click="flag = !flag">switch</button> <!-- 用法1 name属性定义class--> <transition name="fade"> <div v-if="flag" class="box">name属性定义class</div> </transition> </div> </template> <script setup lang='ts'> import{ref} from 'vue' const flag = ref<boolean>(true) </script> <style scoped lang="scss"> .box{ width: 200px; height: 200px; background-color: red; } .fade-enter-from { // 进入 从XX 开始 width: 0; height: 0; } .fade-enter-active { // 过程 transition: all 1.5s ease; } .fade-enter-to { // 进入 到 XX 结束 width: 200px; height: 200px; transform: scale(1.2); // 放大1.2倍 } .fade-leave-from { // 离开 从XX 开始 width: 200px; height: 200px; } .fade-leave-active { // 过程 transition: all 1.5s ease; } .fade-leave-to { // 离开 到 XX 结束 width: 0; height: 0; } </style>
页面效果:
可以通过name属性,绑定指定name的class, 灵活定义过渡的进入
和离开
时的效果;
上面方式缺点是class.xxx-enter-from
-enter-from
部分是固定的, 如果想要定义整个class名,可以使用<Transition>
另外属性;
进入:enter-from-class
、enter-active-class
、enter-to-class
、
离开:leave-from-class
、leave-active-class
、leave-to-class
<template> <transition enter-from-class="dada-enter-from" enter-active-class="dada-enter-active" enter-to-class="dada-enter-to" leave-from-class="dada-leave-from" leave-active-class="dada-leave-active" leave-to-class="dada-leave-to"> <div v-if="flag" class="box">自定义类名</div> </transition> </template> ... <style scoped lang="scss"> dada-enter-from { width: 0; height: 0; } .dada-enter-active { // 过程 transition: all 1.5s ease; } .dada-enter-to { // 进入 到 XX 结束 width: 200px; height: 200px; transform: scale(1.2); // 放大1.2倍 } .dada-leave-from { width: 200px; height: 200px; } .dada-leave-active { // 过程 transition: all 1.5s ease; } .dada-leave-to { // 离开 到 XX 结束 width: 0; height: 0; } </style>
页面效果:同上
<transition> + 动画库 animate.css
安装: npm install animate.css --save
或yarn add animate.css
<transition :duration="1000" enter-active-class="animate__animated animate__flipInX" leave-active-class="animate__animated animate__fadeOutDown"> <div v-if="flag" class="box font-12">结合第三方类库 animate.css</div> </transition> <script setup lang='ts'> import 'animate.css' </script>
属性duration:number|{enter:number, leave:number}
是指动画时长;如果进入
和离开
定义相同时长,值可定义number类型,如果进入
和离开
定义不同时长,值可定义object类型;
注意,使用class时不要漏加特定classanimate__animated
,
页面效果:
使用第三方CSS动画库,过渡效果丰富,减少自己写CSS代码,直接添加对应效果的class即可;
丰富有趣的交互效果,往往只有class是不够的,还需要通过JS代码控制动画来实现;
想要通过 Javascript来控制过渡动画,首先理解过渡的时机,动画分为进入和离开,进入有:进入前、进入、进入后,同样离开: 离开前、离开、离开后,那么在不同时机中,触发JavaScript 逻辑即可;
<transition>
对应的事件:
@before-enter
:进入之前@before-leave
:离开之前@enter
:进入时@leave
:离开时@after-enter
:进入之后@after-leave
:离开之后@enter-cancelled
:进入中断@leave-cancelled
(v-show
only):离开中断
<template> <transition @before-enter="EnterFrom" @enter="EnterActive" @after-enter="EnterTo" @enter-cancelled="EnterCancel" @before-leave="LeaveFrom" @leave="LeaveActive" @after-leave="LeaveTo" @leave-cancelled="LeaveCancel" > <div v-if="flag" class="box">8个 生命周期</div> </transition> </template> <script setup lang='ts'> // 进入 const EnterFrom = (el:Element) => { console.log('动画进入之前EnterFrom'); } const EnterActive = (el:Element, done: gsap.Callback) => { console.log('进入时 EnterActive'); } const EnterTo = (el:Element) => { console.log(el,'动画进入之后 EnterTo'); } const EnterCancel = (el:Element) => { console.log(el,'动画进过渡效果 被打断时 EnterCancel'); } // 离开 // el DOM 节点 const LeaveFrom = (el:Element) => { console.log(el, '动画离开之前LeaveFrom'); } const LeaveActive = (el:Element, done:Function) => { console.log(el,'离开时 LeaveActive'); done() } const LeaveTo = (el:Element) => { console.log(el,'动画离开之后 LeaveTo'); } const LeaveCancel = (el:Element) => { console.log(el,'动画离开过渡效果 被打断时------'); } </script>
过渡进入时触发:
过渡离开时触发:
过渡中断是什么时候出发呢,当进入过程中立马切换为离开时就会触发中断的函数了;当理解了出发函数钩子的时机,可以结合优秀的动画库,精准的实现效果;
2、<transition-group> 标签
单节点动画可以使用<transition>
,多节点可以使用 <transition-group>
;
特点:
- 默认情况下 它不会渲染一个包裹元素,但是可以通过tag attribute 指定渲染一个元素,
<transition-group tag="div">
或<transition tag="section">
实际生成DOM标签div
或section
包一层; - 过渡模式下不可用, 因为我们不再相互切换特有的元素
- 内部元素 总是需要提供一个唯一的 key attribute值
- CSS过渡的类型将会应用在内部的元素中,而不是这个组/容器本身
列表的移动过渡示例:
<template> <!-- 列表的移动过度示例 技术点: <transition-group> 组件还有一个特殊之处除了进入和离开,transition-group还可以为定位的改变添加动画 第三方库: lodash npm install lodash --S 注意在ts 下 还需要安装类型声明文件库 npm i --save-dev @types/lodash --> <div> <button @click="random">random</button> <transition-group move-class="move" class="wrap" tag="div"> <div class="item" v-for="item in list" :key="item.id">{{ item.number }}</div> </transition-group> </div> </template> <script setup lang='ts'> import {ref} from 'vue' import _ from 'lodash' // 需要安装声明文件 npm i -D @types/lodash let list = ref(Array.apply(null, {length:81} as number[]).map((_, index) => { return { id: index, number: (index % 9) + 1 } })) console.log(list, 'list'); const random = () => { list.value = _.shuffle(list.value) } </script> <style scoped lang="scss"> .wrap { display: flex; flex-wrap: wrap; width: calc(25px * 9 + 9px); .item { width: 25px; height: 25px; border: 1px solid #ccc; display: flex; justify-self: center; align-items: center; } } .move { transition: all 1s; } </style>
状态的过渡:
<template> <input type="number" step="20" v-model="num.current"> <div style="font-size: 30px; margin-left: 20px;">{{ num.tweenedNumber.toFixed() }} </div> </template> <script setup lang='ts'> import {reactive, watch} from 'vue' import gsap from 'gsap' const num = reactive({ current: 0, tweenedNumber:0 }) watch(() => num.current, (newVal) =>{ gsap.to(num, { duration: 1, tweenedNumber: newVal }) }) </script>
3、总结
主要理解<Transition>
、<TransitionGroup>
,同时结合动画库来实现过渡效果;
到此这篇关于Vue3使用transition组件改变DOM属性的方式小结的文章就介绍到这了,更多相关Vue3 transition改变DOM属性内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!