百科狗-知识改变命运!
--

Transition 过度 - css 属性 transition、animation、transform - vue 内置组件

百变鹏仔12个月前 (11-21)阅读数 13#技术干货
文章标签动画

Transition 过度

Vue 提供了两个内置组件,可以帮助你制作基于状态变化的过渡和动画:

  • :在一个元素或组件,进入和离开 DOM 时,应用动画。
  • :在一个元素或组件,在v-for列表中,被插入、移动或被移除时,应用动画。

除了这两个组件,我们也可以通过其他技术手段来应用动画,比如切换 CSS 类或用状态绑定样式来驱动动画。这些其他的方法会在动画技巧章节中展开介绍到。

组件

是一个内置组件,这意味着它在任意别的组件中都可以被使用,无需注册。它可以在通过默认插槽传递给它的元素或组件上,应用进入和离开动画。进入或离开可以由以下其中一种触发:

  1. v-if所触发的切换
  2. v-show所触发的切换
  3. 由特殊元素切换的动态组件

以下是最基本用法的示例:

Toggle 

hello

/* 下面我们会解释这些类是做什么的 */
.v-enter-active,
.v-leave-active { transition: opacity 0.5s ease;
}

.v-enter-from,
.v-leave-to {
  opacity: 0;
}
仅支持单个元素或组件作为其插槽内容。如果内容是一个组件,这个组件必须仅有一个根元素。

当一个组件中的元素被插入或移除时,会发生下面这些事情:

  • Vue 会自动检测目标元素是否应用了 CSS 过渡或动画。如果是,则一些 CSS 过渡类会在适当的时机被添加和移除。
  • 如果有作为监听器的 JavaScript 钩子,这些钩子函数会在适当时机被调用。
  • 如果没有探测到 CSS 过渡或动画、没有提供 JavaScript 钩子,那么 DOM 的插入、删除操作将在浏览器的下一个动画帧上执行。


基于 CSS 的过渡

过渡 CSS 类

一共有 6 个应用于进入与离开过渡效果的 CSS 类。


  • v-enter-active:进入动画的生效状态,应用于整个进入动画阶段。这个 CSS 类,在元素被插入之前添加,在过渡/动画完成之后移除。这个类可以用来定义,进入动画的持续时间、延迟与速度曲线类型。
  • v-enter-from:进入动画的起始状态。这个 CSS 类,在元素插入之前添加,在元素插入完成后的下一帧,移除。
  • v-enter-to:进入动画的结束状态。这个 CSS 类,在元素插入完成后的下一帧,被添加(也就是v-enter-from被移除的同时),在过渡/动画完成之后移除。
  • v-leave-active:离开动画的生效状态,应用于整个离开动画阶段。在离开过渡效果被触发时立即添加,在过渡/动画完成之后移除。这个类可以用来定义,离开动画的持续时间、延迟与速度曲线类型。
  • v-leave-from:离开动画的起始状态,在离开过渡效果被触发时,立即添加,在一帧后被移除。
  • v-leave-to:离开动画的结束状态。这个 CSS 类,在一个离开动画被触发后的下一帧,被添加(也就是v-leave-from被移除的同时),在过渡/动画完成之后移除。

v-enter-active和v-leave-active给了我们为进入和离开动画指定不同速度曲线的能力。


为过渡命名

可以通过一个name prop 来声明一种过渡:

 ...... 

对于一个有名字的过渡,它的过渡相关 CSS 类会以其名字而不是v作为前缀。举个例子,上面被应用的 CSS 类将会是fade-enter-active而不是v-enter-active。这个fade过渡的 CSS 类将会是这样:

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s ease;
} .fade-enter-from,
.fade-leave-to {
  opacity: 0;
}


CSS 的 transition

一般都会搭配原生 CSS 过渡一起使用,正如你在上面的例子中所看到的那样。这个transition CSS 属性是一个简写形式,使我们可以一次定义一个过渡的各个方面,包括需要执行动画的属性、持续时间和速度曲线。

下面是一个更高级的例子,使用不同的持续时间和速度曲线来过渡多个属性:

 

hello

/* 进入和离开动画可以使用不同 持续时间和速度曲线。 */
.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;
}


CSS 的 animation

原生 CSS 动画和 CSS trasition 的应用方式基本上是相同的,只有一点不同,那就是*-enter-from不是在元素插入后立即移除,而是在一个animationend事件触发时被移除。

对于大多数的 CSS 动画,我们可以简单地在*-enter-active和*-leave-active类下面声明它们。下面是一个示例:

 

Hello here is some bouncy text!

.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);
  }
}


自定义过渡类

你也可以向传递以下的props来指定自定义的过渡类:

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

