理解vue中的过渡&动画

657 阅读1分钟

理解vue中的过渡&动画

最近两年在公司面对的业务都是pc后台管理系统的开发,极少会遇到要求增加动画来提升用户体验的需求,顶多就是加个loading,最近闲来无事继续看了看vue的开发文档,不得不说每次看都会有一些新的收获,今天就根据文档理解理解在vue中的过渡和动画

  • 过渡

bg.gif

简单的一个背景过渡,只需要在style上给需要改变的属性一个变量即可实现

<template>
  <div
    @touchmove="xCoordinate"
    :style="{ backgroundColor: `hsl(${x}, 80%, 50%)` }"
    class="movearea"
  >
    <h3>Move your mouse across the screen...</h3>
    <p>x: {{x}}</p>
  </div>
</template>
xCoordinate(e) {
  this.x = e.targetTouches[0].clientX
}

如此在改变x的值时就会动态的改变背景色

同样基于class的过渡,通过动态的改变class去改变状态。

  • 元素过渡

对于单元素过渡vue提供了一个组件<transition name=[name]>,同时提供了css钩子[name]-enter-from, [name]-enter-to, [name]-enter-active, [name]-leave-active分别代表进入前状态、进入后状态(固定状态),进入时、离开时(动画状态),

对于多元素状态例如列表该如何呢?

list.gif

list2.gif

类似如此的我们需要列表元素从底部渐入,vue提供了 <transition-group tag=[element-tag] name=[name]>, tag指的是包裹标签需要渲染成什么标签,如果不提供tag则默认不会渲染一个包裹元素,例如

<transition-group tag='ul'>
    <li></li>
</transition-group>

会被渲染成

<ul>
    <li></li>
</ul>

name 同样代表css钩子前缀

需要注意的是内部元素必须要有唯一的key,CSS 过渡的类将会应用在内部的元素中,而不是这个组/容器本身 接着我们来实现上面的gif图所示效果: html

<template>
  <transition-group name="list" tag="ul">
    <li class="li" v-for="(l, idx) in list"
       :key="l"
       :style="{ backgroundColor: `hsl(${l*100}, 80%, 50%)`}"
       @touchend="delItem(idx)"
    >{{l}}</li>
  </transition-group>
</template>

css:

.list-enter-from{
  opacity: 0;
  transform: translateY(100vh);
}
.list-leave-to{
  opacity: 0;
  transform: translateX(100vw);
}
.list-enter-active, .list-leave-active{
  transition: all .6s;
}
.list-leave-active{
  position: absolute;
}
.list-move{
  transition: transform 0.8s ease;
}

.li{
  width: 100vw;
  height: 40px;
  line-height: 40px;
}

js

export default{
  data() {
    return {
      list: []
    }
  },
  mounted() {
    this.sourceList = [1,2,3,4,5,6,7,8,9,10]
    this.startPush()
  },
  methods:{
    startPush() {
      if(this.sourceList.length){
        this.list.push(this.sourceList.shift())
        requestAnimationFrame(this.startPush)
      }
    },
    delItem(idx) {
      this.list.splice(idx, 1)
    },
  }
}

我们需要列表元素一个一个有先后顺序的从底部过渡到渲染位置,所以列表元素需要我们一个一个push进去,而不能给list直接赋值,所以这里用了requestAnimationFrame这个api 需要说明的是当我们删除单项的时候为了不让容器变得生硬我们需要在元素离开时将position设置为absolute来释放所占据的空间

.list-leave-active{
  position: absolute;
}