乐趣区

关于前端: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>
退出移动版