vue提供了内置组件transition用来处理动画效果
原理: 1. 通过添加或删除css类名来处理动画效果 2. 使用内置钩子函数来控制动画,也就是通过js来控制动画
注意:当动画完成之后,vue会帮我们删除class 那么会带来两个问题: 1.我门在控制台中看动画的时候是捕获不到class类名的。 2.可以用v-if来控制动画。也就是当元素创建之后才会去执行transition动画。
使用css类名控制动画用法
- v-enter:定义进入过渡的开始状态
- v-enter-to: 定义进入的结束状态
- v-enter-active: 定义进入活动状态 [定义组件/dom进入时的持续时间和运动形式,比如定义transition,animation]
- v-leave: 定义离开过渡的开始状态
- v-leave-to: 定义离开的结束状态
- v-leave-active: 定义离开活动状态 [定义组件/dom离开时的持续时间和运动形式,比如定义transition,animation]
- 使用name属性可以自定义前缀
拿路由切换举一个例子
做一个切换路由时淡隐淡出的动画
主要逻辑
<transition >
<router-view ></router-view>
</transition>
.v-enter {
opacity: 0;
}
.v-enter-to {
opacity: 1;
}
.v-enter-active {
transition: 1s;
}
.v-leave {
opacity: 1;
}
.v-leave-to {
opacity: 0;
}
.v-leave-active {
transition: 2s;
}
先来分析一下这个路由切换的过程 1.当组件进入的时候 设置组件进入时的开始状态(v-enter)和组件进入时的结束状态(v-enter-to) 然后设置组件进入时(开始状态和结束状态v-enter-active)的持续时间和运动形式 即当前组件进入时是淡出的效果 2.当组件离开的时候呢 设置组件离开时的开始状态(v-leave)和组件离开时的结束状态(v-leave-to) 然后设置组件离开时(开始状态和结束状态v-leave-active)的持续时间和运动形式
组件进入时的过渡状态我们设置的是1秒 组件离开时的过渡状态我们设置的是2秒
那么会造成什么问题呢? 当前路由进入的时候,要离开的那个路由还没有消失,,也就是两个路由都会出现在文档流中,会造成两个路由共存的情况
See the Pen <a href='https://codepen.io/wensiyuanseven/pen/QWjMgvg'>vue-router-demo-1</a> by 思远 (<a href='https://codepen.io/wensiyuanseven'>@wensiyuanseven</a>) on <a href='https://codepen.io'>CodePen</a>. 那这种情况我们怎么处理呢? 给路由加个定位 ``` .router{ position:absolute; top:20; left:10; } ``` See the Pen <a href='https://codepen.io/wensiyuanseven/pen/QWjMgvg'>路由淡隐淡出-定位</a> by 思远 (<a href='https://codepen.io/wensiyuanseven'>@wensiyuanseven</a>) on <a href='https://codepen.io'>CodePen</a>.然而你发现这样还是会有问题。也就是当下一个路由进入时(1秒),要离开的路由还没消失(2秒)。
这时候两个路由会重叠在一起。这是因为离开和进入的动画是同时进行的。然而实际项目中,需求并不是这样,而是在离开的元素过渡完成之后,进入的元素在进行动画。 这时候vue提供的过渡模式就派上用场了。 先看定义
- in-out:新元素先进行过渡,完成之后当前元素过渡离开
- out-in:当前元素先进行过渡,完成之后新元素过渡进入
我们一般用out-in比较多
See the Pen <a href='https://codepen.io/wensiyuanseven/pen/abvyeVz'>路由-过渡模式</a> by 思远 (<a href='https://codepen.io/wensiyuanseven'>@wensiyuanseven</a>) on <a href='https://codepen.io'>CodePen</a>.那么如果只控制路由进入时的过渡动画 ,路由离开时不添加动画,那么就会有一个路由淡出的动画,路由离开时会瞬间离开,不用添加动画
See the Pen <a href='https://codepen.io/wensiyuanseven/pen/VwvzoYe'>路由淡出动画</a> by 思远 (<a href='https://codepen.io/wensiyuanseven'>@wensiyuanseven</a>) on <a href='https://codepen.io'>CodePen</a>.我们来做一个tab切换效果
路由往左运动的动画
<transition name="left">
See the Pen <a href='https://codepen.io/wensiyuanseven/pen/JjYrPep'>路由从左边弹出动画</a> by 思远
(<a href='https://codepen.io/wensiyuanseven'>@wensiyuanseven</a>) on <a href='https://codepen.io'>CodePen</a>.
那当路由离开的时候需要继续往左运动 又因为 两个路由是同时运动的,所以不需要设置mode(过渡状态),而防止两个路由同时出现在文档流当中,所以需要给router-view设置定位
See the Pen <a href='https://codepen.io/wensiyuanseven/pen/PoPJYvM'>PoPJYvM</a> by 思远 (<a href='https://codepen.io/wensiyuanseven'>@wensiyuanseven</a>) on <a href='https://codepen.io'>CodePen</a>.注意 有时候我们可以不写动画运动到的默认的位置,transition会自动帮我门去处理. 可以省略
transform: translateX(0);
那动画就可以写成
/* 路由进入时 */
.left-enter {
transform: translateX(100%);
}
.left-enter-active {
transition: 1s;
}
/*路由离开时*/
.left-leave-to {
transform: translateX(-100%);
}
.left-leave-active {
transition: 1s;
}
路由往右运动的动画
See the Pen <a href='https://codepen.io/wensiyuanseven/pen/MWaERqx'>路由往右运动的动画-连续</a> by 思远 (<a href='https://codepen.io/wensiyuanseven'>@wensiyuanseven</a>) on <a href='https://codepen.io'>CodePen</a>.那么name值不同运动形式也不同
可以根据meta路由元存储路由的索引值来判断是向左还是向右运动【就是判断向前还是向后】,假如路由很多,也可以把路由循环出来,动态添加路由元信息。
注意点: 1.路由中如果有默认的子路由,路由元信息需要存储在子路由当中,否则,存储的信息不生效。 2.用watch监听$route需要和router-view标签同级,否则不生效。
初始化时给一个默认路由
{ path: "/", component: Foo, meta: { index: 0 } }, //因为初始化的时候路由并没有改变,所以不会有动画
See the Pen <a href='https://codepen.io/wensiyuanseven/pen/BaowbgQ'>路由切换完整动画</a> by 思远
(<a href='https://codepen.io/wensiyuanseven'>@wensiyuanseven</a>) on <a href='https://codepen.io'>CodePen</a>.
可以发现当路由切换过快时会有空白的间隙,为什么呢?可能和transition的动画机制和css动画机制有关系,比如动画曲线有关系(当动画还没有结束时被终止会出现空白) 两种办法:
第一种:在动画结束时才允许切换动画 第二种:transition过渡时间设置小一点比如0.3s(推荐)
推荐对于仅使用 JavaScript 过渡的元素添加 v-bind:css="false",Vue 会跳过 CSS 的检测。这也可以避免过渡过程中 CSS 的影响,提高性能