你传入的这些类会覆盖相应阶段的默认类名。这个功能在你想要在 Vue 的动画机制下集成其他的第三方 CSS 动画库时非常有用,比如Animate.css:

 

hello


同时使用 transition 和 animation

Vue 需要附加事件侦听器,以便知道过渡何时结束。可以是transitionendanimationend,这取决于你所应用的 CSS 规则。如果你仅仅使用二者其中之一,Vue 可以自动探测到正确的类型。

然而在某些场景中,你或许想要在同一个元素上同时使用它们两个,举个例子,触发了一个 CSS 动画的同时,由于副作用触发了另一个 CSS 过渡。此时你需要显式地传入type prop 来声明,告诉 Vue 需要关心哪种类型,传入的值是animation或transition:

...


深层级过渡与显式过渡时间

尽管过渡类仅能应用在的直接子元素上,我们还是可以使用深层级的 CSS 选择器,使深层级的元素发生过渡。

 
Hello
/* 应用于深层级元素的规则 */
.nested-enter-active .inner,
.nested-leave-active .inner {
  transition: all 0.3s ease-in-out;
}

.nested-enter-from .inner,
.nested-leave-to .inner {
  transform: translateX(30px);
  opacity: 0;
}

我们甚至可以在深层级的元素上添加一个过渡延迟,这会创建一个交错进入动画序列:

/* 延迟进入深层级元素以获得交错效果 */
.nested-enter-active .inner {
  transition-delay: 0.25s;
}

然而,这会带来一个小问题。默认情况下,组件会通过监听过渡根元素上的第一个transitionend或者animationend事件来尝试自动判断过渡何时结束。而在深层级的过渡中,期望的行为应该是等待所有内部元素的过渡完成。

在这种情况下,你可以通过向组件传入duration prop 来显式指定的过渡持续时间(以毫秒为单位)。总持续时间应该匹配延迟加上内部元素的过渡持续时间:

...

如果有必要的话,你也可以用对象的形式传入,分开指定进入和离开所需的时间:

...


性能考量

你可能注意到我们上面例子中展示的动画所用到的属性大多是transformopacity之类的。用这些属性制作动画非常高效,因为:

  • 他们在动画过程中不会影响到 DOM 结构,因此每一个动画帧都不会触发昂贵的 CSS 布局重新计算。
  • 大多数的现代浏览器都可以在执行transform动画时利用 GPU 进行硬件加速。

相比之下,像height或者margin这样的属性会触发 CSS 布局变动,因此执行它们的动画效果更昂贵,需要谨慎使用。我们可以在CSS-Triggers这类的网站查询哪些属性会在执行动画时触发 CSS 布局变动。 ...

在有了:css="false"后,我们就全权自己负责控制什么时候过渡结束了。这种情况下对于@enter@leave钩子来说,回调函数done()就是必须的。否则,钩子将被同步调用,过渡将立即完成


可重用过渡

得益于 Vue 的组件系统,过渡是可以被重用的。要创建一个可被重用的过渡,我们需要为组件创建一个包装组件,并向内传入插槽内容:

  /*
  必要的 CSS...
  注意:避免在这里使用 
  因为那不会应用到插槽内容上
*/ 

Transition 过度 - css 属性 transition、animation、transform - vue 内置组件

现在 MyTransition 可以在导入后像内置组件那样使用了:

 
Hello


出现时过渡

如果你想在某个节点初次渲染时应用一个过渡效果,你可以添加appear attribute:

 ... 


元素间过渡

除了通过v-if/v-show切换一个元素,我们也可以通过v-if/v-else/v-else-if在几个组件间进行切换过:

 Edit
  Save
  Cancel 


过渡模式

在之前的例子中,进入和离开的元素都是在同时开始动画的,并且我们必须将它们设为position: absolute以避免二者同时存在时出现的布局问题。

然而,在某些场景中这可能不是个好的方案,或者并不能符合行为预期。我们可能想要先执行离开动画,然后在其完成之后再执行元素的进入动画。手动编排这样的动画是非常复杂的,好在我们可以通过向传入一个mode prop 来实现这个行为:

 ... 

也支持mode="in-out",虽然这并不常用。


组件间过渡

也可以用在动态组件之间:

 


动态过渡

的props(比如name)也可以是动态的!这让我们可以根据状态变化动态地应用不同类型的过渡:

 Fallthrough

当你使用 Vue 的过渡类约定规则定义了 CSS 过渡/动画,并想在它们之间切换时,这可能很有用。

你也可以根据你的组件的当前状态在 JavaScript 过渡钩子中应用不同的行为。在此篇的最后,我们可以得出结论,创建动态过渡的终极方式是创建可重用的过渡组件,这些组件接受prop来改变过渡的性质。现在在编写动画时,就真的只有你想不到,没有做不到的了。

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)