Vue简单实例——过渡和动画

前提条件:

在显示Vue封装的效果之前,首先我们演示一下,在不经过Vue实例的动画效果,即使用CSS样式进行动画的制作

演示效果:

 代码实现:

<template>
  <div>
    <button type="button" @click="show = !show">动画</button>
<!--      在这里将应用什么样的样式手动的使用类名绑定在DOM上,实现某一种特定的样式-->
    <h1 v-show="show" class="com">你好世界</h1>
  </div>
</template>

<script>
export default {
  name: "animation_demo",
  data(){
    return {
      show:true
    }
  }

}
</script>

<style scoped>
h1{
  background-color: orange;
}
/*动画效果的类名*/
.com{
  /*表示执行的动画效果,后面的属性表示动画将在1S内完成*/
  animation: translate 1s;
}
.go{
  /*表示执行的动画效果,后面的属性表示动画将在一秒内完成,并且反转动画的效果*/
  animation: translate 1s reverse;
}
/*使用@keyframes来创建一个动画,后面跟着的字符串就是动画的名字,from表示开始,to表示结束*/
/*这是一个简单的动画,*/
@keyframes translate {
  from{
    /*CSS transform 属性允许你旋转,缩放,倾斜或平移给定元素。*/
    /*其中translateX就表示按X轴,也就是横向的平移这个元素,平移百分之一百也就是完全的向左移除屏幕*/
    /*如果是正数则表示向右移除*/
    transform: translateX(-100%);
  }
  to{
    /*表示动画结束时的样式,动画结束时,平移百分之0也就是恢复原位,整体的动画效果表示为从屏幕左边逐渐平移到屏幕中间*/
    transform: translateX(0);
  }
}
</style>

可以看到,在不使用Vue封装的动画的前提下,也是可以实现动画效果的,只不过需要使用回调方法进行不同动画类的切换,比较的麻烦,所以Vue封装了一个可以来回切换的动画效果

Vue对动画进行的封装:

在使用Vue进行动画封装的时候,首先需要对要进行动画的DOM使用transition标签进行包裹,并且不再手动的使用class指定动画的对象,而由Vue在合适的时候调用合适的动画,那么Vue怎么知道在何时调用什么样式呢?这里就需要对动画类的名字进行说明了,在之前,我们给动画执行类的名字设定的是com和go,但是在Vue中,如果你想让它智能的选择使用何种动画,就需要使用Vue认识的名字,写作:v-enter-active,表示进入的动画。v-leave-active,表示退出的动画

演示效果:

 代码实现:

<template>
  <div>
    <button type="button" @click="show = !show">动画</button>
    <transition>
<!--      之前使用什么样的动画样式需要手动的更改,现在则由Vue帮我们选择,所以这里就不需要写class属性了-->
      <h1 v-show="show">你好世界</h1>
    </transition>
  </div>
</template>

<script>
export default {
  name: "animation_demo",
  data(){
    return {
      show:true
    }
  }

}
</script>

<style scoped>
h1{
  background-color: orange;
}
/*动画效果的类名,之前是随意的设定,现在需要修改为Vue可以只能识别的类名*/
.v-enter-active{
  /*表示执行的动画效果,后面的属性表示动画将在1S内完成*/
  animation: translate 1s;
}
.v-leave-active{
  /*表示执行的动画效果,后面的属性表示动画将在一秒内完成,并且反转动画的效果*/
  animation: translate 1s reverse;
}
/*使用@keyframes来创建一个动画,后面跟着的字符串就是动画的名字,from表示开始,to表示结束*/
/*这是一个简单的动画,*/
@keyframes translate {
  from{
    /*CSS transform 属性允许你旋转,缩放,倾斜或平移给定元素。*/
    /*其中translateX就表示按X轴,也就是横向的平移这个元素,平移百分之一百也就是完全的向左移除屏幕*/
    /*如果是正数则表示向右移除*/
    transform: translateX(-100%);
  }
  to{
    /*表示动画结束时的样式,动画结束时,平移百分之0也就是恢复原位,整体的动画效果表示为从屏幕左边逐渐平移到屏幕中间*/
    transform: translateX(0);
  }
}
</style>

这里有一个小的注意点就是动画播放的时机,实际上,在我们点击按钮,使show的值变成false,DOM对象消失之前,他会执行退出的动画,而再次点击按钮,使show的值变成true,在DOM对象出现之前,他会执行出现的动画,也就是说,是先改变的值,再执行动画,最后DOM对象完整的出现在页面中。

