Vue Router 路由

路由守卫钩子和元信息

深入讲解 Vue 2 路由的导航守卫、路由元信息和页面切换过渡动画,助你掌握高级路由技巧。

🎯 引言

学完这篇文章,你将能够熟练运用 Vue 2 路由中的高级功能,比如如何用导航守卫实现权限控制和页面访问拦截,利用路由元信息管理页面标题,以及为页面切换添加炫酷的过渡动画。这些技巧能让你的单页面应用更加专业、流畅和用户友好。


🔐 导航守卫介绍

Vue 2 路由提供了丰富的导航守卫机制,帮我们在路由切换时插入逻辑,比如权限验证、数据预处理等。导航守卫主要分为三类:

  • 全局守卫(所有路由生效)
  • 路由独享守卫(某个路由独有)
  • 组件内守卫(路由对应组件内部)

下面我们详细看这三类守卫的使用。


🌟 全局前置守卫 router.beforeEach

全局前置守卫在路由跳转开始时就触发,常用于做权限验证、登录拦截等。在路由实例 router 上调用 beforeEach 函数。

router.js
router.beforeEach((to, from, next) => {
    const isLogin = Boolean(localStorage.getItem('token'));

    if (isLogin) {
        next();
    } else {
        next('/login'); // 未登录重定向到登录页
    }
});
在全局前置守卫钩子 router.beforeEach 请根据情况放行 next(),否则路由操作会被终止。

🌟 路由独享守卫(beforeEnter

每个路由单独维护自己的守卫,写法简单,适合单个路由特定的逻辑。

const routes = [
    {
        path: '/admin',
        component: () => import('@/components/Admin.vue'),
        beforeEnter: (to, from, next) => {
            const isLogin = Boolean(localStorage.getItem('token'));

            if (isLogin) {
                next();
            } else {
                next('/login'); // 未登录重定向到登录页
            }
        },
    },
];

这个守卫只会在访问 /admin 路由时执行,比较适合路由权限的细粒度控制。


🏷️ 路由元信息(meta)

路由的 meta 字段是个超级好用的自定义数据容器。你可以在里面放权限信息、页面标题、缓存标记等,然后结合导航守卫或组件逻辑实现各种功能。

const routes = [
    {
        path: '/dashboard',
        component: Dashboard,
        meta: {
            requiresAuth: true,
            title: '用户仪表盘',
            keepAlive: true,
        },
    },
];

页面标题

结合守卫动态修改页面标题:

router.afterEach(to => {
    document.title = to.meta.title || '默认标题';
});

🎨 页面切换过渡动画

Vue 的 <transition> 组件让我们可以轻松添加页面切换的动画效果,让用户感觉切换更加流畅。

基础示例

<template>
    <div id="app">
        <transition name="fade" mode="out-in">
            <router-view />
        </transition>
    </div>
</template>

<style>
.fade-enter-active,
.fade-leave-active {
    transition: opacity 0.5s;
}
.fade-enter,
.fade-leave-to {
    opacity: 0;
}
</style>

复杂动画

你可以结合 CSS 动画或 JS 钩子实现更丰富的效果,比如左右滑动、翻转等。

.slide-enter-active {
    animation: slide-in 0.3s forwards;
}
.slide-leave-active {
    animation: slide-out 0.3s forwards;
}

@keyframes slide-in {
    from {
        transform: translateX(100%);
        opacity: 0;
    }
    to {
        transform: translateX(0);
        opacity: 1;
    }
}
@keyframes slide-out {
    from {
        transform: translateX(0);
        opacity: 1;
    }
    to {
        transform: translateX(-100%);
        opacity: 0;
    }
}

结合 <transition name="slide" mode="out-in"> 使用即可。


🧾 小节总结

  • Vue 2 路由提供三种导航守卫(全局、路由独享、组件内),让你灵活处理路由切换逻辑。
  • 路由元信息 (meta) 是管理权限、页面标题和缓存的重要利器。
  • 页面切换动画用 <transition> 配合 CSS 制作,增强视觉反馈。

❓ 知识问答(Q&A)

Q:全局守卫和路由独享守卫有什么区别?

A:全局守卫对所有路由生效,适合统一逻辑;路由独享守卫只作用于特定路由,适合单独处理。

Q:为什么 beforeRouteEnter 不能直接访问组件实例?

A:因为组件还没被创建,需通过 next(vm => {}) 回调拿到组件实例。

Q:如何根据路由元信息动态设置页面标题?

A:可在 router.afterEach 中通过 to.meta.title 修改 document.title


🧪 小练习

请基于以下模板,完成权限验证和页面标题动态修改的功能。

import Vue from 'vue';
import Router from 'vue-router';
import Home from '@/components/Home.vue';
import Login from '@/components/Login.vue';
import Dashboard from '@/components/Dashboard.vue';

Vue.use(Router);

const router = new Router({
    routes: [
        { path: '/', component: Home, meta: { title: '首页' } },
        { path: '/login', component: Login, meta: { title: '登录' } },
        { path: '/dashboard', component: Dashboard, meta: { requiresAuth: true, title: '仪表盘' } },
    ],
});

// TODO: 添加全局前置守卫,实现未登录用户不能访问 /dashboard,跳转登录页

// TODO: 添加 afterEach 钩子,实现根据路由 meta.title 修改页面标题

export default router;

🎉 恭喜你已经掌握导航守卫、路由元信息和页面切换过渡动画技能啦!