参考博客:手摸手,带你用 vue 动画实现原生 app 切换效果,丝滑般的体验
使用vue官方提供的transition组件实现类似微信的转场动画效果,动画分前进动画与退出动画两种
- 当跳转至新页面(前进)时,当前页面向左侧滑出,新页面从右侧滑入
- 当触发返回(退出)时,当前页面向右侧滑出,上一层页面从左侧滑入
所以需要在store中存放一个变量,transtion组件根据变量名判断使用前进动画还是退出动画
// store.js
export default new Vuex.Store({
state: {
animateState: ''
},
mutations: {
setAnimateState (state, animateState) {
state.animateState = animateState
}
}
})
在App.vue中监听路由返回(popstate),并将动画类型设置为退出动画
<template>
<div id="app">
<transition :name="$store.state.animateState">
<router-view />
</transition>
</div>
</template>
<script>
import store from '@/store'
export default {
name: "App",
mounted() {
window.addEventListener("popstate", () => {
this.$store.commit('setAnimateState', 'out')
})
},
}
</script>
<style lang="scss">
html, body, #app {
height: 100%;
}
@mixin fixStyle {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.in-enter-active {
@include fixStyle;
z-index: 200;
transition: transform .4s ease;
}
.in-enter {
transform: translateX(100vw);
}
.in-leave-active {
@include fixStyle;
z-index: 100;
transition: transform .4s ease;
}
.in-leave-to {
transform: translateX(-100vw);
}
.out-enter-active {
@include fixStyle;
z-index: 200;
transition: transform .4s ease;
}
.out-enter {
transform: translateX(-100vw);
}
.out-leave-active {
@include fixStyle;
z-index: 200;
transition: transform .4s ease;
}
.out-leave-to {
transform: translateX(100vw);
}
</style>
路由跳转时,添加前进动画,定义一个mixins函数
// common.js
import router from '@/router'
import store from '@/store'
export default {
methods: {
router_push (params) {
store.commit('setAnimateState', 'in')
router.push({ ...params }) // 对象解构
}
}
}
路由跳转时调用router_push函数
import Common from '@/common/js/common.js'
export default {
mixins: [Common],
name: "home",
data() {
return {}
},
methods: {
showGood(id) {
this.router_push({ path: "good", query: { id } })
}
}
}
底部导航栏切换页面不使用转场动画的处理
在main.js中添加全局前置守卫,检测到位底部导航页则剪动画类型设为空
// main.js
import store from './store'
router.beforeEach((to, from, next) => {
// 不使用过渡效果页面的白名单
const whiteList = ['home', 'me']
if (whiteList.includes(to.name) && whiteList.includes(from.name)) {
store.commit('setAnimateState', '')
}
next()
})