Vue3官网-过度&动画(一)transition&animation、ease-out,cubic-bezier、过渡class enter-from JavaScript 钩子 过渡模式out-i

Vue3官网-过度&漫画(一)过渡 & 动画概述(transition & animation)、ease-in,ease-out,cubic-bezier、过渡class(v-enter-from,v-enter-active)、JavaScript 钩子、过渡模式(out-in)

文章目录

  • Vue3官网-过度&漫画(一)过渡 & 动画概述(transition & animation)、ease-in,ease-out,cubic-bezier、过渡class(v-enter-from,v-enter-active)、JavaScript 钩子、过渡模式(out-in)
    • 1. 过渡 & 动画概述
      • 基于 class 的动画和过渡
      • 过渡与 Style 绑定
      • 性能
        • Transform 和 Opacity
        • 硬件加速
      • Timing
      • Easing
      • 进一步阅读
    • 2. 进入过渡 & 离开过渡
      • 单元素/组件的过渡
        • 过渡class
        • CSS 过渡
        • CSS 动画
        • 自定义过渡 class 类名
        • 同时使用过渡和动画
        • 显性的过渡持续时间
        • JavaScript 钩子
      • 初始渲染的过渡
      • 多个元素的过渡
        • 过渡模式
      • 多个组件之间过渡

