Skip to Content

实现

1.创建路由实例

  • 使用createRouter来创建路由实例,它接受一个对象,其中包含history和routes两个属性
  • history: 指定路由的历史记录模式。常见的模式有 createWebHistory(HTML5 模式)和 createWebHashHistory(Hash 模式)
  • routes: 定义了一系列路由规则,每个规则包括 path(路径)、name(名称)和 component(组件)
import {createRouter, createWebHistory} from 'vue-router' const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ { path: '/home',// 首页 name: 'Home', component: () => import('../views/Home/Home.vue'), }, { path: '/detail/:id',// 详情页 name: 'Detail', component: () => import('../views/Detail/Detail.vue') }, { path: '/', redirect: '/svg'// 重定向到首页 }, { path: '/:pathMatch(.*)*', // 匹配不到的路由,跳转到404页面 name: 'NotFound', component: () => import('../views/404.vue') } ] })

2.配置路由守卫

前置守卫

  • 通过跳转或取消的方式来守卫导航,在每次导航时会触发
  • 注册全局前置守卫: router.beforeEach()
  • 参数: to, from
  • 返回: Boolean, route
router.beforeEach(async (to, from) => { if ( // 检查用户是否已登录, 并避免无限重定向 !isAuthenticated && to.name !== 'Login' ) { // 将用户重定向到登录页面 return { name: 'Login' } } })

解析守卫

  • 类似于前置守卫,但在导航确认之前,异步路由解析之后触发
  • 能够确保用户导航确认后正确获取到数据,以及避免错误执行操作
router.beforeResolve(async to => { if (to.meta.requiresCamera) { try { await askForCameraPermission()//获取用户访问摄像头的权限 } catch (error) { if (error instanceof NotAllowedError) { // ... 处理错误,然后取消导航 return false } else { // 意料之外的错误,取消导航并把错误传给全局处理器 throw error } } } })

组件内守卫

  • 在组件内部注册路由守卫,只对该组件生效
beforeRouteEnter(to, from) { // 在渲染该组件的对应路由被验证前调用 // 不能获取组件实例 `this` ! // 因为当守卫执行时,组件实例还没被创建! }, beforeRouteUpdate(to, from) { // 在当前路由改变,但是该组件被复用时调用 // 举例来说,对于一个带有动态参数的路径 `/users/:id`,在 `/users/1` 和 `/users/2` 之间跳转的时候, // 由于会渲染同样的 `UserDetails` 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。 // 因为在这种情况发生的时候,组件已经挂载好了,导航守卫可以访问组件实例 `this` }, beforeRouteLeave(to, from) { // 在导航离开渲染该组件的对应路由时调用 // 与 `beforeRouteUpdate` 一样,它可以访问组件实例 `this` },

3.导出路由

  • 将创建的路由器实例 router 导出,以便在应用的其他部分使用。
export default router

4.使用路由

获取路由信息

  • useRoute(): 返回当前路由信息
  • useRouter(): 返回路由器实例
//导航完成后获取数据, 在数据获取期间显示“加载中”的指示 import { ref, watch } from 'vue' import { useRoute } from 'vue-router' import { getPost } from './api.js' const route = useRoute() const loading = ref(false) const post = ref(null) const error = ref(null) // 侦听路由的参数,以便再次获取数据 watch(() => route.params.id, fetchData, { immediate: true }) async function fetchData(id) {//这里的id是响应式数据源route.params.id的变化后的新值 error.value = post.value = null loading.value = true try { // 用获取数据的工具函数 / API 包裹器替换 `getPost` post.value = await getPost(id) } catch (err) { error.value = err.toString() } finally { loading.value = false } }

进行路由导航

  • router.push(): 导航到不同的位置, 会在历史堆栈内留下足迹
  • router.replace(): 替换当前路由位置,因此不会记录到历史堆内
  • router.go(): 在历史堆栈中前进或后退多少步
router.push({ path: `/user/${username}` }) // -> /user/eduardo // 如果可能的话,使用 `name` 和 `params` 从自动 URL 编码中获益 router.push({ name: 'user', params: { username } }) // -> /user/eduardo // `params` 不能与 `path` 一起使用 router.push({ path: '/user', params: { username } }) // -> /user router.push({ path: '/home', replace: true }) router.replace({ path: '/home' }) router.go(3)
Last updated on