用Transition组件犯迷糊?看我这篇给你安排的明明白白的

1,374 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情

transition组件作为Vue的内置组件,可以用来实现组件的过渡效果。在Vue中,过渡效果是通过CSS来实现的,所以过渡不是如何使用组件,而是如何写CSS。

本文将介绍如何使用transition组件实现组件的过渡效果。

1. 认识transition组件

vue中提供了两个用于实现过渡效果的组件:transitiontransition-group。其中,transition 组件用于实现单个组件的过渡效果,而transition-group组件用于实现多个组件的过渡效果。

transition-group组件的使用方法与transition组件类似,transition组件用于单个组件的过渡效果,而transition-group 组件用于多个组件的过渡效果,学会了一个就相当于两个都掌握了。

transition组件的使用方法如下:

<template>
  <transition>
    <div v-if="show">Hello</div>
  </transition>
  <button @click="show = !show">Toggle</button>
</template>

<script>
import { defineComponent, ref } from 'vue';

export default defineComponent({
  setup() {
    const show = ref(true);

    return {
      show
    };
  },
});
</script>

<style>
.v-enter-active,
.v-leave-active {
  transition: opacity .5s;
}
.v-enter,
.v-leave-to {
  opacity: 0;
}
</style>

上面的代码是官网的一个例子transition,可以先官网看看,接下来我们来分析它具体的运行机制。

2. 运行机制

transition的英文意思是过渡,过渡是什么呢?过渡是指在一个状态到另一个状态的过程中,会有一个过程,这个过程就是过渡。

vue中一共有6个应用于进入和离开的过渡类名,下面是官网描述的截图,写的很清楚,我就不过度解读了: image.png

我这里对其进行总结分类解释一下:

  1. 过渡一共有两个状态,一个是进入(enter),一个是离开(leave)。
  2. 进入和离开细分为三个阶段,插入(from),激活(active),离开(to)。
  3. 模式分为三种,官方描述只有两种,一种是in-out,一种是out-in,还有一种是默认效果,就是进入和离开的过渡效果同时进行。

上面的分类1和2是固定的,过渡一定只有进入和离开,进入和离开一定有三个状态,顺序一定是固定的,重要的是模式,来看一下代码示例:

<template>
     <transition>
      <div :key="show" style="background: pink;">默认-{{ show }}</div>
    </transition>

     <transition mode="in-out">
      <div :key="show" style="background: blue;">in-out-{{ show }}</div>
    </transition>

     <transition mode="out-in">
      <div :key="show" style="background: green;">out-in-{{ show }}</div>
    </transition>

    <button @click="show = !show">Toggle</button>
</template>

<script>
import { defineComponent, ref } from 'vue';

export default defineComponent({
  setup() {
    const show = ref(true);
    
    return {
      show
    };
  },
});
</script>

<style>
  div {
    margin: 10px;
    width: 100px;
    height: 50px;
    line-height: 50px;
    background: pink;
    text-align: center;
    float: left;
  }
.v-enter-active, .v-leave-active {
  transition: opacity 2s;
}

.v-enter-to {
  opacity: 0;
}

.v-enter-from {
  opacity: 1;
}

 .v-leave-to {
  opacity: 1;
}


 .v-leave-from {
  opacity: 0;
}
</style>
      

QQ录屏20220929111027.gif

示例效果可能看着不怎么明显,建议移除opacity属性尝试一下没有过渡效果的状态切换。

上面的示例可以看到:

  • 默认:两种过渡同时进行。
  • in-out:进入的过渡先进行,离开的过渡后进行。
  • out-in:离开的过渡先进行,进入的过渡后进行。

我们一般用的最多的是out-in,因为其他的两个让我们看着有点迷惑,只有out-in看起来最符合我们的直觉,但是另外两个就没有用武之地吗?

3. 实践

上面讲到的只是浅显的基础知识,现在要将这些基础知识用于实践,我要将这三种过渡模式都用到实际场景中:

上面只是简简单单的写了一些小效果,这个并不能让人有太多的成就感,你以为它就只有这么多吗?

4. 进阶

上面只是基础,transition组件的基础,他的本质就是在不同的阶段加入不同的css选择器,如果我们再加入一些选择器的基础,再配合transition组件的其他属性,我们就可以做出更多的效果。

4.1. 操作伪类

<template>
  <div class="box">
    <transition name="before-pseudo" mode="out-in" :duration="1000">
      <div :key="show" @click="show = !show">
        点我切换
      </div>
    </transition>
  </div>
</template>

<script>
import {defineComponent, ref} from 'vue';

export default defineComponent({
  setup() {
    const show = ref(true);

    return {
      show
    };
  },
});
</script>

<style>
div.box {
  width: 100px;
  height: 50px;
  position: relative;
  margin: 10px;
  overflow: hidden;
}

div.box div {
  position: absolute;
  left: 0;
  top: 0;
  width: 100px;
  height: 50px;
  line-height: 50px;
  background: pink;
  text-align: center;
}
.before-pseudo-enter-active,
.before-pseudo-leave-active {
  z-index: 9;
}

.before-pseudo-leave-active::before,
.before-pseudo-enter-active::before {
  content: " ";
  display: block;
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  inset: 0 0 0 0;
  background: hsl(200 100% 80%);
  z-index: -1;
  transition: transform 1s ease;
}

.before-pseudo-leave-from::before,
.before-pseudo-enter-to::before {
  transform: scaleX(0);
  transform-origin: bottom right;
}

.before-pseudo-leave-to::before,
.before-pseudo-enter-from::before {
  transform: scaleX(1);
  transform-origin: bottom left;
}
</style>

上面的效果参考了codepan 这里

操作伪类因为transition组件无法检测到过渡的执行时间,所以需要组件上需要传递执行时间的参数,这里我传递了1000ms,这样就可以让伪类的过渡效果和transition组件的过渡效果同步。

都可以操作伪类,当然也可以操作子元素,这里有个伪元素的示例了,子元素的操作就留给大家自己去尝试了。

4.2. animation动画

<template>
  <div class="box">
    <transition name="bounce">
      <div :key="show" @click="show = !show">
        点我切换
      </div>
    </transition>
  </div>
</template>

<script>
import {defineComponent, ref} from 'vue';

export default defineComponent({
  setup() {
    const show = ref(true);

    return {
      show
    };
  },
});
</script>

<style>
div.box {
  width: 100px;
  height: 50px;
  position: relative;
  margin: 10px;
  overflow: hidden;
}

div.box div {
  position: absolute;
  left: 0;
  top: 0;
  width: 100px;
  height: 50px;
  line-height: 50px;
  background: pink;
  text-align: center;
}
.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);
  }
}
</style>

上面的效果参考了官网

这个上面使用了cssanimation属性,这就引出了transition的另一个属性type,有两个可选值transition | animation.

这个属性通常情况下是不需要设置的,内部默认会自动检测执行时间最长的一个。

4.3. appear属性

这个属性本其实不用讲的,就是在组件一开始创建的时候就加一个进入的过渡效果,这个属性默认是false

就上面的几个例子,你把页面刷新是没有任何过渡效果的,你加上这个属性,在刷新就有效果了。

总结

transition组件其实并不复杂,只需要了解他们的过渡过程就好了,过渡开始有一个起点,从这个起点过渡到终点,这就是一个过渡效果,然后再配合transition组件提供的模式,就可以实现各种各样的过渡效果了。