0


vue3 中使用动画技术

vue3 中使用动画技术

作者: jcLee95
邮箱 :291148484@163.com
CSDN 主页https://blog.csdn.net/qq_28550263?spm=1001.2101.3001.5343
本文地址https://blog.csdn.net/qq_28550263/article/details/122892028
  1. // TODO: // 增加 [animejs](#https://animejs.com/)、[Motion One](#https://motion.dev/) 结合vue trasition的用法

目 录

组件名描述用于在元素或组件

  1. 进入

  1. 离开

DOM 时应用动画。用于在将

  1. 元素

  1. 组件

**

  1. 插入列表

  1. 从列表删除

** 或 **

  1. v-for列表中移动

** 时应用动画。

作为VUE内置组件,可以在任何VUE组件的模板中使用,而无需注册它。

1) 通过条件渲染 (
  1. v-if

);

2) 通过条件显示 (
  1. v-show

3) 通过特殊元素切换动态组件(
  1. <component>

4) 通过路由切换:需要 VueRouter 中 <router-view> 的
  1. v-slot

API。

请添加图片描述
CSS类名描述

  1. v-enter-from

进入的起始状态。在元素插入之前添加,在元素插入后一帧移除。

  1. v-enter-active

进入的活动状态。在整个进入阶段应用。在插入元素之前添加,在过渡/动画完成时移除。此类可用于定义进入过渡的持续时间、延迟和缓动曲线。

  1. v-enter-to

进入的结束状态。在元素插入后添加一帧(同时

  1. v-enter-from

被移除),在过渡/动画完成时移除。

  1. v-leave-from

休假的开始状态。触发离开过渡时立即添加,一帧后删除。

  1. v-leave-active

休假的活动状态。在整个离开阶段应用。在触发离开过渡时立即添加,在过渡/动画完成时删除。此类可用于定义离开过渡的持续时间、延迟和缓动曲线。

  1. v-leave-to

休假的结束状态。在触发离开过渡后添加一帧(同时

  1. v-leave-from

删除),在过渡/动画完成时删除。

  1. v-enter-active

  1. v-leave-active

让我们能够为进入/离开过渡指定不同的缓动曲线。

例如:

  1. <template><button@click="show = !show"> {{show}}</button><transition><h1:class="{
  2. animate__animated:true,
  3. animate__fadeIn:show,
  4. animate__fadeOut:!show,
  5. }">一段淡入淡出的动画文字。
  6. </h1></transition></template><scriptlang="ts">import{ defineComponent, ref }from'vue';exportdefaultdefineComponent({setup(){return{
  7. show:ref(true)}}});</script><style>.v-enter-active,
  8. .v-leave-active{transition: opacity 0.5s ease;}.v-enter-from,
  9. .v-leave-to{opacity: 0;}</style>

我们可以指定transition名(name属性),则以上类名中的

  1. v

将被替换成对应的transition名。上例中,可以改为:

  1. <template><button@click="show = !show"> {{show}}</button><transitionname="fade"><h1:class="{
  2. animate__animated:true,
  3. animate__fadeIn:show,
  4. animate__fadeOut:!show,
  5. }">一段淡入淡出的动画文字。
  6. </h1></transition></template><scriptlang="ts">import{ defineComponent, ref }from'vue';exportdefaultdefineComponent({setup(){return{
  7. show:ref(true)}}});</script><style>.fade-enter-active,
  8. .fade-leave-active{transition: opacity 0.5s ease;}.fade-enter-from,
  9. .fade-leave-to{opacity: 0;}</style>

可以看到,这里对应的CSS类名也都由

  1. v

变成了

  1. fade

,如

  1. .v-enter-active

变成了

  1. .fade-enter-active

,这里的效果还是一样的,只是为了我们控制页面上的多个动画元素时用以区别。

  1. <template><transitionname="custom-classes"enter-active-class="animate__animated animate__tada"leave-active-class="animate__animated animate__bounceOutRight"><pv-if="show">hello</p></transition></template><scriptlang="ts">import{ defineComponent, ref }from'vue';import'animate.css';exportdefaultdefineComponent({});</script>

可以理解,这里我们将

  1. enter-active-class