四个小细节:

transition并不会被渲染成标签:

在我们使用transition标签的时候,在浏览器打开检查页面,可以看到在h1标签也就是我们的绑定动画样式的标签并没有被标签包裹:

说明Vue在最终解析的时候,并没有将transition标签渲染出来 

transition的name属性:

transition可以具有一个name属性,表示这个动画的名字,如果你给一个transition标签添加了一个name属性,那么在使用类名的时候,就不能写v-enter-active了,需要改成:name属性值-enter-active,因为v是当没有name属性时默认使用的,如果由name则需要进行对应的修改

例如:这里添加了一个name属性

 那么,在使用样式的类名的时候,就需要修改成:

 其实name属性存在的意义更多的是在于,当页面中存在多个需要不同动画的元素时,使用name属性可以精准的给每一个元素添加对应的属性

 appear属性:

在我们刷新页面的时候可以发现,在页面第一次被加载出来的时候,元素是没有进场动画的,如果想让元素在第一次加载页面的时候就出现动画,需要在transition标签上加入一个appear属性:

 这样就可以在第一次加载页面的时候也出现动画了

动画的实现并不是Vue所关心的:

 在上图中,是由具体实现动画的类去实现动画,而Vue在意的只是识别相应的实现动画的类的类名,而动画的实现并不是Vue的操作范围,说明Vue不跟动画进行对话,而是跟样式的类名进行对话。

Vue对过渡进行的封装:

在上个案例中,我们看到了Vue对于动画的封装,而现在,我们开始看Vue对于过渡效果的封装,我们分为三个阶段开始慢慢的深入:

第一阶段:

在之前的动画的案例中,我们是定义了一个动画效果,并在合适的时候使用了这个效果,但是我们现在要使用过渡,所以定义动画和使用动画的过程就不再需要了,取而代之的是两个新的类:tran-enter,进入的起点和tran-enter-to,进入的终点,根据这两个类的描述可以得知,这两个类是定义过渡开始的关键帧的,也就是开始的位置和结束的位置,所以我们在这两个类中定义过渡开始的起点和终点,但是只有关键帧是不够用的,还需要定义动画的持续时间和运动效果,那么现在没有active了,就遵循,给谁用过渡,就在谁那里定义效果。所以,在本案例中是给h1标签使用过渡,就在h1标签中定义了过渡动画。具体的效果如下:

 代码实现:

<template>
  <div>
    <button type="button" @click="show = !show">动画</button>
    <transition name="tran" appear>
      <h1 v-show="show">你好世界</h1>
    </transition>
  </div>
</template>

<script>
export default {
  name: "animation_demo",
  data(){
    return {
      show:true
    }
  }

}
</script>

<style scoped>
h1{
  background-color: orange;
  transition: 1s linear;
}
/*进入的起点*/
.tran-enter{
  transform: translateX(-100%);
}
/*进入的终点*/
.tran-enter-to{
  transform: translateX(0);
}
</style>

第二阶段:

在效果图中可以看到,进入时的效果体现出来了,但是退出时的效果则是在等待了一秒后直接消失,并没有显示出移走的效果,所以就需要用到我们的另外两个类来达成离开时候的效果:tran-leave,离开时的起点和rean-leave-to,离开时的终点,在添加对应的类之后,效果如下:

 代码实现:

<template>
  <div>
    <button type="button" @click="show = !show">动画</button>
    <transition name="tran" appear>
      <h1 v-show="show">你好世界</h1>
    </transition>
  </div>
</template>

<script>
export default {
  name: "animation_demo",
  data(){
    return {
      show:true
    }
  }

}
</script>

<style scoped>
h1{
  background-color: orange;
  transition: 1s linear;
}
/*进入的起点*/
.tran-enter{
  transform: translateX(-100%);
}
/*进入的终点*/
.tran-enter-to{
  transform: translateX(0);
}
/*离开的起点*/
.tran-leave{
  transform: translateX(0);
}
/*离开的终点*/
.tran-leave-to{
  transform: translateX(100%);
}
</style>

第三阶段:最后一个阶段主要是对代码的优化部分

