Vue Router 路由管理完全指南:从入门到精通前言
前言
大家好!今天我要和大家聊聊 Vue Router,这个 Vue.js 官方的路由管理器。如果你正在开发 Vue 应用,那么路由管理肯定是绕不开的话题。无论是构建简单的单页应用还是复杂的企业级项目,Vue Router 都能帮你轻松实现页面之间的跳转和状态管理
在这篇文章中,我会从最基础的概念开始,一步步带你深入 Vue Router 的世界,最后还会分享一些实际项目中的应用案例。无论你是 Vue 新手还是有一定经验的开发者,相信都能从这篇文章中有所收获
一、什么是 Vue Router?
1、路由的基本概念
首先,我们得搞清楚什么是 "路由"。简单来说,路由就是一组 key-value 的对应关系。在前端开发中,这个对应关系通常是路径 -> 组件。当用户访问某个路径时,路由系统就会渲染对应的组件
举个生活中的例子,路由就像是一个酒店的前台。客人报出自己的房间号(路径),前台就会指引客人到对应的房间(组件)
2、SPA 应用的特点
Vue Router 主要用于构建单页 Web 应用(SPA),SPA 有以下几个特点:
(1)、整个应用只有一个完整的页面:所有内容都在一个 HTML 文件中展示
(2)、页面不会刷新:点击导航链接时,页面不会重新加载,只会做局部更新
(3)、数据通过 AJAX 获取:页面内容的更新通常是通过异步请求获取数据这种方式的好处是用户体验更好,感觉更像使用原生应用。但同时也带来了路由管理的需求,这就是 Vue Router 要解决的问题
二、Vue Router 的基本使用
第一步:安装 Vue Router
首先,我们需要安装 Vue Router。如果你使用的是 Vue 3,那么需要安装 Vue Router 4:
npm install vue-router@4
如果你使用的是 Vue 2,那么需要安装 Vue Router 3:
npm install vue-router@3
第二步:创建路由器
安装完成后,我们需要创建一个路由器实例。通常我们会在 src/router/index.ts 文件中创建:
// src/router/index.ts
import { createRouter, createWebHistory } from "vue-router";
import Home from "@/pages/Home.vue";
import News from "@/pages/News.vue";
import About from "@/pages/About.vue";const router = createRouter({history: createWebHistory(),routes: [{path: "/home",component: Home,},{path: "/news",component: News,},{path: "/about",component: About,},],
});export default router;
这里有几个关键点:
1、createRouter:创建路由实例的函数
2、createWebHistory:使用 HTML5 History 模式
3、routers:路由规则数组,每个规则包含 path(路径)和 component(组件)
第三步:注册路由器
创建好路由器后,我们需要在 Vue 应用中注册它:
// src/main.ts
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";const app = createApp(App);
app.use(router); // 注册路由器
app.mount("#app");
第四步:使用路由
现在我们可以在组件中使用路由了。主要有两个组件:
1、RouterLink:用于创建导航链接
2、RouterView:用于渲染匹配的组件
<template><div class="app"><h2 class="title">Vue路由测试</h2><!-- 导航区 --><div class="navigate"><RouterLink to="/home" active-class="active">首页</RouterLink><RouterLink to="/news" active-class="active">新闻</RouterLink><RouterLink to="/about" active-class="active">关于</RouterLink></div><!-- 展示区 --><div class="main-content"><RouterView></RouterView></div></div>
</template><script lang="ts" setup name="App">
import { RouterLink, RouterView } from "vue-router";
</script>
RouterLink 会被渲染成<a>标签,但它有一些特殊的功能:
① to:指定跳转的路径
② active-class:当路由激活时添加的CSS类
RouterView 是一个占位符,匹配的组件会在这里渲染
三、路由器工作模式
Vue Router 提供了两种工作模式:History 模式和 Hash 模式
1、History 模式
const router = createRouter({history: createWebHistory(), // History 模式routes: [...]
});
优点:
① URL 更加美观,不带有 #
② 更接近传统的网站 URL
缺点:
① 项目上线时需要服务端配合处理路径问题
② 刷新页面可能会出现 404 错误
2、Hash 模式
const router = createRouter({history: createWebHashHistory(), // Hash 模式routes: [...]
});
优点:
① 兼容性更好,不需要服务器端处理
② 刷新页面不会有 404 错误
缺点:
① URL 带有 # ,不太美观
② SEO 优化方面相对较差
选择建议
① 如果是内部管理系统,对 URL 美观度要求不高,可以使用 Hash 模式
② 如果是面向用户的网站,建议使用 History 模式,但需要后端配合
四、路由导航的三种方式
1、RouterLink 组件
这是最常用的方式,通过 to 属性指定路径:
<!-- 字符串写法 -->
<RouterLink to="/home">首页</RouterLink><!-- 对象写法 -->
<RouterLink :to="{ path: '/home' }">首页</RouterLink>
2、命名路由
给路由规则起个名字,可以简化跳转:
// 路由配置
routes: [{name: "home", // 给路由命名path: "/home",component: Home}
]
<!-- 使用名字跳转 -->
<RouterLink :to="{ name: 'home' }">首页</RouterLink>
好处:
① 当路径发生变化时,不需要修改所有的跳转链接
② 配合参数传递更方便
3、编程式导航
有时候我们需要在 JavaScript 代码中进行页面跳转,这时候就需要使用编程式导航:
import { useRouter } from "vue-router";const router = useRouter();// 字符串路径
router.push("/home");// 对象形式
router.push({ path: "/home" });// 命名路由
router.push({ name: "home" });// 带参数
router.push({ name: "newsDetail", params: { id: 123 }
});
五、路由传参详解
在实际开发中,我们经常需要在页面之间传递数据。Vue Router 提供了多种传参方式
1、Query 参数
Query 参数类似于 URL 中的查询字符串,格式为 ?key=value&key2=value2
传递参数:
<!-- 字符串写法 -->
<RouterLink to="/news/detail?id=123&title=新闻标题">查看详情</RouterLink><!-- 对象写法 -->
<RouterLink :to="{path: '/news/detail',query: {id: 123,title: '新闻标题'}
}">查看详情</RouterLink>
接收参数:
import { useRoute } from "vue-router";const route = useRoute();
console.log(route.query.id); // 123
console.log(route.query.title); // '新闻标题'
2、Params 参数
Params 参数是路径的一部分,需要在路由规则中提前占位
配置路由规则:
routes: [{name: "newsDetail",path: "/news/detail/:id/:title", // 占位符component: NewsDetail}
]
传递参数:
<!-- 字符串写法 -->
<RouterLink to="/news/detail/123/新闻标题">查看详情</RouterLink><!-- 对象写法 -->
<RouterLink :to="{name: 'newsDetail', // 必须使用 name,不能用 pathparams: {id: 123,title: '新闻标题'}
}">查看详情</RouterLink>
接收参数:
import { useRoute } from "vue-router";const route = useRoute();
console.log(route.params.id); // 123
console.log(route.params.title); // '新闻标题'
3、Props 配置
为了让组件更方便地接收参数,Vue Router 提供了 props 配置:
routes: [{name: "newsDetail",path: "/news/detail/:id/:title",component: NewsDetail,// 方式一:对象写法// props: { a: 1, b: 2 }// 方式二:布尔值写法,会把 params 参数作为 props 传递// props: true// 方式三:函数写法,可以自定义处理props(route) {return {id: route.params.id,title: route.params.title,timestamp: Date.now()};}}
]
然后在组件中就可以像使用普通 props 一样使用这些参数:
// NewsDetail.vue
const props = defineProps({id: String,title: String,timestamp: Number
});
六、嵌套路由
嵌套路由是指在一个路由组件内部嵌套另一个路由组件。比如在新闻页面中嵌套新闻详情页面
1、配置嵌套路由
const router = createRouter({history: createWebHistory(),routes: [{path: "/news",component: News,children: [ // 子路由配置{path: "detail/:id", // 子路径,注意不要加 /component: NewsDetail}]}]
});
2、在父组件中预留出口
<!-- News.vue -->
<template><div class="news"><div class="news-list"><RouterLink v-for="news in newsList" :key="news.id" :to="`/news/detail/${news.id}`">{{ news.title }}</RouterLink></div><!-- 子路由出口 --><div class="news-content"><RouterView /></div></div>
</template>
七、路由守卫
路由守卫允许我们在路由跳转前后执行一些操作,比如权限验证、数据加载等
1、全局守卫
// router/index.ts// 全局前置守卫
router.beforeEach((to, from, next) => {console.log('从', from.path, '跳转到', to.path);// 权限验证const isAuthenticated = localStorage.getItem('token');if (to.path === '/admin' && !isAuthenticated) {next('/login'); // 未登录,跳转到登录页} else {next(); // 继续跳转}
});// 全局后置守卫
router.afterEach((to, from) => {console.log('跳转完成');// 可以在这里设置页面标题document.title = to.meta.title || '默认标题';
});
2、组件内守卫
// 在组件中
import { onBeforeRouteEnter, onBeforeRouteUpdate, onBeforeRouteLeave } from 'vue-router';// 进入路由前
onBeforeRouteEnter((to, from, next) => {console.log('进入路由前');next();
});// 路由更新时
onBeforeRouteUpdate((to, from, next) => {console.log('路由更新时');next();
});// 离开路由前
onBeforeRouteLeave((to, from, next) => {console.log('离开路由前');next();
});
八、常见问题和解决方案
1、刷新页面出现 404 错误
原因:使用了 History 模式,但服务器没有正确配置
解决方案:开发环境,在 vite.config.ts 或 vue.config.js 中配置 base
2、路由参数变化时组件不重新渲染
原因:当路由参数变化时,Vue Router 会复用同一个组件实例
解决方案:
① 使用 watch 监听路由变化
② 使用 onBeforeRouteUpdate 钩子
③ 给组件添加 key 属性
// 方案一:使用 watch
watch(() => route.params.id,(newId) => {// 处理逻辑fetchData(newId);}
);// 方案二:使用 onBeforeRouteUpdate
onBeforeRouteUpdate((to) => {fetchData(to.params.id);
});// 方案三:添加 key
<RouterView :key="$route.fullPath" />
3、路由守卫中如何正确使用 next ()
常见错误:忘记调用 next(),导致路由跳转被阻塞
正确用法:
router.beforeEach((to, from, next) => {if (需要验证) {if (验证通过) {next(); // 继续跳转} else {next('/login'); // 重定向}} else {next(); // 一定要调用 next()}
});
希望这篇文章能帮助你更好地理解和使用 Vue Router,学习编程最好的方法就是动手实践,尝试使用 Vue Router 的各种特性,这样才能真正认识它