总结:

  • 补充

    • Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。

    • truthy(真值):在 JavaScript 中,truthy(真值)指的是在布尔值上下文中,转换后的值为真的值。所有值都是真值,除非它们被定义为 假值(即除 false0""nullundefinedNaN 以外皆为真值)。括号内都是假值falsy。

    • .prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault()

    • ==Event.preventDefault方法取消浏览器对当前事件的默认行为。==比如点击链接后,浏览器默认会跳转到另一个页面,使用这个方法以后,就不会跳转了;再比如,按一下空格键,页面向下滚动一段距离,使用这个方法以后也不会滚动了。该方法生效的前提是,事件对象的cancelable属性为true,如果为false,调用该方法没有任何效果。

    • vue:用组件(app.component)构建一个模板(template),并反复使用模板

    • 父组件、子组件

      • const app = Vue.createApp({
                    
          components: {
                    
            'component-a': ComponentA,
            'component-b': ComponentB
          }
        })
        
      • 上面代码中app为父组件,ComponentA和ComponentB为子组件

    • Vue中美元$符号的意思

      • 除了数据属性,Vue 实例还暴露了一些有用的实例属性与方法。它们都有前缀 $,以便与用户定义的属性区分开来。
      • vue中$refs的作用?
        • 当我们需要获取一个dom元素进行操作的时候 可以利用原生js的getElementByXxx 而在vue中可以设置refs来获取这个dom元素
    • 第三方网站

      • greensock API(GSAP):是一套用于所有主流浏览器中制作高性能html5动画的工具。他们有一个很棒的 ease visualizer,帮助你建立精心制作的画架。
      • animate.css :集成第三方 CSS 动画库
      • CSS Triggers :来查看哪些属性会在动画时触发重绘。这个网站是用来告诉开发者不同内核浏览器对css属性修改的重绘/回流情况,开发者知道了这些细节可以提高页面性能。
  • 过渡 & 动画概述(transition & animation)

    • Vue 提供了多种应用转换效果的方法

      • 自动为 CSS 过渡和动画应用 class;
      • 集成第三方 CSS 动画库,例如 animate.css ;
      • 在过渡钩子期间使用 JavaScript 直接操作 DOM;
      • 集成第三方 JavaScript 动画库。
    • css-hsl()函数

      • hsl() 函数使用色相、饱和度、亮度来定义颜色。

        HSL 即色相、饱和度、亮度(英语:Hue, Saturation, Lightness)。

        HSL 是一种将 RGB 色彩模型中的点在圆柱坐标系中的表示法。这两种表示法试图做到比基于笛卡尔坐标系的几何结构 RGB 更加直观。

      • hue - 色相 定义色相 (0 到 360) - 0 (或 360) 为红色, 120 为绿色, 240 为蓝色
        saturation - 饱和度 定义饱和度; 0% 为灰色, 100% 全色
        lightness - 亮度 定义亮度 0% 为暗, 50% 为普通, 100% 为白
    • css triggers

      • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kb79T3Ph-1632302146812)(https://segmentfault.com/img/bVCLim/view)]
      • 紫色代表如果layout,中文一般翻译成回流,浅绿色代表Paint,一般翻译成重绘,深墨绿色代表Composite,翻译成混合重绘回流任意发生一个就会引起混合
        Change from default:设置属性(从默认值修改,相当于一开始没设置css),Subsequernt updates:修改属性(对现有的属性值进行修改)。你当前看的属性是align-content,在这种情况下,B/G/W/E四种内核因为内核不同对修改/设置align-content引起的重绘/回流的情况各不相同,所以这个网站是用来告诉开发者不同内核浏览器对css属性修改的重绘/回流情况,开发者知道了这些细节可以提高页面性能。
    • transition

      • 描述
        transition-property 指定CSS属性的name,transition效果
        transition-duration transition效果需要指定多少秒或毫秒才能完成
        transition-timing-function 指定transition效果的转速曲线
        transition-delay 定义transition效果开始的时候
    • 动画:ease-in,ease-in-out,ease-out,cubic-bezier

      • linear 规定以相同速度开始至结束的过渡效果(等于 cubic-bezier(0,0,1,1))。(匀速)
        ease 规定慢速开始,然后变快,然后慢速结束的过渡效果(cubic-bezier(0.25,0.1,0.25,1))(相对于匀速,中间快,两头慢)。
        ease-in 规定以慢速开始的过渡效果(等于 cubic-bezier(0.42,0,1,1))(相对于匀速,开始的时候慢,之后快)。
        ease-out 规定以慢速结束的过渡效果(等于 cubic-bezier(0,0,0.58,1))(相对于匀速,开始时快,结束时候间慢,)。
        ease-in-out 规定以慢速开始和结束的过渡效果(等于 cubic-bezier(0.42,0,0.58,1))(相对于匀速,(开始和结束都慢)两头慢)。
        cubic-bezier(n,n,n,n) 在 cubic-bezier 函数中定义自己的值。可能的值是 0 至 1 之间的数值。
      • cubic-bezier

        • 称为三次贝塞尔曲线,主要是生成速度曲线的函数,规定是cubic-bezier(,,,) .
        • img
        • 从上图中我们可以看到,cubic-bezier有四个点:
          两个默认的,即:P0(0,0),P3(1,1);
          两个控制点,即:P1(x1,y1),P2(x2,y2)
          注:X轴的范围是0~1,超出cubic-bezier将失效,Y轴的取值没有规定,但是也不宜过大。
          我们只要调整两个控制点P1和P2的坐标,最后形成的曲线就是动画曲线。
    • greensock API(GSAP)

  • 进入过渡 & 离开过渡

    • 过渡class

      • v-enter-active:定义进入过渡生效时的状态。==在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。==这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
      • v-leave-active:定义离开过渡生效时的状态。==在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。==这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
      • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-COtyJC38-1632302146814)(https://v3.cn.vuejs.org/images/transitions.svg)]
      • 对于这些在过渡中切换的类名来说,如果你使用一个没有名字的 ,则 v- 是这些class名的默认前缀。如果你使用了 ,那么 v-enter-from会替换为 my-transition-enter-from
    • CSS过渡

      • transition: all 0.3s ease-out;
        
      • 使用过渡class即可

    • CSS动画

      • CSS 动画用法同 CSS 过渡,区别是在动画中 v-enter-from 类名在节点插入 DOM 后不会立即删除,而是在 animationend 事件触发时删除。

      • animation: bounce-in 0.5s;
        
    • 自定义类名

      • 他们的优先级高于普通的类名,这对于 Vue 的过渡系统和其他第三方 CSS 动画库,如 Animate.css. 结合使用十分有用。
      • 类别
        • enter-from-class
        • enter-active-class
        • enter-to-class
        • leave-from-class
        • leave-active-class
        • leave-to-class
    • 显性的过渡持续时间

      • 组件上的 duration prop 定制一个显性的过渡持续时间 (以毫秒计):

        <transition :duration="1000">...transition>
        
      • 你也可以定制进入和移出的持续时间:

        <transition :duration="{ enter: 500, leave: 800 }">...transition>
        
    • JavaScript 钩子

      • 可以在 attribute 中声明 JavaScript 钩子

          <transition
            @before-enter="beforeEnter"
            @enter="enter"
            @leave="leave"
            :css="false"
          >
         ---------------------------------------------methods: {
            beforeEnter(el) {
              gsap.set(el, {
                scaleX: 0.8,
                scaleY: 1.2
              })
            },
        
    • 过渡模式

      • in-out: 新元素先进行过渡,完成之后当前元素过渡离开。

      • out-in: 当前元素先进行过渡,完成之后新元素过渡进入。(大多数时候想要的状态

      • <transition name="fade" mode="out-in">
          
        transition>
        

1. 过渡 & 动画概述

Vue 提供了一些抽象概念,可以帮助处理过渡和动画,特别是在响应某些变化时。这些抽象的概念包括:

  • 在 CSS 和 JS 中,使用内置的 组件来钩住组件中进入和离开 DOM。
  • 过渡模式,以便你在过渡期间编排顺序。
  • 在处理多个元素位置更新时,使用 组件,通过 FLIP 技术来提高性能。
  • 使用 watchers 来处理应用中不同状态的过渡。

我们将在本指南接下来的三个部分中介绍所有这些以及更多内容。然而,除了提供这些有用的 API 之外,值得一提的是,我们前面介绍的 class 和 style 声明也可以应用于动画和过渡,用于更简单的用例。

在下一节中,我们将回顾一些 web 动画和过渡的基础知识,并提供一些资源链接以进行进一步的研究。如果你已经熟悉 web 动画,并且了解这些原理如何与 Vue 的某些指令配合使用,可以跳过这一节。对于希望在开始学习之前进一步了解网络动画基础知识的其他人,请继续阅读。

基于 class 的动画和过渡

尽管 组件对于组件的进入和离开非常有用,但你也可以通过添加一个条件 class 来激活动画,而无需挂载组件。

<div id="demo">
  Push this button to do something you shouldn't be doing:<br />

  <div :class="{ shake: noActivated }">
    <button @click="noActivated = true">Click mebutton>
    <span v-if="noActivated">Oh no!span>
  div>
div>
.shake {
     
  animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
  transform: translate3d(0, 0, 0);
  backface-visibility: hidden;
  perspective: 1000px;
}

@keyframes shake {
     
  10%,
  90% {
     
    transform: translate3d(-1px, 0, 0);
  }

  20%,
  80% {
     
    transform: translate3d(2px, 0, 0);
  }

  30%,
  50%,
  70% {
     
    transform: translate3d(-4px, 0, 0);
  }

  40%,
  60% {
     
    transform: translate3d(4px, 0, 0);
  }
}
const Demo = {
     
  data() {
     
    return {
     
      noActivated: false
    }
  }
}

Vue.createApp(Demo).mount('#demo')

Vue3官网-过度&动画(一)transition&animation、ease-out,cubic-bezier、过渡class enter-from JavaScript 钩子 过渡模式out-i_第1张图片

过渡与 Style 绑定

一些过渡效果可以通过插值的方式来实现,例如在发生交互时将样式绑定到元素上。以这个例子为例:

<div id="demo">
  <div
    @mousemove="xCoordinate"
    :style="{ backgroundColor: `hsl(${x}, 80%, 50%)` }"
    class="movearea"
  >
    <h3>Move your mouse across the screen...h3>
    <p>x: {
    {x}}p>
  div>
div>
.movearea {
     
  transition: 0.2s background-color ease;
}
const Demo = {
     
  data() {
     
    return {
     
      x: 0
    }
  },
  methods: {
     
    xCoordinate(e) {
     
      this.x = e.clientX
    }
  }
}

Vue.createApp(Demo).mount('#demo')

Vue3官网-过度&动画(一)transition&animation、ease-out,cubic-bezier、过渡class enter-from JavaScript 钩子 过渡模式out-i_第2张图片

在这个例子中,我们是通过使用插值来创建动画,将触发条件添加到鼠标的移动过程上。同时将 CSS 过渡属性应用在元素上,让元素知道在更新时要使用什么过渡效果。

性能

你可能注意到上面显示的动画使用了 transforms 之类的东西,并应用了诸如 perspective 之类的奇怪的 property——为什么它们是这样实现的,而不是仅仅使用 margintop 等?

我们可以通过对性能的了解,在 web 上创建极其流畅的动画。我们希望尽可能对元素动画进行硬件加速,并使用不触发重绘的 property。我们来介绍一下如何实现这个目标。

Transform 和 Opacity

我们可以通过工具,例如 CSS Triggers 来查看哪些属性会在动画时触发重绘。在工具中,查看 transform 的相关内容,你将看到:

非常好的是,更改 transform 不会触发任何几何形状变化或绘制。这意味着该操作可能是由合成器线程在 GPU 的帮助下执行。

opacity 属性的行为也类似。因此,他们是在 web 上做元素移动的理想选择。

硬件加速

诸如 perspectivebackface-visibilitytransform:translateZ(x) 等 property 将让浏览器知道你需要硬件加速。

如果要对一个元素进行硬件加速,可以应用以下任何一个 property (并不是需要全部,任意一个就可以):

perspective: 1000px;
backface-visibility: hidden;
transform: translateZ(0);

许多像 GreenSock 这样的 JS 库都会默认你需要硬件加速,并在默认情况下应用,所以你不需要手动设置它们。

Timing

对于简单 UI (User Interface 用户界面)过渡,即从一个状态到另一个没有中间状态的状态,通常使用 0.1s 到 0.4s 之间的计时,大多数人发现 0.25s 是一个最佳选择。你能用这个定时做任何事情吗?并不是。如果你有一些元素需要移动更大的距离,或者有更多的步骤或状态变化,0.25s 并不会有很好的效果,你将不得不有更多的目的性,而且定时也需要更加独特。但这并不意味着你不能在应用中重复使用效果好的默认值。

你也可能会发现,起始动画比结束动画的时间稍长一些,看起来会更好一些。用户通常是在动画开始时被引导的,而在动画结束时没有那么多耐心,因为他们想继续他们的动作。

Easing

Easing 是在动画中表达深度的一个重要方式。动画新手最常犯的一个错误是在起始动画节点使用 ease-in,在结束动画节点使用 ease-out。实际上你需要的是反过来的。

如果我们将这些状态应用于过渡,它应该像这样:

.button {
     
  background: #1b8f5a;
  /* 应用于初始状态,因此此转换将应用于返回状态 */
  transition: background 0.25s ease-in;
}

.button:hover {
     
  background: #3eaf7c;
  /* 应用于悬停状态,因此在触发悬停时将应用此过渡 */
  transition: background 0.35s ease-out;
}

Vue3官网-过度&动画(一)transition&animation、ease-out,cubic-bezier、过渡class enter-from JavaScript 钩子 过渡模式out-i_第3张图片

Easing 也可以表达动画元素的质量。以下面的 Pen 为例,你认为哪个球是硬的,哪个球是软的?

Vue3官网-过度&动画(一)transition&animation、ease-out,cubic-bezier、过渡class enter-from JavaScript 钩子 过渡模式out-i_第4张图片

你可以通过调整你的 Easing 来获得很多独特的效果,使你的动画非常时尚。CSS 允许你通过调整 cubic bezier 属性来修改 Easing,Lea Verou 开发的这个 playground 对探索这个问题非常有帮助。

虽然使用 cubic-bezier ease 提供的两个控制柄可以为简单的动画获得很好的效果,但是 JavaScript 允许多个控制柄,以此支持更多的变化。

Vue3官网-过度&动画(一)transition&animation、ease-out,cubic-bezier、过渡class enter-from JavaScript 钩子 过渡模式out-i_第5张图片

以弹跳为例。在 CSS 中,我们必须声明向上和向下的每个关键帧。在 JavaScript 中,我们可以通过在 greensock API(GSAP) 中声明 bounce 来描述 ease 中所有这些移动 (其他 JS 库有其他类型的 easing 默认值)。

这里是 CSS 中用来实现 bounce 的代码 (来自 animate.css 的例子):

@keyframes bounceInDown {
     
  from,
  60%,
  75%,
  90%,
  to {
     
    animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
  }

  0% {
     
    opacity: 0;
    transform: translate3d(0, -3000px, 0) scaleY(3);
  }

  60% {
     
    opacity: 1;
    transform: translate3d(0, 25px, 0) scaleY(0.9);
  }

  75% {
     
    transform: translate3d(0, -10px, 0) scaleY(0.95);
  }

  90% {
     
    transform: translate3d(0, 5px, 0) scaleY(0.985);
  }

  to {
     
    transform: translate3d(0, 0, 0);
  }
}

.bounceInDown {
     
  animation-name: bounceInDown;
}

下面是 JS 中使用 GreenSock 实现相同的 bounce:

gsap.from(element, {
      duration: 1, ease: 'bounce.out', y: -500 })

我们将在之后章节的部分示例中使用 GreenSock。他们有一个很棒的 ease visualizer,帮助你建立精心制作的画架。

进一步阅读

  • 界面动画设计:通过 Val Head 动画改善用户体验
  • Animation at Work 作者:Rachel Nabors

2. 进入过渡 & 离开过渡

在插入、更新或从 DOM 中移除项时,Vue 提供了多种应用转换效果的方法。这包括以下工具:

  • 自动为 CSS 过渡和动画应用 class;
  • 集成第三方 CSS 动画库,例如 animate.css ;
  • 在过渡钩子期间使用 JavaScript 直接操作 DOM;
  • 集成第三方 JavaScript 动画库。

在这里,我们只介绍进入、离开和列表的过渡,你也可以看下一节列表过渡和管理过渡状态 。

单元素/组件的过渡

Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡

  • 条件渲染 (使用 v-if)
  • 条件展示 (使用 v-show)
  • 动态组件
  • 组件根节点

这里是一个典型的例子:

<div id="demo">
  <button @click="show = !show">
    Toggle
  button>

  <transition name="fade">
    <p v-if="show">hellop>
  transition>
div>
const Demo = {
     
  data() {
     
    return {
     
      show: true
    }
  }
}

Vue.createApp(Demo).mount('#demo')
.fade-enter-active,
.fade-leave-active {
     
  transition: opacity 0.5s ease;
}

.fade-enter-from,
.fade-leave-to {
     
  opacity: 0;
}

Vue3官网-过度&动画(一)transition&animation、ease-out,cubic-bezier、过渡class enter-from JavaScript 钩子 过渡模式out-i_第6张图片

当插入或删除包含在 transition 组件中的元素时,Vue 将会做以下处理:

  1. 自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加/删除 CSS 类名。
  2. 如果过渡组件提供了 JavaScript 钩子函数 ,这些钩子函数将在恰当的时机被调用。
  3. 如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡/动画,DOM 操作 (插入/删除) 在下一帧中立即执行。(注意:此指浏览器逐帧动画机制,和 Vue 的 nextTick 概念不同)

过渡class

在进入/离开的过渡中,会有 6 个 class 切换。

  1. v-enter-from:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
  2. v-enter-active:定义进入过渡生效时的状态。==在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。==这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
  3. v-enter-to:定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter-from 被移除),在过渡/动画完成之后移除。
  4. v-leave-from:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
  5. v-leave-active:定义离开过渡生效时的状态。==在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。==这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
  6. v-leave-to:离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave-from 被删除),在过渡/动画完成之后移除。

Vue3官网-过度&动画(一)transition&animation、ease-out,cubic-bezier、过渡class enter-from JavaScript 钩子 过渡模式out-i_第7张图片

对于这些在过渡中切换的类名来说,如果你使用一个没有名字的 ,则 v- 是这些class名的默认前缀。如果你使用了 ,那么 v-enter-from会替换为 my-transition-enter-from

v-enter-activev-leave-active 可以控制进入/离开过渡的不同的缓和曲线,在下面章节会有个示例说明。

CSS 过渡

常用的过渡都是使用 CSS 过渡。

<div id="demo">
  <button @click="show = !show">
    Toggle render
  button>

  <transition name="slide-fade">
    <p v-if="show">hellop>
  transition>
div>
const Demo = {
     
  data() {
     
    return {
     
      show: true
    }
  }
}

Vue.createApp(Demo).mount('#demo')
/* 可以设置不同的进入和离开动画   */
/* 设置持续时间和动画函数        */
.slide-fade-enter-active {
     
  transition: all 0.3s ease-out;
}

.slide-fade-leave-active {
     
  transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1);
}

