初识路由
- Vue-Router 是 Vue.js 官方的路由管理器;
- 它能够创建单页应用 (SPA),通过在应用中创建不同的视图和路径;
基本使用
-
定义路由组件
import Vue from 'vue' import VueRouter from 'vue-router' import Home from '../views/Home.vue' Vue.use(VueRouter) const routes = [ { path: '/', name: 'Home', component: Home }, { path: '/about', name: 'About', // 利用 component 动态引入组件 component: () => import(/* webpackChunkName: "about" */ '../views/About.vue'), children: [ { // 直接写全或者写 a,不要写 /a path: '/about/a', component: () => import(/* webpackChunkName: "hello" */ '../views/Hello.vue') } ] } ] const router = new VueRouter({ // hash利用的是 onhashchange 事件 // history利用的是 onpopstate 事件和 pushstate、replaceState 方法 mode: 'history', base: process.env.BASE_URL, routes, linkActiveClass: 'active',// 重命名全局配置,活跃link linkExactActiveClass: 'qq'// 重命名全局配置,精确匹配活跃link }) export default router
-
注册路由
/* 入口 js */ import Vue from 'vue' import App from './App.vue' import router from './router' /* eslint-disable no-new */ new Vue({ el: '#app', components: { App }, // 映射组件标签 template: '<App/>', // 指定需要渲染到页面的模板 router // 注册路由器 })
-
使用路由
<div> <!-- 路由链接 --> <router-link to="/about">About</router-link> <!-- 用于渲染当前路由组件 --> <router-view/> </div>
动态路由
动态路径参数
同一个路径可以匹配多个路由,路由定义得越早,优先级就越高
-
router 配置
「/user/:id」
:/user/foo 和 /user/bar 都将映射到相同的路由 User;const router = new VueRouter({ routes: [{ path: '/user/:id', // 动态路径参数 以冒号开头 props: true, // 开启 props,会把 URL 中的参数传递给组件 component: () => import('@/User.vue'), // 懒加载组件 },] })
-
获取参数
<template> <div> <!-- 方式1: 通过当前路由规则,获取数据 --> 通过当前路由规则获取:{{ $route.params.id }} <br> <!-- 方式2(推荐):路由规则中开启 props 传参 --> 通过开启 props 获取:{{ id }} </div> </template> <script> export default { name: 'User', props: ['id'] } </script>
-
监控路由参数的变化
export default { // 第一种:使用 watch (监测变化) $route 对象 watch: { $route(to, from) { // 对路由变化作出响应... } }, // 第二种:使用 2.2 中引入的 beforeRouteUpdate 导航守卫 beforeRouteUpdate(to, from, next) { // don't forget to call next() } }
捕获所有路由或 404 Not found 路由
-
匹配任意路径,使用通配符 (*),通过 pathMatch 获取通配符参数;
// 将匹配所有内容并将其放在 `route.params.pathMatch` 下 // 会匹配所有路径,应该放在最后,通常用于客户端 404 错误 // 假设访问的 URL 是 /a/b/c,则 route.params.pathMatch = 'a/b/c'; { path: '/:pathMatch(.*)' }, // 假设访问的 URL 是 /a/b/c,则 route.params.pathMatch = ['a', 'b', 'c']; { path: '/:pathMatch(.*)*' }, // 将匹配以 `/user-` 开头的所有内容,并将其放在 `route.params.afterUser` 下 { path: '/user-:afterUser(.*)' }
嵌套路由
-
一些应用程序的 UI 由多层嵌套的组件组成;在这种情况下,URL 的片段通常对应于特定的嵌套组件结构,例如:
-
配置嵌套路由
const User = { template: ` <div class="user"> <!--子路由出口, profile/posts組件 --> <router-view/> </div> ` } const router = new VueRouter({ routes: [ { path: '/user/:id', component: User, children: [ { // 当 /user/:id/profile 匹配成功, // UserProfile 会被渲染在 User 的 <router-view> 中 path: 'profile', component: UserProfile }, { // 当 /user/:id/posts 匹配成功 // UserPosts 会被渲染在 User 的 <router-view> 中 path: 'posts', component: UserPosts } ] } ] })
路由跳转
-
使用
<router-link>
创建 a 标签来定义导航链接;<router-link : to="{ name: 'user', params: { userId: 123 }}">User</router-link>
-
router.push
:会向 history 添加新记录;const router = new VueRouter({ routes: [ { path: '/user/:userId', name: 'user', // 设置名称 component: User } ] }); router.push({ name: 'user', params: { userId: 123 }, query: { name: 'zhangsan' } }); router.push({ path: '/user', params: { userId: 123 } });
-
router.replace
:不会向 history 添加新记录; -
router.go(n)
:在 history 记录中向前或者后退多少步,类似window.history.go(n)
;// 在浏览器记录中前进一步,等同于 history.forward() router.go(1) // 后退一步记录,等同于 history.back() router.go(-1) // 前进 3 步记录 router.go(3)
重定向、别名
重定向
-
重定向是 Vue Router 中的重要功能,允许将一个 URL 自动转向另一个 URL;
-
静态重定向:
const routes = [ { path: '/home', redirect: '/dashboard' // 访问/home时重定向到/dashboard } ]
-
命名路由重定向:
const routes = [ { path: '/home', redirect: { name: 'dashboard' } // 重定向到命名路由 } ]
-
基于路径参数的重定向:
const routes = [ { path: '/user/:id', redirect: '/profile/:id' // 保留参数 } ]
-
函数式重定向:
const routes = [ { path: '/old-path', redirect: (to) => { // 保留原始查询参数和 hash return { path: '/new-path', query: to.query, hash: to.hash }; } } ]
别名
-
别名是 Vue Router 中一个非常有用的功能,它允许你为同一个组件定义多个访问路径,而不会改变浏览器地址栏显示的 URL;
-
嵌套路由中的别名:
const routes = [ { path: '/user', component: User, children: [ { path: 'profile', component: Profile, alias: ['/me', '/account'] // 嵌套别名 } ] } ]
-
带参数的别名:
const routes = [ { path: '/post/:id', component: Post, alias: '/article/:id' // 带参数的别名 } ]
-
绝对路径别名:
const routes = [ { path: '/admin', component: Admin, alias: '/root' // 绝对路径别名 } ]
-
实际应用场景:
JavaScriptJavaScriptJavaScript// 场景1:多语言路径 const routes = [ { path: '/about', component: About, alias: ['/sobre', '/ueber'] // 西班牙语和德语的别名 } ]
// 场景2:新旧URL并存 const routes = [ { path: '/new-products', component: Products, alias: '/legacy-products' // 保持旧URL可用 } ]
// 场景3:简化复杂路径 const routes = [ { path: '/user/:userId/settings/notifications', component: Notifications, alias: '/notifications' // 简化路径 } ]
别名 VS 重定向
特性 | 重定向 | 别名 |
---|---|---|
URL 变化 |
浏览器地址栏会改变 | 浏览器地址栏保持不变 |
历史记录 |
创建新的导航记录 | 不创建新的导航记录 |
实现方式 |
redirect 属性 | alias 属性 |
典型场景 |
旧 URL 迁移 | 同一个组件多个访问路径 |
路由组件传参
路由组件传参
-
通过路由参数传递 (动态路由)
JavaScriptHTML// 路由配置 const routes = [ { path: '/user/:id', component: User, props: true // 启用props传参 } ];
<!-- User.vue 组件 --> <template> <div>用户ID: {{ id }}</div> </template> <script> export default { props: ['id'] // 通过props接收参数 } </script>
-
通过查询参数传递 (?key=value)
JavaScriptHTML// 路由跳转 this.$router.push({ path: '/search', query: { q: 'vue' } });
<!-- Search.vue 组件 --> <template> <div>搜索关键词: {{ $route.query.q }}</div> </template> <script> export default { created() { console.log(this.$route.query.q); // 输出: vue } } </script>
-
通过 props 传递 (对象模式)
JavaScriptHTML// 路由配置 const routes = [ { path: '/promo', component: PromoPage, props: { newsletterPopup: false } // 静态props } ]
<!-- PromoPage.vue --> <script> export default { props: { newsletterPopup: Boolean }, created() { console.log(this.newsletterPopup) // false } } </script>
-
通过 props 传递 (函数模式)
JavaScriptHTML// 路由配置 const routes = [ { path: '/search/:query', component: SearchResults, props: (route) => ({ query: route.params.query, sort: route.query.sort || 'date' }) } ]
<!-- SearchResults.vue --> <script> export default { props: ['query', 'sort'], created() { console.log(this.query, this.sort) } } </script>
-
通过 meta 字段传递
JavaScriptJavaScript// 路由配置 const routes = [ { path: '/admin', component: AdminPanel, meta: { requiresAuth: true } } ]
// 在组件或导航守卫中访问 this.$route.meta.requiresAuth
-
通过编程式导航传递 state (Vue Router 4+)
JavaScriptJavaScript// 跳转时传递state this.$router.push({ name: 'user', state: { fromDashboard: true } })
// 在目标组件中访问 this.$route.state.fromDashboard
最佳实践对比
传参方式 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
路由参数 |
ID 类参数,形成漂亮 URL | URL 可收藏,SEO 友好 | 只能传字符串 |
查询参数 |
可选参数,过滤条件 | 灵活,可传多个 | URL 较长 |
Props 对象 |
静态配置 | 类型安全 | 不能动态变化 |
Props 函数 |
需要处理参数的复杂场景 | 高度灵活 | 配置稍复杂 |
Meta 字段 |
路由元信息,权限控制等 | 不暴露给用户 | 不能在组件中响应式更新 |
State 对象 |
临时传递大量数据(Vue Router 4+) | 不暴露在 URL 上 | 刷新页面会丢失 |
webpack 核心功能👉 loader 模块加载器
上一篇