Vue Router 是 Vue 官方的客户端路由解决方案,可以通过配置路由来告诉 Vue Router 为每个 URL 路径显示哪些组件。
1. Vue3 中使用 vue-router
安装
npm install vue-router@4
创建路由配置文件
新建 router/index.js 文件按用来统一管理路由配置。
// router/index.js
import { createRouter, createWebHistory } from "vue-router";const router = createRouter({history: createWebHistory(),routes: [{path: '/',component: () => import("@/views/Home"),},{path: '/user',component: () => import("@/views/User"),}]
})export default router;
在 main.js 中注册路由
// main.jsimport { createApp } from 'vue'
import router from './router'
import App from './app.vue'const app = createApp(App)
app.use(router).mount('#app')
在组件中使用路由
<!-- App.vue -->
<template><nav><router-link to="/">首页</router-link><router-link to="/user">用户</router-link></nav><main><router-view /></main></template>
2. 路由配置
动态路由匹配
// router/index.jsconst routes = [{path: '/user/:id',component: User,}
]
路径参数用冒号 :
表示。当一个路由被匹配时(/user/123),它的 params 的值可以使用 useRoute() 钩子函数获取。
<!-- User.vue -->
<script setup>
import { useRoute } from 'vue-router'const route = useRoute();
console.log(route.params); // {id: 123}
</script>
使用带有参数的路由时需要注意的是,当用户从 /users/122 导航到 /users/123 时,相同的组件实例将被重复使用,从而组件的生命周期钩子不会被调用。
要对同一个组件中参数的变化做出响应的话,可以使用 watch 监听 route.params。
嵌套路由
const routes = [{path: '/user/:id',component: User,children: [{ path: '', // 当 /user/:id 匹配成功component: UserHome, // UserHome 将被渲染到 User 的 <router-view> 内部},{ path: 'posts', // 当 /user/:id/posts 匹配成功component: UserPosts, // UserPosts 将被渲染到 User 的 <router-view> 内部},],},
]
注意:子路由的 path 属性中不可以带 /
,否则无法匹配。
<!-- User.vue -->
<template><div>{{ route.params.id }}</div><router-view />
</template>
3. 路由导航
<script setup>
import { useRouter } from 'vue-router'const router = useRouter()
router.push() // 导航
router.replace() // 替换
router.go(1) // 返回上一条记录
</script>
传参
const username = 'eduardo'router.push(`/user/${username}`) // -> /user/eduardorouter.push({ path: `/user/${username}` }) // -> /user/eduardo// 命名路由
router.push({ name: 'user', params: { username } }) // -> /user/eduardo// `params` 不能与 `path` 一起使用
router.push({ path: '/user', params: { username } }) // -> /user// 带查询参数
router.push({ path: '/user', query: { username } }) // -> /user?username=eduardo
4. 导航守卫
vue-router 提供的导航守卫主要用于在路由导航过程中添加一些额外的逻辑,如权限验证、数据获取等。它允许你在路由发生变化的不同阶段插入自定义的代码片段,从而控制路由的跳转和取消。
全局前置守卫
router.beforeEach
用于在路由跳转前执行一些逻辑,例如身份验证。当一个导航触发时,全局前置守卫按照创建顺序调用。
// router/index.js
const router = createRouter({ ... })router.beforeEach(async (to, from) => {if (!isAuthenticated && to.path !== '/login'){return '/login' // 检查用户是否已登录,否则重定向到登录页面}
})
- 参数
- to:即将要进入的目标
- from:当前导航正要离开的路由
- 返回值
- false:取消当前的跳转
- 路由地址:跳转到指定路由
- 不返回或返回 true / undefined:进行默认导航
全局解析守卫
router.beforeResolve
在导航被确认之前、所有组件内守卫和异步路由组件被解析之后调用。适用于在组件渲染之前获取必要的数据。例如,你可能想要根据路由参数从服务器获取数据,并在组件渲染之前将数据传递给组件。
全局后置钩子
router.afterEach
在导航完成后触发。它不改变导航本身,不能取消或重定向导航,而通常用于执行一些与导航结果相关的操作,如追踪、分析或调试。例如,你可以在这里记录页面访问统计信息。