.slide-fade-enter-from,
.slide-fade-leave-to {
     
  transform: translateX(20px);
  opacity: 0;
}

Vue3官网-过度&动画(一)transition&animation、ease-out,cubic-bezier、过渡class enter-from JavaScript 钩子 过渡模式out-i_第8张图片

CSS 动画

CSS 动画用法同 CSS 过渡,区别是在动画中 v-enter-from 类名在节点插入 DOM 后不会立即删除,而是在 animationend 事件触发时删除

下面是一个例子,为了简洁起见,省略了带前缀的 CSS 规则:

<div id="demo">
  <button @click="show = !show">Toggle showbutton>
  <transition name="bounce">
    <p v-if="show">
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris facilisis
      enim libero, at lacinia diam fermentum id. Pellentesque habitant morbi
      tristique senectus et netus.
    p>
  transition>
div>
const Demo = {
     
  data() {
     
    return {
     
      show: true
    }
  }
}

Vue.createApp(Demo).mount('#demo')
.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);
  }
}

Vue3官网-过度&动画(一)transition&animation、ease-out,cubic-bezier、过渡class enter-from JavaScript 钩子 过渡模式out-i_第9张图片

自定义过渡 class 类名

我们可以通过以下 attribute 来自定义过渡类名:

  • enter-from-class
  • enter-active-class
  • enter-to-class
  • leave-from-class
  • leave-active-class
  • leave-to-class

