VueRouter(二):vue-router 的使用

149 阅读4分钟

vue-router 是基于路由和组件的。

vue-router 的使用

vue-router 的基本使用

  • 创建组件;
  • 配置组件与路径的映射关系(定义路由);
  • 创建路由实例对象,将映射关系挂载到路由实例上,并且配置路由模式;
  • 导出路由实例,在 main.js 中导入并使用;
  • 使用路由:
    • 通过内置组件 router-link 来进行导航
    • 通过内置组件 router-view 来渲染组件

JavaScript

创建 /router/index.js

import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'

// 1. 导入组件
import Home from '../views/Home.vue'
import About from '../views/About.vue'

// 2. 配置组件与路径的映射关系
const routes = [
  { 
    path: '/',
    redirect: '/home' // 配置默认路径
  },
  { // 路由对象
    path: '/home',
    component: Home
  },
  {
    path: '/about',
    component: About
  }
]

// 3. 创建一个路由实例对象
const router = createRouter({
  routes, // 将映射关系挂载到路由对象上
  history: createWebHashHistory() // 配置路由模式
  // history: createWebHistory()
})

// 4. 导出路由实例
export default router

main.js 中:

// 导入路由实例
import router from '../src/router'

const app = createApp(App)

// 挂载到根组件上
app.use(router)

HTML

在任一个组件中,使用 router-link 组件来进行导航,使用 router-view 来渲染组件。

<router-link> 将呈现一个带有正确 href 属性的 <a> 标签。

<!--通过 `to` 属性来指定路径 -->
<router-link to="/home">首页</router-link>
<router-link to="/about">关于</router-link>

<!-- 路由匹配到的组件将渲染在这里 -->
<router-view />

注:router-viewrouter-link 可以不在同一个组件中。

路由懒加载

只有当路由被访问时才加载对应的组件,这样可以提高首屏的渲染效率。我们可以通过动态导入组件的方式来实现。

const routes = [
  { 
    path: '/',
    redirect: '/home'
  },
  {
    path: '/home',
    component: () => import('../views/Home.vue'),
  },
  {
    path: '/about',
    component: () => import('../views/About.vue'),
  }
]

动态导入之后,webpack 在打包时就会进行分包操作,对应的组件在打包时就会单独打包,在需要时才会被加载。

分包前:

image.png

分包后:

image.png

可以通过魔法注释的方式来对打包后的文件进行命名:

component: () => import(/* webpackChunkName: "home" */ '../views/Home.vue')

image.png

动态路由匹配

很多时候我们希望将同一匹配模式下的路由指向同一个组件。例如 '/user/kobe''/user/james',它们都是在 '/user' 这个匹配模式下的,我们希望匹配到它们时都渲染 User 组件,这时就可以使用动态路由匹配。

实现方法是,在定义路由时我们不要把路径写死,而是在路径中使用动态的字段:

  {
    // 通过 :字段名 的方式来定义动态的字段
    path: '/user/:username',
    component: () => import('../views/User.vue')
  }

在进行跳转时,我们需要传递一个确切的路径:

<router-link to="/user/kobe">用户</router-link>
<!-- 或者是 -->
<router-link to="/user/james">用户</router-link>

在组件中,我们可以获取到对应的路由对象,也就可以获取到对应的 路径参数

<!-- 在模板中通过 $route 来获取路由对象 -->
<div>{{ $route.params.username }}</div>
import { useRoute } from 'vue-router'

export default {
  setup() {
    // 在 setup 函数中通过 useRoute 方法来获取路由对象
    const route = useRoute()
    console.log(route.params.username)
  }
}

404 Not Found 路由

对于那些没有匹配到的路由,我们通常会匹配到固定的某个页面:

{
    path: '/:pathMatch(.*)*',
    component: () => import('../views/NotFound.vue')
}

在组件中可以通过 $route.params.pathMatch 获取到路径参数。

嵌套路由(嵌套组件)

目前我们匹配的HomeAboutUser 等都属于底层路由,我们在它们之间可以来回进行切换,但是呢,Home 页面本身,也可能会在多个组件之间来回切换,这个时候我们就需要使用嵌套路由,在 Home 中也使用 router-view 来占位之后需要渲染的组件。

嵌套路由在配置时,是直接在上一级路由中通过 children 属性来设置的。

子路由的路径在设置时不需要在前面加上 /,在跳转时会自动对路径进行拼接。

例如,嵌套路由如下:

{
  path: '/home',
  component: () => import('../views/Home.vue'),
  // 通过 children 属性来配置嵌套路由
  children: [
    {
      path: 'message',
      component: () => import('../views/HomeMessage.vue')
    },
    {
      path: 'shop',
      component: () => import('../views/HomeShop.vue')
    }
  ]
}

那么,在跳转时,我们跳转的路径就是:

<router-link to="/home/message">消息</router-link>
<router-link to="/home/shop">商品</router-link>

路由传参

动态添加路由

某些情况下我们可能需要动态的来添加路由,这个时候我们可以使用 addRoute 方法。

动态添加一级路由

const addRoutes = [
  {
    path: '/books',
    component: () => import('../views/Books.vue')
  }
]

router.addRoute(addRoutes)

动态添加二级路由

// 一级路由
{
  path: '/home',
  name: 'Home',
  component: () => import('../views/Home.vue')
}
const addRoutes = [
  {
    path: 'books',
    component: () => import('../views/Books.vue')
  }
]

router.addRoute('Home', addRoutes)

路由导航守卫

有些时候我们需要在路由进行跳转的时候进行一些操作,比方说如果判断用户没有登录,就跳转到登录页面或者是不允许跳转,这个时候就需要用到导航守卫。

前置导航守卫 beforeEach,在路由跳转之前触发。

router.beforeEach((to, from) => {
  // to 即将进入的 route 对象
  // from 即将离开的 route 对象
  
  /** 
    返回值:
       false: 不进行跳转
       undefined 或者没有返回值:直接跳转
       字符串:路径,跳转到该路径
       对象:类似于 router.push({})
  */
  return
})

routerroute 的区别?