css动画:transition
先弄清除transition标签的原理,下图是出现动画的 class 添加情况:
如上图所示,动画开始的第一瞬间,为标签添加 class v-enter
和v-enter-active
两个标签;第一瞬间过去,就会马上将v-enter
移除,来引发变化的动画动作,同时添加v-enter-to
;动画结束后,将class全部移除。
注意:上图中由于transition已经被命名,所以添加class的时候,会以名字 fade 来代替 v。
<style>
.v-enter {
opacity: 0;
/* 第一瞬间是opacity为0,这个class被移除,相当于元素恢复到opacity:1,产生了变化,可以被监听到 */
}
.v-enter-active {
transition: opacity 3s;
/* 这个class是在用css3的transition全程监听opacity是否有变化,有变化就进行动画效果 */
}
</style>
<div id="root">
<transition > <!--这里的transition没有命名-->
<div v-if='show'>hello world</div>
</transition>
<button @click='handleClick'>切换</button>
</div>
var vm = new Vue({
el:'#root',
data:{
show:true
},
methods:{
handleClick:function(){
this.show=!this.show
}
}
})
同时,还有结束动画的效果:
如上图所示,动画开始的第一瞬间,为标签添加 class v-leave
和v-leave-active
两个标签;第一瞬间过去,就会马上将v-leave
移除,同时添加v-leave-to
来引发变化的动画动作;动画结束后,将class全部移除。
<style>
.v-leave-to{
opacity: 0;
}
.v-leave-active {
transition: opacity 3s;
}
</style>
将开始和结束的动画合并在一块写,如下:
<style>
.v-enter ,
.v-leave-to{
opacity: 0;
}
.v-enter-active ,
.v-leave-active {
transition: opacity 3s;
}
</style>
@keyframes 动画
<style>
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
.v-enter-active {
transform-origin: left center;
animation: bounce-in 1s;
}
.v-leave-active {
transform-origin: left center;
animation: bounce-in 1s reverse;
}
</style>
<div id="root">
<transition > <!--这里的transition没有命名-->
<div v-if='show'>hello world</div>
</transition>
<button @click='handleClick'>切换</button>
</div>
var vm = new Vue({
el:'#root',
data:{
show:true
},
methods:{
handleClick:function(){
this.show=!this.show
}
}
})
如果不想使用 .v-leave-active
(transition未命名)或者 .fade-leave-active
(transition命名为fade)这种固定标签的写法,也可以使用自定义的class name。
<div id="root">
<transition
name='fade'
enter-active-class='active'
leave-active-class='leave'> <!--active和leave都是可以自定义的-->
<div v-if='show'>hello world</div>
</transition>
<button @click='handleClick'>切换</button>
</div>
animate.css的库
那么接下来就可以使用 animate.css的库了,不需要自己去写css的样式库了。(这个库使用的是@keyframes)
<!--引入下载好的文件-->
<link rel="stylesheet" type="text/css" href="./animate.css">
<!--将原有的style样式全部移除,在自定义class name中修改名称-->
<div id="root">
<transition
name='fade'
enter-active-class='animate swing'
leave-active-class='animate shake'> <!--使用了animate.css里面自带的动画效果-->
<div v-if='show'>hello world</div>
</transition>
<button @click='handleClick'>切换</button>
</div>
-
第一次打开页面没有动画效果的问题?
在transition 标签里面添加
appear
和appear-active-class="animated swing"
<div id="root"> <transition name='fade' appear enter-active-class='animate swing' leave-active-class='animate shake' appear-active-class='animate swing'> <!--添加了appear及appear class name--> <div v-if='show'>hello world</div> </transition> <button @click='handleClick'>切换</button> </div>
同时使用过渡和动画
同时使用就是在自定义名字的时候,定义多个名字,使每个样式都可以实现。
<style>
.fade-enter ,
.fade-leave-to{
opacity: 0;
}
.fade-enter-active ,
.fade-leave-active {
transition: opacity 3s;
}
</style>
<div id="root">
<transition
name='fade'
appear
enter-active-class='animate swing fade-enter-active'
leave-active-class='animate shake fade-leave-active'
appear-active-class='animate swing'> <!--添加了样式名称-->
<div v-if='show'>hello world</div>
</transition>
<button @click='handleClick'>切换</button>
</div>
- 过渡动画设置为3s,animate.css动画的源码中时长设置是1s,这个时候需要手动设置动画时长以哪个为准。
- 方法一:在transition中添加
type='transition'
属性进行定义; - 方法二:添加
:duration='5000'
自定义的动画时长; - 方法三:添加
:duration={enter:5000,leave:10000}
自定义的动画时长;
<div id="root">
<transition
type='transition'
:duration='5000'
:duration={enter:5000,leave:10000}
name='fade'
appear
enter-active-class='animate swing fade-enter-active'
leave-active-class='animate shake fade-leave-active'
appear-active-class='animate swing'> <!--三种方法任选其一,指定时长以谁为准-->
<div v-if='show'>hello world</div>
</transition>
<button @click='handleClick'>切换</button>
</div>
Js动画
入场动画、出场动画,都使用js提供的勾子实现。
<div id="root">
<transition
name='fade'
@before-enter="handleBeforeEnter"
@enter="handleEnter"
@after-enter="handleAfterEnter"
> <!--指定不同时期的勾子来触发不同的事件,通过事件来改变样式-->
<div v-if='show'>hello world</div>
</transition>
<button @click='handleClick'>切换</button>
</div>
var vm = new Vue({
el:'#root',
data:{
show:true
},
methods:{
handleClick:function(){
this.show=!this.show
}
},
handleBeforeEnter:function(el){
el.style.color:'red'
}, //el指的就是动画包裹的div标签,动画入场前,触发的时候是红色的
handleEnter:function(el,done){
setTimeout(()=>{
el.style.color='grren'
},2000)
setTimeout(()=>{
done()
},4000)
},//这里就是主战场,运行动画效果,记得结束要调用done()启用下面的勾子
handleAfterEnter:function(el){
el.style.color='#000'
}//动画完成了之后执行
})
出场动画和入场动画除了名字,其他都是一致的。@before-leave="handleBeforeLeave"
@leave="handleLeave"
` @after-leave=”handleAfterLeave”`。
Velocity.js
这里介绍一个js动画的库,Velocity.js 。
<!--引入库文件-->
<script src="./velocity.js"></script>
var vm = new Vue({
el:'#root',
data:{
show:true
},
methods:{
handleClick:function(){
this.show=!this.show
}
},
handleBeforeEnter:function(el){
el.style.opacity=0
},
handleEnter:function(el,done){
Velocity(el,{opacity:1},{
duration:1000,
complete:done
})
},//在这里使用velocity的js动画库
handleAfterEnter:function(el){
console.log('动画结束')
}
})
多个元素或组件的过渡
多个元素,使用key值阻止默认的复用DOM
<style>
.v-enter ,
.v-leave-to{
opacity: 0;
}
.v-enter-active ,
.v-leave-active {
transition: opacity 3s;
}
</style>
<div id="root">
<transition > <!--使用不同的key-->
<div v-if='show' key="hello">hello world</div>
<div v-else key="bye" >Bye world </div>
</transition>
<button @click='handleClick'>切换</button>
</div>
vue还提供了一个<transition mode="in-out">
,显示的元素先进入,隐藏的元素再隐藏;<transition mode="out-in">
,先隐藏再显示。
多个组件之间的过渡,动态组件
<style>
.v-enter ,
.v-leave-to{
opacity: 0;
}
.v-enter-active ,
.v-leave-active {
transition: opacity 3s;
}
</style>
<div id="root">
<transition mode='out-in'>
<component :is='type'></component><!--使用is将动态组件与自定义子组件名进行关联-->
</transition>
<button @click='handleClick'>切换</button>
</div>
Vue.component('child',{
template:'<div>child</div>'
})
Vue.component('child-one',{
template:'<div>child-one</div>'
})
var vm =new Vue({
el:'#root',
data:{
type:'child'
},
methods:{
handleClick:function(){
this.type = this.type === 'child' ? 'child-one' : 'child'
}
}
})
列表过渡 transition-group
使用transition-group
标签将列表包裹,效果是为每一次循环出来的div标签添加class。
<style>
.v-enter ,
.v-leave-to{
opacity: 0;
}
.v-enter-active ,
.v-leave-active {
transition: opacity 3s;
}
</style>
<div id='root'>
<transition-group><!--使用transition-group来包裹列表-->
<div v-for="item of list" :key="item.id">
</div>
</transition-group>
<button @click="handleBtnClick">Add</button>
</div>
var count= 0;
var vm =new Vue({
el:'#root',
data:{
list:[]
},
methods:{
handleBtnClick:function(){
this.list.push({
id:count++,
title:'hello world'
})
}
}
})
进行动画封装
Vue.component('fade',{
props:['show'],
template:`
<transition @before-enter="handleBeforeEnter" @enter="handleEnter">
<slot v-if="show"></slot>
</transition>`,
methods:{
handleBeforeEnter:function(el){
el.style.color='red'
},
handleEnter:function(el,done){
setTimeout(()=>{
el.style.color='green',
done()
},2000)
}
}
})
var vm = new Vue({
el:'#root',
data:{
show:true
},
methods:{
handleClick:function(){
this.show=!this.show
}
}
})
复用的时候,只要调用组件fade,
记得要传入参数show
<fade :show='show'>
<h1>byebye</h1>
</fade>
单文件组件
后缀为.vue的文件叫做单文件组件,里面放的是vue的一个组件。
- 组件的模板放在
<template>
标签中 - 组件的逻辑放在
<script>
标签中 - 组件的css样式放在
<style>
标签中
路由
路由就是根据网址的不同,返回不同的内容给用户。
<router-view/>
标签显示的是当前路由地址所对应的内容。
vue要求对外暴露的只有一个标签,需要的时候可以在最外层添加一个<div>
标签。
- 为了解决多个显示屏的显示样式不同 和 移动端的1px不能显示成1px问题,src/assets/styles中添加reset.css和border.css两个文件;同时在router文件夹中的main.js中添加
import '.assets/styles/reset.css' import '.assets/styles/border.css'
; - 在某些移动端还会出现click点击事件延迟300ms的情况,在当前Travel目录下安装
npm install fastclick --save
,然后还是在router下面的main.js中添加代码import fastClick from 'fastClick' fastClick.attach(document.body)