vue-router

目前前端流行的三大框架, 都有自己的路由实现:

  • Angular:ngRouter

  • React:ReactRouter

  • Vue:vue-router

Vue Router 是 Vue.js 的官方路由:

它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用(SPA)变得非常容易。

vue-router是基于路由和组件的:路由用于设定访问路径, 将路径和组件映射起来;

在vue-router的单页面应用中, 页面路径的改变就是组件的切换。

01. 基本使用

1.1 安装Vue Router

npm install vue-router

1.2 使用步骤

使用vue-router的步骤:

  • 第一步:创建路由需要映射的组件(打算显示的页面);

  • 第二步:通过createRouter创建路由对象,并且传入routes和history模式;

配置路由映射: 组件和路径映射关系的routes数组;

创建基于hash或者history的模式;

  • 第三步:使用app注册路由对象(use方法);

  • 第四步:路由使用: 通过<router-link><router-view>

目录结构图:

router/index.js:

main.js:

app.vue:

02. router-link属性

router-link有很多属性可以配置:

  • to属性:是一个字符串,或者是一个对象;

  • replace属性:设置 replace 属性的话,当点击时,会调用 router.replace(),而不是 router.push();

  • active-class属性:设置激活a元素后应用的class,默认是router-link-active;

  • exact-active-class属性:链接精准激活时,应用于渲染的 的 class,默认是router-link-exact-active;

03. 路由懒加载

前面我们提到过,如果项目的业务逻辑很多,组件很多,当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。

如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就能提高首屏的渲染效率;

其实这里还是我们前面讲到过的webpack的分包知识,而Vue Router默认就支持动态来导入组件:

这是因为component可以传入一个组件,也可以接收一个函数,该函数 需要返回一个Promise;

使用import导入,打包时会进行分包处理。

04. 其他属性

name属性:路由记录独一无二的名称;

meta属性:自定义的数据

05. 动态路由

很多时候我们需要将给定匹配模式的路由映射到同一个组件,

例如,我们可能有一个 User 组件,它应该对所有用户进行渲染,但是用户的ID是不同的,

在Vue Router中,我们可以在路径中使用一个动态字段来实现,我们称之为 路径参数

在router-link中进行如下跳转:

如果在子组件中,需要用到路由中传递的值,可以通过$route.params.id来获取。

06. NotFound

对于那些没有匹配到的路由,我们通常会将之匹配到固定的某个页面 --> NotFount页面。

{
// abc/cba/nba
// path: "/:pathMatch(.*)*", // 这种写法会对路径进行解析,返回数组。
path: "/:pathMatch(.*)",
component: () => import("../Views/NotFound.vue")
}

我们可以通过 $route.params.pathMatch 获取传入的参数:

<template>
<div class="not-found">
<h2>NotFound: 您当前的路径{{ $route.params.pathMatch }}不正确, 请输入正确的路径!</h2>
</div>
</template> <script setup>
</script> <style scoped> .not-found {
color: red;
} </style>

07. 编程式导航

前面我们都是通过<router-link>进行路由跳转。

但有时候,我们也需要使用其他标签,比如span标签、button标签,来进行路由跳转。

应该怎么实现呢?需要通过事件来进行。

这种方式称之为“编程式导航”。

<template>
<div class="app">
<div class="nav">
<router-link to="/home" replace>首页</router-link>
<router-link to="/about" replace active-class="active">关于</router-link> <!-- 其他元素跳转 -->
<span @click="homeSpanClick">首页</span>
<button @click="aboutBtnClick">关于</button>
</div>
<router-view></router-view>
</div>
</template>
<script setup>
import { useRouter } from 'vue-router' const router = useRouter() // 监听元素的点击
function homeSpanClick() {
// 跳转到【首页】
// router.push("/home") // 简单写法
router.push({
// name: "home"
path: "/home"
})
}
function aboutBtnClick() {
// 跳转到【关于】
router.push({
path: "/about",
query: {
name: "why",
age: 18
}
})
} </script>

某些页面中,我们也会添加【返回】,或【向前】按钮。

让用户根据自己的浏览路径,实现向前跳转与向后跳转。

实现方法同样是拿到router对象。

  • router.back():向后跳转
  • router.forward():向前跳转
  • go(delta):delta为跳转步数。正数表示向前跳转;负数表示向后跳转。
<script setup>
import { useRouter } from 'vue-router' const router = useRouter() function backBtnClick() {
// router.back()
// router.forward() // go(delta)
// go(1) -> forward()
// go(-1) -> back()
router.go(-1)
} </script>

08. 动态管理路由

某些情况下我们可能需要动态地添加路由,比如根据用户角色的不同、权限的不同,注册不同的路由,

这时候我们可以使用一个方法addRouter。