他们的优先级高于普通的类名,这对于 Vue 的过渡系统和其他第三方 CSS 动画库,如 Animate.css. 结合使用十分有用。

示例:

<link
  href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.0/animate.min.css"
  rel="stylesheet"
  type="text/css"
/>

<div id="demo">
  <button @click="show = !show">
    Toggle render
  button>

  <transition
    name="custom-classes-transition"
    enter-active-class="animate__animated animate__tada"
    leave-active-class="animate__animated animate__bounceOutRight"
  >
    <p v-if="show">hellop>
  transition>
div>
const Demo = {
     
  data() {
     
    return {
     
      show: true
    }
  }
}

Vue.createApp(Demo).mount('#demo')

同时使用过渡和动画

Vue 为了知道过渡的完成,必须设置相应的事件监听器。它可以是 transitionendanimationend,这取决于给元素应用的 CSS 规则。如果你使用其中任何一种,Vue 能自动识别类型并设置监听。

但是,在一些场景中,你需要给同一个元素同时设置两种过渡动效,比如 animation 很快的被触发并完成了,而 transition 效果还没结束。在这种情况中,你就需要使用 type attribute 并设置 animationtransition 来明确声明你需要 Vue 监听的类型。

显性的过渡持续时间

在很多情况下,Vue 可以自动得出过渡效果的完成时机。默认情况下,Vue 会等待其在过渡效果的根元素的第一个 transitionendanimationend 事件。然而也可以不这样设定——比如,我们可以拥有一个精心编排的一系列过渡效果,其中一些嵌套的内部元素相比于过渡效果的根元素有延迟的或更长的过渡效果。

