加载中...
知识补充:Router 4
第1节:项目介绍
第2节:项目后端准备和接口文档
第3节:知识补充:Router 4
第4节:知识补充:Pinia
第5节:vite 配置
第6节:Axios 封装
课文封面

Vue Router 就是用来处理这种基于组件的动态路由系统。
使页面之间的切换不再像传统的多页应用那样重新加载整个页面,而是通过改变 URL 并且仅替换应用程序中的一部分视图来实现。
这节课将介绍后续项目中将用到的 Vue Router 4 的基础知识点。

Vue Router 是 Vue.js 官方提供的路由管理器,它与 Vue.js 核心深度集成,使得构建单页面应用(SPA)变得容易。在单页面应用中,所有视图和组件都通过路由来管理和切换,而不是传统的整页刷新。

在本课文中将介绍Vue Router的一些常用方法。

视频🎞️

安装

新建项目

npm create vite@latest
创建项目时选择Customize with create-vue,并且选择引入 Vue Router 进行单页面应用开发,其他选项可以按需进行选择。
这样创建的项目已经初始化好Vue Router文件配置。可以开箱即用。

已有项目

  1. 在终端中输入npm install vue-router@4
  2. 创建router/index.js
import { createRouter, createWebHistory } from 'vue-router' const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ ... // 页面路由配置 ] }) export default router
  1. 在main.js中引入router/index.js,并且通过app.use()明确地安装路由功能
... ... import { createApp } from 'vue' import App from './App.vue' import router from './router' // 导入创建的js const app = createApp(App) app.use(router) // 安装路由功能 app.mount('#app')

页面组件的内容将在<RouterView/>中渲染。

routes配置

history模式配置

HTML5 模式(推荐)

createWebHistory()
url效果:http://example.com/myroute
url看上去和正常的链接一样干净,需要注意在生产环境中要进行配置,使得任何非静态资源请求(如 /about、/dashboard 等)都被重定向到应用的入口 HTML 文件(通常是 index.html),否则会出现404。

import { createRouter, createWebHistory } from 'vue-router' const router = createRouter({ history: createWebHistory(), // HTML5 模式 routes: [ // ... ] }) export default router

Hash 模式

createWebHashHistory()
url效果:http://example.com/#/myroute
它在内部传递的实际 URL 之前使用了一个哈希字符(#)。由于这部分 URL 从未被发送到服务器,所以它不需要在服务器层面上进行任何特殊处理。但是seo效果不好。

import { createRouter, createWebHashHistory} from 'vue-router' const router = createRouter({0 history: createWebHashHistory(), // Hash 模式 routes: [ // ... ] }) export default router

路由组件导入方法

静态导入

静态导入会在应用启动时随主资源一同加载,当模块多的时候容易造成首屏加载时间过长,

import { createRouter, createWebHistory } from 'vue-router' // 静态导入页面组件 import HomeView from '../views/HomeView.vue' const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ { path: '/', name: 'home', // 使用引入的路由组件 component: HomeView } ] }) export default router

懒加载

当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。
如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就会更加高效。

import { createRouter, createWebHistory } from 'vue-router' // 动态导入页面组件 const AboutView = () => import('../views/AboutView.vue') const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ { path: '/about', name: 'about', component: AboutView } ] }) export default router

路由传参

方式一:query

使用query传参会跟传统的参数一样,? 跟在url后面,多个参数以 & 隔开。

import {useRouter} from "vue-router"; const $router = useRouter() function onToView(){ $router.push({path:'/user',query:{text:'UserView'}}) // $router.push('/user?text=UserView') // 自己拼接url }

方式二:params

需要先在路由配置中使用 :参数名 来配置参数

routes: [ // ... { path: '/user/:id', //配置id参数 name: 'user', component: () => import('../views/UserView.vue'), } // ... ]

当使用path时,params属性会被忽略,所以要么使用name属性,或者自己拼接url

import {useRouter} from "vue-router"; const $router = useRouter() function onToView(){ let id = 0 $router.push({name:'user',params:{id:id}}) // $router.push(`/user/${id}`) // 自己拼接url }

元信息

当需要一些信息附加到路由上时,可以通过配置路由元信息来实现,比如是否需要登录才能访问,设置页面切换过渡效果,是否要缓存该页面…

routes: [ // ... { path: '/', name: 'home', meta: {checkLogin: true}, // 配置元信息 component: () => import('../views/HomeView.vue'), } // ... ]

单独配置元信息不会起到任何作用,还需要写相应的代码来达成期望效果;
例如通过元信息配置部分页面需要使用<keep-alive/>缓存

<template> <router-view v-slot="{ Component }"> <keep-alive :include="cacheRouteName"> <component :key="$route.name" :is="Component" /> </keep-alive> </router-view> </template> <script setup> import { useRouter } from "vue-router" const router = useRouter() // 从路由中获取带有缓存元数据的路由名称 const cacheRouteName = router .getRoutes() .filter((item) => item.meta?.cache) // 过滤出带有缓存元数据的路由 .map((item) => item.name) // 提取路由名称 </script>

路由守卫

路由守卫主要用来通过跳转或取消的方式守卫导航。

每个路由守卫接收两个参数

  • to:代表即将要进入的路由
  • from:代表当前即将离开的路由

可选的第三个参数next
当设置该参数时,需要确保在路由守卫中执行一次next()若未调用,则页面导航将被阻塞,无法正常跳转。它可以出现多次,但应只执行一次。
next方法中可以传递path来重定向到其它页面

router.beforeEach((to, from, next) => { if (/* 用户未登录 */) { next('/login'); // 通过 next 方法重定向到登录页 } else { next(); // 继续正常跳转 } });
import { createRouter, createWebHistory } from 'vue-router'; const router = createRouter({ history: createWebHistory(), routes: [ // 定义路由 { path: '/home', component: Home, // 路由独享的守卫 beforeEnter: (to, from, next) => { // 在进入路由前执行的逻辑 // 可以进行权限验证等操作 next(); // 调用next()继续路由导航 } }, // 其他路由定义 ] }); // 全局前置路由守卫 router.beforeEach((to, from, next) => { // 在进入每个路由前执行的逻辑 // 可以进行全局的权限验证等操作 next(); // 调用next()继续路由导航 }); export default router;