// 模拟管理员
let isAdmin = true // 给管理员添加专属于管理员的路由
if (isAdmin) {
// 添加一级路由
router.addRoute({
path: "/admin",
component: () => import("../Views/Admin.vue")
}) // 添加二级路由,第一个参数传入父级路由的name
router.addRoute("home", {
path: "vip", // 注意,不用书写成 /home/vip
component: () => import("../Views/HomeVip.vue")
})
}

8.1 删除路由

删除路由的情景比较少,删除路由有三种方式:

  • 添加name相同的路由,那么后者将会替换前者;
  • 通过removeRouter方法,传入路由的名称;
  • 通过addRouter方法的返回值回调;

8.2 路由的其他方法

  • router.hasRouter():检查路由是否存在;
  • router.getRoutes():获取一个包含所有路由记录的数组。

09. 导航守卫

对于某些页面,比如由【商场首页】跳转【个人中心】,在路由跳转之前,需要先验证用户是否已经登录了:

  • 用户已经登录,则顺利跳转;
  • 用户没有登录,则跳转到登录页面。

从某一路由跳转到另一路由,这个过程称之为“导航”;

而在导航前做逻辑判断,或者导航后执行某一逻辑,这种功能即称之为“导航守卫”,

vue-router 也提供了对应的导航守卫功能:

  • 全局前置守卫beforeEach
  • 全局解析守卫beforeResolve
  • 全局后置守卫afterEach(全局后置钩子)
  • ...

参考官网:https://router.vuejs.org/zh/guide/advanced/navigation-guards.html

全局前置守卫

全局前置守卫beforeEach,传入一个函数,该函数在导航触发时会自动执行。

前置守卫:在跳转之前进行守卫。

router.beforeEach((to,from)=>{
console.log(to)
console.log(from) // 获取登录凭证
const token = localStorage.getItem("token") // 没有登录凭证,且将跳转的路由并非登录界面,
if (to.path !== "/login" && !token) {
return "/login" // 对象写法
// return { name: 'Login' }
} // return false
})

它有两个参数:

  • to:即将进入的路由Route对象;

  • from:即将离开的路由Route对象;

可以设置返回值:

  • false:取消当前导航;

  • 不返回或者undefined:进行默认导航;

  • 也可以返回一个路由地址,将跳转到该路由地址,就像你调用 router.push() 一样。

    • 可以是一个string类型的路径;

    • 可以是一个对象,对象中包含path、query、params等信息;

可选的第三个参数:next(不推荐使用)

在Vue2中我们是通过next函数来决定如何进行跳转的;

但是在Vue3中我们是通过返回值来控制的,不再推荐使用next函数,这是因为开发中很容易调用多次next;

全局后置钩子

你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:

router.afterEach((to, from) => {
sendToAnalytics(to.fullPath)
})

它们对于分析、更改页面标题、声明页面等辅助功能以及许多其他事情都很有用。

它们也反映了 navigation failures 作为第三个参数:

router.afterEach((to, from, failure) => {
if (!failure) sendToAnalytics(to.fullPath)
})

路由独享的守卫

你可以直接在路由配置上定义 beforeEnter 守卫:

const routes = [
{
path: '/users/:id',
component: UserDetails,
beforeEnter: (to, from) => {
// reject the navigation
return false
},
},
]

beforeEnter 守卫 只在进入路由时触发,不会在 paramsqueryhash 改变时触发。例如,从 /users/2 进入到 /users/3 或者从 /users/2#info 进入到 /users/2#projects。它们只有在 从一个不同的 路由导航时,才会被触发。

你也可以将一个函数数组传递给 beforeEnter,这在为不同的路由重用守卫时很有用:

function removeQueryParams(to) {
if (Object.keys(to.query).length)
return { path: to.path, query: {}, hash: to.hash }
} function removeHash(to) {
if (to.hash) return { path: to.path, query: to.query, hash: '' }
} const routes = [
{
path: '/users/:id',
component: UserDetails,
beforeEnter: [removeQueryParams, removeHash],
},
{
path: '/about',
component: UserDetails,
beforeEnter: [removeQueryParams],
},
]

完整的导航解析流程

  1. 导航被触发。
  2. 在失活的组件里调用 beforeRouteLeave 守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫(2.2+)。
  5. 在路由配置里调用 beforeEnter
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter
  8. 调用全局的 beforeResolve 守卫(2.5+)。
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

