Vue Router Transition(页面路由转场动画)

近期在导航组件的测试时,遇到了市面上一些 vue-router 组件转场效果不理想的问题,所以就自己写了一个例子,使用的是 slide 效果,以供参考。

vue 代码

App.vue
<template>
  <div id="app">
    <transition :name="transitionName">
      <router-view />
    </transition>
  </div>
</template>
   

js 代码

main.js
由于 history 的效果实在不理想,所以使用了 meta 自定义了 depthback url 属性来控制页面之间的跳转关系。特效使用进场向右左滑动,离场向右滑动。
data() {
    return {
      transitionName: 'slide-left'
    };
},

watch: {
    $route(to, from) {
      const toDepth = to.meta.depth;
      const fromDepth = from.meta.depth;
      this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left';
    }
}
router.js
示例路由,另外通过 router.beforeEach 实现了权限验证,登录权限无效则直接跳转登录页。
import Vue from 'vue';
import Router from 'vue-router';

import Login from '../pages/login';
import Home from '../pages/home';
import Test from '../pages/test';

Vue.use(Router);

const router = new Router({
  routes: [
    {
      path: '/login',
      name: 'login',
      meta: {
        title: '登录',
        depth: 0
      },
      component: Login
    },
    {
      path: '/',
      name: 'home',
      meta: {
        title: '主页',
        depth: 1,
        back: '/login'
      },
      component: Home
    },
    {
      path: '/test',
      name: 'test',
      meta: {
        title: '测试页面',
        depth: 2,
        back: '/'
      },
      component: Test
    }
  ]
});

router.beforeEach((to, from, next) => {
  if (to.name !== 'login') {
    const token = checkUserToken(); // 检测当前是否有权限登录
    if (!token) {
      next({ // 权限无效则跳转登录页
        path: '/login'
      });
    } else {
      next();
    }
  } else {
    next();
  }
});

export default router;
css 代码
`<style lang="scss">`
.slide-right-enter-active,
.slide-right-leave-active,
.slide-left-enter-active,
.slide-left-leave-active {
  position: absolute; // 需要注意的地方
  width: 100%; // 需要注意的地方,否则会出现页面渲染卡顿现象
  will-change: transform;
  transition: all 0.3s ease-out;
}

.slide-right-enter {
  opacity: 0;
  transform: translate(-100%, 0);
}

.slide-right-leave-active {
  opacity: 0;
  transform: translate(0%, 0);
}

.slide-left-enter {
  opacity: 0;
  transform: translate(100%, 0);
}

.slide-left-leave-active {
  opacity: 0;
  transform: translate(0%, 0);
}
</style>
阅读 58

推荐阅读