在这种情况下你可以用 组件上的 duration prop 定制一个显性的过渡持续时间 (以毫秒计):

<transition :duration="1000">...transition>

你也可以定制进入和移出的持续时间:

<transition :duration="{ enter: 500, leave: 800 }">...transition>

JavaScript 钩子

可以在 attribute 中声明 JavaScript 钩子

<transition
  @before-enter="beforeEnter"
  @enter="enter"
  @after-enter="afterEnter"
  @enter-cancelled="enterCancelled"
  @before-leave="beforeLeave"
  @leave="leave"
  @after-leave="afterLeave"
  @leave-cancelled="leaveCancelled"
  :css="false"
>
  
transition>
// ...
methods: {
     
  // --------
  // ENTERING
  // --------

  beforeEnter(el) {
     
    // ...
  },
  // 当与 CSS 结合使用时
  // 回调函数 done 是可选的
  enter(el, done) {
     
    // ...
    done()
  },
  afterEnter(el) {
     
    // ...
  },
  enterCancelled(el) {
     
    // ...
  },

  // --------
  // 离开时
  // --------

  beforeLeave(el) {
     
    // ...
  },
  // 当与 CSS 结合使用时
  // 回调函数 done 是可选的
  leave(el, done) {
     
    // ...
    done()
  },
  afterLeave(el) {
     
    // ...
  },
  // leaveCancelled 只用于 v-show 中
  leaveCancelled(el) {
     
    // ...
  }
}