Vue04-vue-router的更多相关文章

  1. Vue04——vue自定义事件、Router、Vue-cli、发布上线

    一.Vue的自定义事件 点击任何一个按钮,按钮本身计数累加,但是每点击三个按钮中的一个,totalCounter 都要累加. <body> <div id="app&quo ...

  2. Vue 2.0 + Vue Router + Vuex

    用 Vue.js 2.x 与相配套的 Vue Router.Vuex 搭建了一个最基本的后台管理系统的骨架. 当然先要安装 node.js(包括了 npm).vue-cli 项目结构如图所示: ass ...

  3. vue router 只需要这么几步

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  4. Vue.js 2.x笔记:路由Vue Router(6)

    1. Vue Router简介与安装 1.1 Vue Router简介 Vue Router 是 Vue.js 官方的路由管理器.它和 Vue.js 的核心深度集成,构建单页面应用. Vue Rout ...

  5. Vue Router学习笔记

    前端的路由:一个地址对应一个组件 Vue Router中文文档 一.路由基本使用 第1步:导入Vue Router: <script src="https://unpkg.com/vu ...

  6. vue router.push(),router.replace(),router.go()和router.replace后需要返回两次的问题

    转载:https://www.cnblogs.com/lwwen/p/7245083.html https://blog.csdn.net/qq_15385627/article/details/83 ...

  7. 前端MVC Vue2学习总结(八)——Vue Router路由、Vuex状态管理、Element-UI

    一.Vue Router路由 二.Vuex状态管理 三.Element-UI Element-UI是饿了么前端团队推出的一款基于Vue.js 2.0 的桌面端UI框架,手机端有对应框架是 Mint U ...

  8. 深入浅出的webpack4构建工具---webpack+vue+router 按需加载页面(十五)

    1. 为什么需要按需加载? 对于vue单页应用来讲,我们常见的做法把页面上所有的代码都打包到一个bundle.js文件内,但是随着项目越来越大,文件越来越多的情况下,那么bundle.js文件也会越来 ...

  9. 深入浅出的webpack构建工具--webpack4+vue+router项目架构(十四)

    阅读目录 一:vue-router是什么? 二:vue-router的实现原理 三:vue-router使用及代码配置 四:理解vue设置路由导航的两种方法. 五:理解动态路由和命名视图 六:理解嵌套 ...

  10. python 全栈开发,Day91(Vue实例的生命周期,组件间通信之中央事件总线bus,Vue Router,vue-cli 工具)

    昨日内容回顾 0. 组件注意事项!!! data属性必须是一个函数! 1. 注册全局组件 Vue.component('组件名',{ template: `` }) var app = new Vue ...

随机推荐

  1. c#如何使用WASM跨语言调用?

    介绍Wasm(WebAssembly) WebAssembly(简称Wasm)是一种用于基于堆栈的虚拟机的二进制指令格式.Wasm被设计为编程语言的可移植编译目标,支持在web上部署客户端和服务器应用 ...

  2. 银河麒麟等 Linux系统 安装 .net 5,net 6及更高版本的方法

    最近项目上用到 银河麒麟的操作系统,需要搭建 .net 跨平台方案.一开始使用各种命令都安装不上,很多提示命令找不到,或者下载包时候网络无法下载. 网上教程很多,但没有一个是成功的,多数使用 apt ...

  3. Programming abstractions in C阅读笔记:p84-p87

    <Programming Abstractions In C>学习第43天,p84-p87总结. 一.技术总结 1.record record也称为structure(结构体),是一种数据 ...

  4. 一台服务器上部署 Redis 伪集群

    哈喽大家好,我是咸鱼 今天这篇文章介绍如何在一台服务器(以 CentOS 7.9 为例)上通过 redis-trib.rb 工具搭建 Redis cluster (三主三从) redis-trib.r ...

  5. (2023.8.28)Hi铁布衫-CM Ver 0.001 - Cracked-writeup

    Hi铁布衫-CM Ver 0.001 WriteUp 本文作者:XDbgPYG(小吧唧) 发布时间:2023年8月28日 内容概要:Hi铁布衫-CM Ver 0.001 WriteUp 收集信息 有一 ...

  6. Llama2-Chinese项目:2.1-Atom-7B预训练

      虽然Llama2的预训练数据相对于第一代LLaMA扩大了一倍,但是中文预训练数据的比例依然非常少,仅占0.13%,这也导致了原始Llama2的中文能力较弱.为了能够提升模型的中文能力,可以采用微调 ...

  7. dubbo+zookeeper+springboot远程连接,虚拟机和主机分布式操作

    dubbo+zookeeper+springboot远程连接,虚拟机和主机分布式操作 springboot版本:阿里云2.3.7 实现目标 在主机上的消费者可以调用虚拟机中生产者的接口方法 项目目录 ...

  8. Apache(2.4.49 2.4.50)--目录遍历--命令执行--(CVE-2021-42013)&&(CVE-2021-41773)

    Apache(2.4.49 2.4.50)--目录遍历--命令执行--(CVE-2021-42013)&&(CVE-2021-41773) 复现环境 采用Vulfocus靶场环境进行复 ...

  9. 探索抽象同步队列 AQS

    by emanjusaka from https://www.emanjusaka.top/archives/8 彼岸花开可奈何 本文欢迎分享与聚合,全文转载请留下原文地址. 前言 AbstractQ ...

  10. MySQL实战实战系列 06 全局锁和表锁 :给表加个字段怎么有这么多阻碍?

    今天我要跟你聊聊 MySQL 的锁.数据库锁设计的初衷是处理并发问题.作为多用户共享的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则.而锁就是用来实现这些访问规则的重要数据结构. 根据 ...