对应了

  1. animate__animated

  1. animate__tada

两个类,

  1. leave-active-class

对应了

  1. animate__animated

  1. animate__bounceOutRight

两个类。其中

  1. enter-active-class

也就相当于之前的

  1. .v-enter-active

  1. leave-active-class

也就相当于

  1. v-leave-active

。我们可以定义的属性有如下:

  • enter-from-class,相当于以前单个类名v-enter-from所描述的样式
  • enter-active-class,相当于以前单个类名v-enter-active所描述的样式
  • enter-to-class,相当于以前单个类名v-enter-to所描述的样式
  • leave-from-class,相当于以前单个类名v-leave-from所描述的样式
  • leave-active-class,相当于以前单个类名v-leave-active所描述的样式
  • leave-to-class,相当于以前单个类名v-leave-to所描述的样式

有时

Vue 需要附加事件监听器(watch)才能知道转换何时结束。它可以是 transitionend 或 animationend,具体取决于所应用的 CSS 规则的类型。如果您只使用其中一种,Vue 可以自动检测正确的类型。

但是,在某些情况下,您可能希望将两者都放在同一个元素上,例如让 Vue 触发 CSS 动画,以及悬停时的 CSS 过渡效果。在这些情况下,您必须通过传递 prop 来显式声明您希望 Vue 关心的类型type,其值为animation 或者 transition:

  1. <Transitiontype="animation">...</Transition>

虽然过渡类只应用于

  1. <Transition>

中的直接子元素,但我们可以使用嵌套 CSS 选择器来过渡嵌套元素:

  1. <Transitionname="nested"><divv-if="show"class="outer"><divclass="inner">
  2. Hello
  3. </div></div></Transition>
  1. /* rules that target nested elements */.nested-enter-active .inner,
  2. .nested-leave-active .inner{transition: all 0.3s ease-in-out;}.nested-enter-from .inner,
  3. .nested-leave-to .inner{transform:translateX(30px);opacity: 0;}

我们甚至可以在 enter 的嵌套元素中添加一个过渡延迟,从而创建一个交错的 enter 动画序列:

  1. /* delay enter of nested element for staggered effect */.nested-enter-active .inner{transition-delay: 0.25s;}

但是,这会产生一个小问题。默认情况下,

  1. <Transition>

组件尝试通过侦听根过渡元素上的第一个

  1. transitionend

  1. animationend

事件来自动确定过渡何时完成。对于嵌套转换,所需的行为应该等待所有内部元素的转换完成。
在这种情况下,您可以使用

  1. <transition>

组件上的

  1. duration

prop 指定显式转换持续时间(以毫秒为单位)。总持续时间应与内部元素的延迟加上过渡持续时间相匹配:

  1. <Transition:duration="550">...</Transition>