这些钩子函数可以结合 CSS transitions/animations 使用,也可以单独使用。

当只用 JavaScript 过渡的时候,在 enterleave 钩中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。添加 :css="false",也会让 Vue 会跳过 CSS 的检测,除了性能略高之外,这可以避免过渡过程中 CSS 规则的影响。

现在让我们来看一个例子。下面是一个使用 GreenSock 的 JavaScript 过渡:

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.3.4/gsap.min.js">script>

<div id="demo">
  <button @click="show = !show">
    Toggle
  button>

  <transition
    @before-enter="beforeEnter"
    @enter="enter"
    @leave="leave"
    :css="false"
  >
    <p v-if="show">
      Demo
    p>
  transition>
div>
const Demo = {
     
  data() {
     
    return {
     
      show: false
    }
  },
  methods: {
     
    beforeEnter(el) {
     
      gsap.set(el, {
     
        scaleX: 0.8,
        scaleY: 1.2
      })
    },
    enter(el, done) {
     
      gsap.to(el, {
     
        duration: 1,
        scaleX: 1.5,
        scaleY: 0.7,
        opacity: 1,
        x: 150,
        ease: 'elastic.inOut(2.5, 1)',
        onComplete: done
      })
    },
    leave(el, done) {
     
      gsap.to(el, {
     
        duration: 0.7,
        scaleX: 1,
        scaleY: 1,
        x: 300,
        ease: 'elastic.inOut(2.5, 1)'
      })
      gsap.to(el, {
     
        duration: 0.2,
        delay: 0.5,
        opacity: 0,
        onComplete: done
      })
    }
  }
}