在第二阶段的时候,可以看到基本的效果已经出现了,但是CSS代码的部分过于冗长,完全没有体现出Vue封装代码的精减性,所以我们可以尝试精简一下代码,可以发现,在CSS代码的部分,进入的起点,就等于离开的终点;而进入的终点,就等于离开的起点。这是一个循环,既然知道这些类的内容都是一样的,那么就可以将这些类写成一个。并且在应用过渡的时候,我们一开始说,谁用过渡就给谁添加过渡,但是之前的做法容易混淆元素样式和过渡动画,所以我们推荐将过渡的效果单独写进一个类选择器中,那么这个类选择器就是我们之前用过的两个active,那么整理整合之后的代码如下:

<template>
  <div>
    <button type="button" @click="show = !show">动画</button>
    <transition name="tran" appear>
      <h1 v-show="show">你好世界</h1>
    </transition>
  </div>
</template>

<script>
export default {
  name: "animation_demo",
  data(){
    return {
      show:true
    }
  }

}
</script>

<style scoped>
h1{
  background-color: orange;
}
/*进入的起点,离开的终点*/
.tran-enter,.tran-leave-to{
  transform: translateX(-100%);
}
/*进入的终点,离开的起点*/
.tran-enter-to,.tran-leave{
  transform: translateX(0);
}
/*将过渡动画从元素样式中分离出来,单独写成一个类*/
.tran-enter-active,.tran-leave-active{
  transition: 1s linear;
}
</style>

小细节:

在我按下按钮启动动画的时候,在控制台查看源代码的时候,你会发现在h1标签,也就是我应用过渡的元素,出现了两个样式:

 分别是:.tran-leave-active和.tran-leave-to,而我们再次点击的时候,只会出现.tran-enter-active和.tran-enter-to两个类,但是我们在定义的时候,一共定义了六个类,这里只看到了两个,还有两个类为什么没有看到?

其实在过渡的过程中,.tran-enter和.tran-leave这两个类,只是定义动画开始的一瞬间的状态,在过度开始的瞬间这两个类就在被应用一帧之后就被删除了,这一瞬间我们是无法看见的,但是看不见不代表没有,如果你不写,那妥妥的报错。

多个元素的过渡:

当我们在使用transition标签的时候,内部只能有一个标签,也就是说一个transition标签只能有一个应用了过渡样式的标签,而在有些时候,我们需要给多个标签添加样式,这时候就需要使用一个新的标签:transition-group,来包裹多个过渡。并且需要给每一个标签添加一个唯一的key值,演示效果如下:

代码实现: 

<template>
  <div>
    <button type="button" @click="show = !show">动画</button>
<!--    使用一个新的标签将多个过渡动画标签包裹起来-->
    <transition-group name="tran" appear>
<!--      并且给每一个标签添加一个唯一的key值-->
      <h1 v-show="show" key="1">你好世界</h1>
      <h1 v-show="show" key="2">你好世界</h1>
    </transition-group>
  </div>
</template>

<script>
export default {
  name: "animation_demo",
  data(){
    return {
      show:true
    }
  }

}
</script>

<style scoped>
h1{
  background-color: orange;
}
/*进入的起点,离开的终点*/
.tran-enter,.tran-leave-to{
  transform: translateX(-100%);
}
/*进入的终点,离开的起点*/
.tran-enter-to,.tran-leave{
  transform: translateX(0);
}
/*将过渡动画从元素样式中分离出来,单独写成一个类*/
.tran-enter-active,.tran-leave-active{
  transition: 1s linear;
}
</style>

 这种场景主要应用于当我们给列表应用动画的时候,比如ul或ol列表标签,或许有人会认为,既然transition标签只能包裹一个标签,那么将多个标签封装在一个div标签内不也能实现效果吗?但是如果我们有一个新的需求,即两个标签需要应用不同的样式,这时候,包裹成一个div的做法就没有那么灵活了,比如下面的展示效果:

代码实现: 

<template>
  <div>
    <button type="button" @click="show = !show">动画</button>
<!--    使用一个新的标签将多个过渡动画标签包裹起来-->
    <transition-group name="tran" appear>
<!--      在上一个案例的基础上,对内容显示的变量进行取反,就可以显示交错显示的效果-->
      <h1 v-show="!show" key="1">你好世界</h1>
      <h1 v-show="show" key="2">你好世界</h1>
    </transition-group>
  </div>
</template>

