SHO酱的Blog

SHO酱的Blog

Vue中的过渡和动画

2021-05-13

神奇的transition标签

transition标签用于实现给被包裹在里面的节点元素显示/隐藏(添加/删除)时添加过度动画,在transition标签中跟template标签一样里面不能并列添加多个子元素。
通过transition实现过渡动画的过程十分神奇,只要用transition包裹起来,Vue就会自动给其子元素添加指定的显示/隐藏动画效果。

transition和animation到底有什么区别

字面含义 transition 过渡,animation 动画;

  • 过渡:从一个位置到另一个位置,从一个角度到另一个角度,从一个状态到另一个状态;
  • 动画:一个连贯的动作节点的集合,可能是一个/多个位置的变化,或一个/多个角度的变化等等。

transition 是样式值的变化的过程,只有开始和结束;
animation 也叫关键帧,通过和 keyframe 结合可以设置中间帧的一个状态。

用法

transition标签中既可以使用 transition 也可以使用 animation 。

Vue的内容

<template>
    <div>
        <transition name="fade">
            <div v-show="isShow" class="el-menu-demo">
                <el-menu ...>
                    ...
                </el-menu>
            </div>
        </transition>
        <div id="top-top" ref="toptop">
    </div>
</template>

<script>
// 自定义组件判断页面元素是否显示
import { isElementNotInViewport} from "./utils/elementNotInViewport";
export default {
  data() {
    return {
      isShow: true
    }
  },
  methods: {
    // 滑动出现底部按钮
    handleScroll() {
      if (isElementNotInViewport(this.$refs.toptop)) {
        this.isFixed = true;
      } else {
        this.isFixed = false;
      }
    },
    ...
  },
  mounted() {
    this.$nextTick(() => {
      let timer;
      window.addEventListener("scroll", () => {
        if (timer) {
          clearTimeout(timer);
        }
        timer = setTimeout(() => {
          this.handleScroll();
        }, 200);
      });
      this.handleScroll();
    });
  }
}
</script>

<style>
.fade-enter-active, .fade-leave-active {
    /* transition: opacity .5s; */
    transition-property: opacity,transform;
    transition-duration: .15s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
    opacity: 0;
    transform: translateY(0) translateY(-100%);
}
</style>

elementNotInViewport.js的内容

/**
 * 判断某个原生DOM元素是否不在屏幕可见区内
 * @param {*} el 原生DOM元素
 */
const isElementNotInViewport = function(el) {
    let rect = el.getBoundingClientRect();
    return (
        rect.top >= (window.innerHeight || document.documentElement.clientHeight) ||
        rect.bottom <= 0
    );
};
export { isElementNotInViewport};

效果GIF动画

由于 gif 的帧数问题,过渡效果不太明显[汗]

参考

Vue官网 - 进入/离开 & 列表过渡
animation 和 transition 的区别