Vue.createApp(Demo).mount('#demo')

Vue3官网-过度&动画(一)transition&animation、ease-out,cubic-bezier、过渡class enter-from JavaScript 钩子 过渡模式out-i_第10张图片

初始渲染的过渡

可以通过 appear attribute 设置节点在初始渲染的过渡

<transition appear>
  
transition>

多个元素的过渡

我们之后讨论多个组件之间过渡,对于原生标签可以使用 v-if/v-else-if/v-else。最常见的多标签过渡是一个列表和描述这个列表为空消息的元素:

<transition>
  <table v-if="items.length > 0">
    
  table>
  <p v-else>Sorry, no items found.p>
transition>

实际上,通过使用 v-if/v-else-if/v-else 或将单个元素绑定到一个动态 property,可以在任意数量的元素之间进行过渡。例如:

<transition>
  <button v-if="docState === 'saved'" key="saved">
    Edit
  button>
  <button v-else-if="docState === 'edited'" key="edited">
    Save
  button>
  <button v-else-if="docState === 'editing'" key="editing">
    Cancel
  button>
transition>

也可以写为:

<transition>
  <button :key="docState">
    {
    { buttonMessage }}
  button>
transition>
// ...
computed: {
     
  buttonMessage() {
     
    switch (this.docState) {
     
      case 'saved': return 'Edit'
      case 'edited': return 'Save'
      case 'editing': return 'Cancel'
    }
  }
}