<script>
export default {
  name: "animation_demo",
  data(){
    return {
      show:true
    }
  }

}
</script>

<style scoped>
h1{
  background-color: orange;
}
/*进入的起点,离开的终点*/
.tran-enter,.tran-leave-to{
  transform: translateX(-100%);
}
/*进入的终点,离开的起点*/
.tran-enter-to,.tran-leave{
  transform: translateX(0);
}
/*将过渡动画从元素样式中分离出来,单独写成一个类*/
.tran-enter-active,.tran-leave-active{
  transition: 1s linear;
}
</style>

 集成第三方动画:以Animate为案例

首先我们来到npm网站查看这个库如何使用:

 动画 - npm (npmjs.com)

我们还可以查看这个动画库的官网,在他的官网中明确写明了如何使用以及查看样式:

动画.css |CSS动画的跨浏览器库。 (animate.style)

 这些基本使用和进阶使用都在官网中有明确的介绍,那么具体的使用可以按照下面的流程:

首先可以下载,也可以使用CDN引入,然后将transition的name属性修改为:

animate__animated animate__bounce

 然后添加两个新的属性:enter-active-class和leave-active-class用来定义进入的动画和离开的动画,就不再需要让我们自己定义和修改了,展示效果如下:

 代码实现:

<template>
  <div>
    <button type="button" @click="show = !show">动画</button>
    <transition-group
        appear
        name="animate__animated animate__bounce"
        enter-active-class="animate__rubberBand"
        leave-active-class="animate__hinge"
    >
      <h1 v-show="show" key="2">你好世界</h1>
    </transition-group>
  </div>
</template>

<script>
export default {
  name: "animation_demo",
  data(){
    return {
      show:true
    }
  }

}
</script>

<style scoped>
h1{
  background-color: orange;
}
</style>

这里只是展示了两个基本的效果,他还有很多的好看的效果,各位可以尝试多多使用。值得注意的是,在我们使用不同的引入方式的时候,CDN的方式,需要放在HTML页面中,import导入的方式,需要放置在组件中,一定要分辨这两个的关系。

课本上的简单案例:

<template>
  <div>
    <button type="button" @click="show = !show">点击切换效果</button>
    <transition name="fade">
      <p v-show="show">你好世界</p>
    </transition>
  </div>
</template>

<script>
export default {
  name: "transitionDemo",
  data(){
    return {
      show:true
    }
  },
}
</script>

<style scoped>
/*当动画进入的时候的状态 离开过渡的时候的状态*/
  .fade-enter,.fade-leave-to{
    opacity:0
  }
  /*动画进入时的样式和动画离开时的样式*/
  .fade-enter-active,.fade-leave-active{
    transition: opacity .5s;
  }
</style>
<!--
简单的介绍:
过渡是指在图像消失和出现的时候进行的平滑过渡特效
在本案例中,图像的消失和出现是由v-show的值来决定的,当我们按下按钮的时候,原本为true的值变成了false,原本应该被显示的图像消失了
但是在消失之前,会先播放实现设定好的动画,在本案例中的动画的体现就是透明度的变化。
在消失的时候从不透明到完全透明,在出现的时候从完全透明到不透明的过渡。

因为动画开始和结束时的状态是一样的,所以.fade-enter,.fade-leave-to这两个类可以写在一起
而且动画进入和离开的样式是一样的,所以.fade-enter-active,.fade-leave-active这两个类可以写在一起
-->

展示效果: 

案例二

<template>
  <div>
    <button @click="show = !show">点击淡出</button>
    <transition name="fade">
      <img src="../assets/logo.png" alt="logo" v-show="show">
    </transition>
  </div>
</template>

<script>
export default {
  name: "fadesOut",
  data(){
    return {
      show:true
    }
  }
}
</script>

<style scoped>
  .fade-enter{
    width: 100px;
    height: 100px;
    opacity: 0;
  }
  /*离开过渡的时候的样式*/
  /*如果将值改为300,则不会缩小,只会淡化*/
  .fade-leave-active{
    opacity: 0;
    width: 100px;
    height: 100px;
  }
  .fade-enter-active{
    opacity: 1;
    width: 300px;
    height: 300px;
  }
  .fade-enter-active,.fade-leave-active{
    transition: 1s all ease;
  }
  img{
    width: 300px;
    height: 300px;
  }
</style>

展示效果:

 

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值