可以通过侦听组件上的事件来使用 JavaScript 挂钩到转换过程

  1. <Transition>

  1. <Transition@before-enter="onBeforeEnter"@enter="onEnter"@after-enter="onAfterEnter"@enter-cancelled="onEnterCancelled"@before-leave="onBeforeLeave"@leave="onLeave"@after-leave="onAfterLeave"@leave-cancelled="onLeaveCancelled"><!-- ... --></Transition>
  1. exportdefault{// ...
  2. methods:{// 在元素插入到DOM之前调用。// 用它来设置元素的“enter-from”状态onBeforeEnter(el){},// 插入元素后一帧调用。// 用它来开始动画。onEnter(el, done){// 调用done回调来指示transition结束// 如果与CSS结合使用,则可选done()},// 当进入 transition 完成时调用。onAfterEnter(el){},onEnterCancelled(el){},// 在离开钩子前调用// 大多数情况下,你应该使用离开钩子。onBeforeLeave(el){},// 离开 transition 开始时调用。// 使用这个开始离开动画。onLeave(el, done){// 调用done回调来指示 transition 结束// 如果与CSS结合使用,则可选done()},// 当离开 transition 完成并且元素已经从DOM中移除时调用。onAfterLeave(el){},// 当且仅当使用 v-show transitions 时有效leaveCancelled(el){}}}

这些钩子可以与 CSS 过渡/动画结合使用,也可以单独使用。使用

  1. :css="false"

,我们还完全负责控制过渡何时结束。在这种情况下,

  1. @enter

  1. @leave

钩子完成需要回调。否则,钩子将被同步调用,转换将立即完成。

默认情况下,不渲染包装 DOM 元素,但可以通过

  1. tag

属性 定义。

  1. <TransitionGrouptag="ul"name="slide"><liv-for="item in items":key="item.id">
  2. {{ item.text }}
  3. </li></TransitionGroup>

支持通过 CSS 变换移动过渡。当更新后孩子在屏幕上的位置发生变化时,它将应用一个移动的 CSS 类(从name属性自动生成或使用move-class道具配置)。如果在应用移动类时 CSS transform属性是“可转换的”,则元素将使用FLIP 技术平滑地动画到其目的地。

下面是一个将进入/离开转换应用到v-for列表的示例:

  1. <template><button@click="add()"> 添加 </button><button@click="pop()"> 删除 </button><TransitionGroupname="list"tag="ul"><liv-for="item in items":key="item">
  2. {{ item }}
  3. </li></TransitionGroup></template><scriptlang="ts">import{ defineComponent, ref }from'vue';exportdefaultdefineComponent({setup(){return{
  4. items:ref([1,2,3,4,5,6])}},
  5. methods:{add(){this.items.push(
  6. Math.round(Math.random()*10))},pop(){this.items.pop()}}});</script><stylelang="scss"scoped>.list-enter-active,
  7. .list-leave-active{transition: all 0.5s ease;}.list-enter-from,
  8. .list-leave-to{opacity: 0;transform:translateX(30px);}</style>

上面的演示有一些明显的缺陷:当一个项目被插入或移除时,它周围的项目会立即“跳”到位,而不是平稳地移动。我们可以通过添加一些额外的 CSS 规则来解决这个问题:

  1. .list-move,/* 应用 transition 来移动元素 */.list-enter-active,
  2. .list-leave-active{transition: all 0.5s ease;}.list-enter-from,
  3. .list-leave-to{opacity: 0;transform:translateX(30px);}/* 确保离开项目从布局流中移除,以便可以正确计算移动动画。 */.list-leave-active{position: absolute;}

1.1.2.3 交错列表转换

通过数据属性与 JavaScript 进行通信,还可以在列表中交错转换。首先,我们将项目的索引渲染为 DOM 元素上的数据属性:

  1. <TransitionGrouptag="ul":css="false"@before-enter="onBeforeEnter"@enter="onEnter"@leave="onLeave"><liv-for="(item, index) in computedList":key="item.msg":data-index="index">
  2. {{ item.msg }}
  3. </li></TransitionGroup>

然后,在 JavaScript 钩子中,我们根据数据属性为元素设置一个延迟动画:

  1. functiononEnter(el, done){
  2. gsap.to(el,{
  3. opacity:1,
  4. height:'1.6em',
  5. delay: el.dataset.index *0.15,
  6. onComplete: done
  7. })}

<router-view> 的 v-slot

Vue Router v4.x(对应vue3) 中,<router-view> 暴露了一个

  1. v-slot

API,主要使用 和 组件来包裹你的路由组件。

  1. transition

  1. keep-alive

组件必须通过 v-slot API 在 RouterView 内部使用,如:

  1. <router-viewv-slot="{ Component }"><transition><keep-alive><component:is="Component"/></keep-alive></transition></router-view>

其中,

  1. Component

是要传递给 的 VNodes 是 prop。显然 router-view 中使用插槽时 v-slot 是用于接收对象的,Component 代表的就是需要加载的组件,这将传给内置组件<component>的is使用。除了接收需要渲染的组件外,还接收一个

  1. route

对象,这个对象包含了对应于当前渲染的组件的路由信息。如:

  1. <Suspense><template#default><router-viewv-slot="{ Component, route }"><transition:name="route.meta.transition || 'fade'"mode="out-in"><keep-alive><component:is="Component":key="route.meta.usePathKey ? route.path : undefined"/></keep-alive></transition></router-view></template><template#fallback> Loading... </template></Suspense>

由于所有的导航,包括第一个导航,现在都是异步的,这意味着,如果你使用一个

  1. transition

,你可能需要等待路由 ready 好后再挂载程序:

  1. app.use(router)// 注意:在服务器端,你需要手动跳转到初始地址。
  2. router.isReady().then(()=> app.mount('#app'))

否则会有一个初始过渡,就像你提供了

  1. appear

属性到

  1. transition

一样,因为路由会显示它的初始地址(什么都没有),然后显示第一个地址。

请注意,如果在初始导航时有导航守卫,你可能不想阻止程序渲染,直到它们被解析,除非你正在进行服务器端渲染。否则,在这种情况下,不等待路由准备好挂载应用会产生与 Vue2 中相同的结果。

Animate.css 是一个动画效果库,它提供了多种简单易用的CSS动画效果。

  1. npminstall animate.css --save

或者

  1. yarnadd animate.css
  1. <template><h1class="animate__animated animate__bounce ">一段跳动的动画文字。</h1></template><scriptlang="ts">import'animate.css';import{ defineComponent,}from'vue';exportdefaultdefineComponent({})</script>

Animate.css 提供了延时类,因此我们也可以直接在元素的 class 属性上添加延迟:
类名默认延迟时间

  1. animate__delay-2s

2s

  1. animate__delay-3s

3s

  1. animate__delay-4s

4s

  1. animate__delay-5s

5s
Animate.css 使用自定义属性(也称为 CSS 变量)来定义动画的持续时间、延迟和迭代。这使得 Animate.css 非常灵活和可定制。需要更改动画持续时间时,只需在全局或本地设置一个新值:

  • 这只会改变这个特定的动画持续时间:<stylelang="scss"scoped>.animate__animated.animate__bounce{--animate-duration: 2s;}</style>
  • 这将全局更改所有动画:<stylelang="scss"scoped>:root{--animate-duration: 800ms;--animate-delay: 0.9s;}</style>

尽管该库提供了一些帮助类,例如animated让您快速运行的类,但您可以直接使用提供的动画keyframes。

  1. <template><h1class="my-element">一段跳动的动画文字。</h1></template><scriptlang="ts">import'animate.css';import{ defineComponent,}from'vue';exportdefaultdefineComponent({})</script><stylescropd>.my-element{display: inline-block;margin: 0 0.5rem;animation: bounce;/* 直接引用动画的 @keyframe 声明 */animation-duration: 2s;/* 别忘了设置时长! */}</style>

自定义属性还可以轻松地动态更改所有动画的时间受限属性。这意味着您可以使用 javascript one-liner 获得慢动作或延时效果:

  • 所有动画将花费两倍的时间来完成:document.documentElement.style.setProperty('--animate-duration','2s');
  • 所有动画将花费一半的时间来完成:document.documentElement.style.setProperty('--animate-duration','.5s');

当写在VUE中,你不应该写在

  1. setup

中,因为这是在构建组件前的配置。通常你可以根据需要在以下钩子中使用:

  • beforeCreate(在实例初始化之后、进行数据侦听和事件/侦听器的配置之前);
  • created(在实例创建完成后);
  • mounted(在实例挂载完成后) ;

比如在一个组件中完整看起来是这样写:

  1. <template><h1class="animate__animated animate__bounce ">一段跳动的动画文字。</h1></template><scriptlang="ts">import{ defineComponent }from'vue';import'animate.css';exportdefaultdefineComponent({beforeMount(){// 所有动画将花费两倍的时间来完成
  2. document.documentElement.style.setProperty('--animate-duration','.1s');}});</script>

Animate.css 提供了重复类,因此我们也可以直接在元素的 class 属性上添加重复:
类名默认延迟时间

  1. animate__repeat-1

1

  1. animate__repeat-2

2

  1. animate__repeat-3

3

  1. animate__infinite

infinite
例如:

  1. <!-- 重复2次 --><divclass="animate__animated animate__bounce animate__repeat-2">Example</div>

类名描述说明

  1. animate__bounce

弹跳重复几次的上下跳动的动画效果

  1. animate__flash

闪光重复几次的隐藏又显示的动画效果

  1. animate__pulse

脉冲一次稍微变大又缩小会原来尺寸的效果

  1. animate__rubberBand

橡皮筋像同时往左右拉伸橡皮经一样的动画

  1. animate__shakeX

X轴摇晃反复左右平移几次

  1. animate__shakeY

Y轴摇晃反复上下平移几次

  1. animate__headShake

摇头轻轻地左右平移几次,就像摇头

  1. animate__swing

摇摆绕着上方一个点按弧形摇摆

  1. animate__tada

-略微缩小同时逆时针旋转一个小角度后还原,然后绕中心轻微摇摆几次

  1. animate__wobble

摇晃大幅度大半径按下方圆心的圆弧轨迹摇晃

  1. animate__jello

果冻就像果冻落地一小段时间内的形变过程动画

  1. animate__heartBeat

心跳几次放大放小的动画,就像心跳一样
类名描述说明

  1. animate__backInDown

向下后入从上掉下的进入动画

  1. animate__backInLeft

从左后入从左向右的进入动画

  1. animate__backInRight

从右后入从右向左的进入动画

  1. animate__backInUp

向上后入从下向上的进入动画
类名描述说明

  1. animate__backOutDown

向下后出从上掉下的移出动画

  1. animate__backOutLeft

向左后出从原地退后向右的移出动画

  1. animate__backOutRight

向右后出从原地退后右向左的移出动画

  1. animate__backOutUp

向上后出从原地退后向上的移出动画
类名描述说明

  1. animate__bounceIn

弹入从原地弹入动画

  1. animate__bounceInDown

弹入从上向下弹入动画

  1. animate__bounceInLeft

弹入从左向右弹入动画

  1. animate__bounceInUp

弹入从右向左弹入动画
类名描述说明

  1. animate__bounceOut

-略微缩小后向内移出

  1. animate__bounceOutDown

-略微缩小后向下移出

  1. animate__bounceOutLeft

-略微缩小后向左移出

  1. animate__bounceOutRight

-略微缩小后向右移出

  1. animate__bounceOutUp

-略微缩小后向上移出
类名描述说明

  1. animate__fadeIn

渐显淡入,即逐渐显示

  1. animate__fadeInDown

渐显-下从上向下淡入

  1. animate__fadeInDownBig

渐显-下&大从上向下淡入,更大的动画幅度

  1. animate__fadeInLeft

渐显-左从左向右淡入

  1. animate__fadeInLeftBig

渐显-左&大从左向右淡入,更大的动画幅度

  1. animate__fadeInRight

渐显-右

  1. animate__fadeInRightBig

渐显-右&大更大的动画幅度

  1. animate__fadeInUp

渐显-上更大的动画幅度

  1. animate__fadeInUpBig

渐显-上&大

  1. animate__fadeInTopLeft

渐显-左上

  1. animate__fadeInTopRight

渐显-左上&大更大的动画幅度

  1. animate__fadeInBottomLeft

渐显-左下

  1. animate__fadeInBottomRight

渐显-左&大更大的动画幅度
类名描述说明

  1. animate__fadeOut

淡出变淡找到消失

  1. animate__fadeOutDown

下淡出由上向下淡出

  1. animate__fadeOutDownBig

下淡出-大由上向下淡出,动作幅度更大

  1. animate__fadeOutLeft

左淡出从左向右淡出

  1. animate__fadeOutLeftBig

左淡出-大从左向右淡出,动作幅度更大

  1. animate__fadeOutRight

右淡出从右向左淡出

  1. animate__fadeOutRightBig

右淡出-大从右向左淡出,动作幅度更大

  1. animate__fadeOutUp

上淡出由下向上淡出

  1. animate__fadeOutUpBig

上淡出-大由下向上淡出,动作幅度更大

  1. animate__fadeOutTopLeft

左上方淡出-

  1. animate__fadeOutTopRight

右上方淡出-

  1. animate__fadeOutBottomRight

左下方淡出-

  1. animate__fadeOutBottomLeft

右下方淡出-
类名描述说明

  1. animate__flip

后空翻(为默认的Y轴)

  1. animate__flipInX

绕X轴后空翻以元素横中轴线上下翻动

  1. animate__flipInY

绕Y轴后空翻以元素纵中轴线上下翻动

  1. animate__flipOutX

绕X轴后空翻与

  1. animate__flipInX

旋转方向相反

  1. animate__flipOutY

绕Y轴后空翻与

  1. animate__flipInY

旋转方向相反
类名描述说明

  1. animate__lightSpeedInRight

-从右向左进入

  1. animate__lightSpeedInLeft

-从左向右进入

  1. animate__lightSpeedOutRight

-向右移出

  1. animate__lightSpeedOutLeft

-向左移出
类名描述说明

  1. animate__rotateIn

旋转进入(逆时针)

  1. animate__rotateInDownLeft

-从零点处顺时针90°旋转进入

  1. animate__rotateInDownRight

-从零点处逆时针90°旋转进入

  1. animate__rotateInUpLeft

-从6点处逆时针90°旋转进入

  1. animate__rotateInUpRight

-从6点处顺时针90°旋转进入
类名描述说明

  1. animate__rotateOut

旋转退出(顺时针)

  1. animate__rotateOutDownLeft

-3点向6点顺时针旋转退出

  1. animate__rotateOutDownRight

-9点向6点逆时针旋转退出

  1. animate__rotateOutUpLeft

-3点向12点逆时针旋转退出

  1. animate__rotateOutUpRight

-9点向12点顺时针旋转退出
类名描述说明

  1. animate__zoomIn

-由中心点方法进入

  1. animate__zoomInDown

-由上方一个小点放大掉入

  1. animate__zoomInLeft

-从左向右放大进入

  1. animate__zoomInRight

-从右向左放大进入

  1. animate__zoomInUp

-从下向上放大进入
类名描述说明

  1. animate__zoomOut

-向中心一点缩小退出

  1. animate__zoomOutDown

-缩小到一定尺寸后,向下退出

  1. animate__zoomOutLeft

-缩小到一定尺寸后,向左退出

  1. animate__zoomOutRight

-缩小到一定尺寸后,向右退出

  1. animate__zoomOutUp

-缩小到一定尺寸后,向上退出
类名描述说明

  1. animate__slideInDown

下滑入向下滑入

  1. animate__slideInLeft

左滑入从左滑入

  1. animate__slideInRight

右滑入从右滑入

  1. animate__slideInUp

上滑入向上滑入
类名描述说明

  1. animate__slideOutDown

下滑出向下滑出

  1. animate__slideOutLeft

左滑出从左滑出

  1. animate__slideOutRight

右滑出从右滑出

  1. animate__slideOutUp

上滑出向上滑出
类名描述说明

  1. animate__hinge

-左侧端点为圆心挂住,右侧绕圆弧下垂,最后整体落体

  1. animate__jackInTheBox

-一种旋转进入的效果

  1. animate__rollIn

-一种大幅度从左侧翻滚进入的效果

  1. animate__rollOut

-一种大幅度向右侧翻滚退出的效果

在上文中我们介绍过 ,这也是使用的一种简单方法:

  1. <template><transitionname="custom-classes"enter-active-class="animate__animated animate__tada"leave-active-class="animate__animated animate__bounceOutRight"><pv-if="show">hello</p></transition></template><scriptlang="ts">import{ defineComponent, ref }from'vue';import'animate.css';exportdefaultdefineComponent({});</script>

实际上,为了实现动画效果,有些情况下 Transition 不是必须的。比如在使用 VUERouter时,可以直接将动画CSS绑定到

  1. router-view

上,如:

  1. <router-view:class="{
  2. 'jcadmin-childPage':true,
  3. 'animate__animated': true,
  4. 'animate__zoomInDown': true,
  5. 'animate__zoomOutDown': false,
  6. }"></router-view>

但是这要求当路由变化时,路由渲染了不同的组件。在某些情况下我们可能传入了不同路由相同组件,这种做法比较特殊,因为在VueRouter中的不同路由传入相同的组件作为视图时,他们将获得相同的

  1. scopID

(用于渲染只属于当前组件的样式)、

  1. hmrID

(用于热模块重载)等等,不会被VUE视作不同模块,因此可能通过props传入特定参数来最终显示不同的视图。


本文转载自: https://blog.csdn.net/qq_28550263/article/details/122892028
版权归原作者 jcLee95 所有, 如有侵权,请联系我们删除。

“vue3 中使用动画技术”的评论:

还没有评论