过渡模式

这里还有一个问题,试着点击下面的按钮:

Vue3官网-过度&动画(一)transition&animation、ease-out,cubic-bezier、过渡class enter-from JavaScript 钩子 过渡模式out-i_第11张图片

在“on”按钮和“off”按钮的过渡中,两个按钮都被重绘了,一个离开过渡的时候另一个开始进入过渡。这是 的默认行为 —— 进入和离开同时发生。

有时这很有效,例如当过渡项绝对位于彼此的 top 时:

Vue3官网-过度&动画(一)transition&animation、ease-out,cubic-bezier、过渡class enter-from JavaScript 钩子 过渡模式out-i_第12张图片

同时生效的进入和离开的过渡不能满足所有要求,所以 Vue 提供了过渡模式

  • in-out: 新元素先进行过渡,完成之后当前元素过渡离开。
  • out-in: 当前元素先进行过渡,完成之后新元素过渡进入。

TIP

很快就会发现 out-in 是你大多数时候想要的状态

现在让我们用 out-in 更新 on/off 按钮的转换:

<transition name="fade" mode="out-in">
  
transition>

Vue3官网-过度&动画(一)transition&animation、ease-out,cubic-bezier、过渡class enter-from JavaScript 钩子 过渡模式out-i_第13张图片

通过添加一个 attribute,我们修复了原来的过渡,而不必添加任何特殊 style。

我们可以用它来协调更具表现力的动作,例如折叠卡片,如下所示。实际上是两个元素在彼此之间转换,但是由于开始状态和结束状态的比例是相同的:水平为0,它看起来就像一个流体运动。这种轻描淡写对于真实的 UI 微交互非常有用:

Vue3官网-过度&动画(一)transition&animation、ease-out,cubic-bezier、过渡class enter-from JavaScript 钩子 过渡模式out-i_第14张图片

多个组件之间过渡

组件之间的过渡更简单 —— 我们甚至不需要 key 属性。相反,我们包裹了一个动态组件 :

<div id="demo">
  <input v-model="view" type="radio" value="v-a" id="a"><label for="a">Alabel>
  <input v-model="view" type="radio" value="v-b" id="b"><label for="b">Blabel>
  <transition name="component-fade" mode="out-in">
    <component :is="view">component>
  transition>
div>
const Demo = {
     
  data() {
     
    return {
     
      view: 'v-a'
    }
  },
  components: {
     
    'v-a': {
     
      template: '
Component A
'
}, 'v-b': { template: '
Component B
'
} } } Vue.createApp(Demo).mount('#demo')
.component-fade-enter-active,
.component-fade-leave-active {
     
  transition: opacity 0.3s ease;
}

.component-fade-enter-from,
.component-fade-leave-to {
     
  opacity: 0;
}

Vue3官网-过度&动画(一)transition&animation、ease-out,cubic-bezier、过渡class enter-from JavaScript 钩子 过渡模式out-i_第15张图片

你可能感兴趣的:(前端工程师1——汇总,前端工程师7——Vue,React,javascript,动画,vue.js)