vue2.x之动画

在vue中动画分为两种,一种是过渡效果,一种是动画效果。这些动画效果都可以通过transition标签来实现。

进入/离开 & 列表过渡

1. 单元素/组件的过渡

对于这类过渡效果,我们主要是通过transition来实现的。

<template>
  <div id="app">
    <button @click="showFunc">动画效果</button>
    <transition name="fade">
      <div class="txt-wrapper" v-show="show">你好呀!</div>
    </transition>
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      show: true
    }
  },
  methods: {
    showFunc() {
      this.show = !this.show
    },
  },
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

.txt-wrapper {
  width: 500px;
  height: 100px;
  background-color: yellow;
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity .5s;
}

.fade-enter,
.fade-leave-to {
  opacity: 0;
}
</style>

上面代码可以实现淡入淡出的效果.

⏰ transition的机制

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

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

⏰ transition的六个class类

过程如下:

  • v-enter:定义进入过渡的开始状态。
  • v-enter-active:定义进入过渡生效时的状态。
  • v-enter-to:定义进入过渡的结束状态。
  • v-leave:定义离开过渡的开始状态。
  • v-leave-active:定义离开过渡生效时的状态。
  • v-leave-to:定义离开过渡的结束状态。

特别提醒:

  1. 如果你使用一个没有名字的 ,则 v-是这些类名的默认前缀。如果你使用了 ,那么v-enter会替换为 my-transition-enter。
  2. 这些类里面既可以使用css过渡,也可以使用css动画

⏰ transition可以自定义类名

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

  • enter-class
  • enter-active-class
  • enter-to-class
  • leave-class
  • leave-active-class
  • leave-to-class
<transition  
  name="custom-classes-transition"  
  enter-active-class="animated tada"  
  leave-active-class="animated bounceOutRight"  
>

⏰ transition中可以使用钩子

<transition
  v-on:before-enter="beforeEnter"
  v-on:enter="enter"
  v-on:after-enter="afterEnter"
  v-on:enter-cancelled="enterCancelled"

  v-on:before-leave="beforeLeave"
  v-on:leave="leave"
  v-on:after-leave="afterLeave"
  v-on:leave-cancelled="leaveCancelled"
>
</transition>

这些钩子是函数,和其他的methods中的函数一起定义,可以设置动画,也可以执行其他的操作。

2. 初始渲染的过渡

初始渲染渲染可以通过transition的appear属性来实现,appear = true 表示在页面 第一次加载的时候就使用动画。

<transition appear name="fade">
    <div class="txt-wrapper" v-show="show">你好呀</div>
</transition>  

3. 多个元素的过渡

多个元素的过渡需要给不同元素之间加上key属性, 并且要使用transition-group

<template>
  <div class="hello">
    <button @click="showFunc">动画效果</button>
    <transition-group appear name="fade">
      <div class="txt-wrapper" v-show="show" key="hi">你好呀</div>
      <div class="txt-wrapper" v-show="!show" key="hello">我是神秘人</div>
    </transition-group>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      show: true
    }
  },
  methods: {
    showFunc() {
      this.show = !this.show;
    }
  }
}
</script>

<style scoped>
.txt-wrapper {
  width: 500px;
  height: 100px;
  background-color: yellow;
}
.fade-enter-active, .fade-leave-active {
  transition: opacity .5s;
}
.fade-enter, .fade-leave-to {
  opacity: 0;
}
</style>

4. 多个组件的过渡

多个组件的过渡也要使用transition-group, 但是不需要使用key。还要使用component。

<template>
  <div class="hello">
    <button @click="showFunc">动画效果</button>
    <transition name="fade">
      <component v-bind:is="view"></component>
    </transition>
  </div>
</template>

5. 列表过渡

vue中关于transition-group的定义如下:

  • 不同于 ,它会以一个真实元素呈现:默认为一个 。你也可以通过 tag attribute 更换为其他元素。
  • 过渡模式不可用,因为我们不再相互切换特有的元素。
  • 内部元素总是需要提供唯一的 key attribute 值。
  • CSS 过渡的类将会应用在内部的元素中,而不是这个组/容器本身。
<template>
  <div class="hello">
    <button @click="add">添加</button>
    <button @click="remove">删除</button>
    <transition-group appear name="fade">
      <span v-for="(item, index) in arr" :key="index" class="txt-wrapper">
        {{item}}
      </span>
    </transition-group>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      arr: [1,2,3,4,5,6,7]
    }
  },
  methods: {
    add() {
      let len = this.arr.length;
      this.arr.push(this.arr[len - 1] + 1);
    },
    remove() {
      this.arr.pop();
    }
  }
}
</script>

<style scoped>
.txt-wrapper {
  width: 500px;
  height: 100px;
  background-color: yellow;
}
.fade-enter-active, .fade-leave-active {
  transition: opacity .5s;
}
.fade-enter, .fade-leave-to {
  opacity: 0;
}
</style>

posted on 2024-07-10 17:35  梁飞宇  阅读(8)  评论(0)    收藏  举报