2024年最新Vue全家桶 Vue-router的详细介绍_v-router,面试加分项

文末

技术是没有终点的,也是学不完的,最重要的是活着、不秃。

零基础入门的时候看书还是看视频,我觉得成年人,何必做选择题呢,两个都要。喜欢看书就看书,喜欢看视频就看视频。

最重要的是在自学的过程中,一定不要眼高手低,要实战,把学到的技术投入到项目当中,解决问题,之后进一步锤炼自己的技术。

自学最怕的就是缺乏自驱力,一定要自律,杜绝“三天打鱼两天晒网”,到最后白忙活一场。

高度自律的同时,要保持耐心,不抛弃不放弃,切勿自怨自艾,每天给自己一点点鼓励,学习的劲头就会很足,不容易犯困。

技术学到手后,找工作的时候一定要好好准备一份简历,不要无头苍蝇一样去海投简历,容易“竹篮打水一场空”。好好的准备一下简历,毕竟是找工作的敲门砖。

拿到面试邀请后,在面试的过程中一定要大大方方,尽力把自己学到的知识舒适地表达出来,不要因为是自学就不够自信,给面试官一个好的印象,面试成功的几率就会大很多,加油吧,骚年!

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

+ [动态添加路由](#_874)
+ [路由导航守卫](#_965)
+ - [🍚beforeEach守卫函数](#beforeEach_967)
	- [🍚其他导航守卫(了解)](#_1043)

v-router

前端路由的发展历程

🍤认识路由

认识前端路由之前, 我们先认识一下什么是路由

路由其实是网络工程中的一个术语

在架构一个网络时,非常重要的两个设备就是路由器和交换机。

当然,目前在我们生活中路由器也是越来越被大家所熟知,因为我们生活中都会用到路由器:

事实上,路由器主要维护的是一个映射表;

映射表会决定数据的流向;

路由的概念在软件工程中出现,最早是在后端路由中实现的

也就是说, 早期根本没有前端路由这一说法, 原因是web的发展主要经历了这样一些阶段

  1. 后端路由阶段;
  2. 前后端分离阶段;
  3. 单页面富应用(SPA);

🍤后端路由的阶段

早期的网站开发整个HTML页面是由服务器来渲染的.

服务器直接生产渲染好对应的HTML页面, 返回给客户端进行展示.

但是, 一个网站, 这么多页面服务器如何处理呢?

一个页面有自己对应的网址, 也就是URL;

URL会发送到服务器, 服务器会通过正则对该URL进行匹配, 并且最后交给一个Controller进行处理;

Controller进行各种处理, 最终生成HTML或者数据, 返回给前端.

上面的这种操作, 就是后端路由

当我们页面中需要请求不同的路径内容时, 交给服务器来进行处理, 服务器渲染好整个页面, 并且将页面返回给客户端.

这种情况下渲染好的页面, 不需要单独加载任何的js和css, 可以直接交给浏览器展示, 这样也有利于SEO的优化.

后端路由的缺点:

一种情况是整个页面的模块由后端人员来编写和维护的;

另一种情况是前端开发人员如果要开发页面, 需要通过PHP和Java等语言来编写页面代码;

而且通常情况下HTML代码和数据以及对应的逻辑会混在一起, 编写和维护都是非常糟糕的事情;


🍤前后端分离阶段

前端渲染的理解

每次请求涉及到的静态资源都会从静态资源服务器获取,这些资源包括HTML+CSS+JS,然后在前端对这些请求回来的资源进行渲染;

需要注意的是,客户端的每一次请求,都会从静态资源服务器请求文件;

同时可以看到,和之前的后端路由不同,这时后端只是负责提供API了;

前后端分离阶段

随着Ajax的出现, 有了前后端分离的开发模式;

后端只提供API来返回数据,前端通过Ajax获取数据,并且可以通过JavaScript将数据渲染到页面中;

这样做最大的优点就是前后端责任的清晰,后端专注于数据上,前端专注于交互和可视化上;

并且当移动端(iOS/Android)出现后,后端不需要进行任何处理,依然使用之前的一套API即可;

目前比较少的网站采用这种模式开发;


🍤单页面富应用阶段

单页面富应用阶段:

其实SPA最主要的特点就是在前后端分离的基础上加了一层前端路由.

也就是前端来维护一套路由规则.

前端路由的核心是什么呢?

改变URL,但是页面不进行刷新。

有两种模式可以做到改变URL, 但是页面不刷新:

URL的hash

HTML5的History

目前常见的路由都是采用的以上两种模式之一:

  • 例如vue中的router, react中的router, 都是采用的这两种模式

模式一: URL的hash:

URL的hash也就是锚点(#), 本质上是改变window.location的href属性;

我们可以通过直接赋值location.hash来改变href, 但是页面不发生刷新;

<div class="app">
  <a href="#/home">home</a>
  <a href="#/about">about</a>
  <div class="router-view"></div>
</div>

// 1.获取router-view
const routerViewEl = document.querySelector(".router-view");

// 2.监听hash改变
window.addEventListener("hashchange", () => {
  switch (location.hash) {
    case "#/home":
      routerViewEl.innerHTML = "home";
    case "#/about":
      routerViewEl.innerHTML = "about";
    default:
      routerViewEl.innerHTML = "default";
  }
});

hash的优势就是兼容性更好,在老版IE中都可以运行,但是缺陷是有一个#,显得不像一个真实的路径

模式二: HTML5的History

history接口是HTML5新增的, 它有六种模式改变URL而不刷新页面

replaceState:替换原来的路径;

pushState:使用新的路径;

popState:路径的回退;

go:向前或向后改变路径;

forward:向前改变路径;

back:向后改变路径;


v-router使用

🍔v-router基本使用

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

Angular的ngRouter

React的ReactRouter

Vue的vue-router

Vue Router 是 Vue.js 的官方路由

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

目前Vue路由最新的版本是4.x版本,我们上课会基于最新的版本讲解;

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

路由用于设定访问路径, 将路径和组件映射起来

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

安装Vue Routernpm install vue-router


使用vue-router的步骤:

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

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

  • 配置路由映射: 组件和路径映射关系的routes数组;
  • 创建基于hash或者history的模式;

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

第四步:路由使用, 通过和;

🍔v-router使用流程

路由基本使用的流程如下:

先在一个单独的js文件中配置映射关系, 以及要使用的模式 (hash/history):

// 1.导入createRouter函数/方法, 以及要使用的hash模式
import { createRouter, createWebHashHistory } from "vue-router";

// 3.导入要配置映射关系的组件
import Home from "../views/Home.vue"
import About from "../views/About.vue"

// 2.通过createRouter创建一个路由: 映射关系
const router = createRouter({
  // 指定要是使用的模式: hash/history, 这里指定的hash
  history: createWebHashHistory(),
  // 传入一个对象, 对象中通过routes维护映射关系
  routes: [
    { path: "/home", component: Home },
    { path: "/about", component: About }
  ]
})

// 4.将路由导出, 供外界使用
export default router

在main.js文件中, 导入路由并使用app.use函数注册路由:

import { createApp } from 'vue'
import App from './App.vue'

// 导入路由
import router from './router'

const app = createApp(App)

// 使用app的use方法注册路由
app.use(router)

app.mount('#app')


通过的to属性, 可以设置调转到哪一个url; 通过设置组价要展示的位置

<template>
  <div class="app">
    <h2>App</h2>
    <!-- 设置要跳转的url -->
    <!-- 点击首页, url会自动拼接上/#/home, Home组件 就会替换下面的router-view -->
    <router-link to="/home">首页</router-link>
    <!-- 点击关于, url会自动拼接上/#/about, About组件 就会替换下面的router-view -->
    <router-link to="/about">关于</router-link>

    <!-- 设置组件要展示的位置 -->
    <router-view></router-view>
  </div>
</template>

🍔v-router细节补充

补充一: 配置默认路由

我们这里还有一个不太好的实现:

默认情况下, 进入网站的首页, 我们希望渲染首页的内容;

但是刚刚我们的实现中, 默认没有显示首页组件, 必须让用户点击才可以;

如何可以让路径默认跳到到首页, 并且渲染首页组件呢?

const router = createRouter({
  history: createWebHashHistory(),
  routes: [
    // 添加一个映射关系, 设置默认的展示页面
    { path: "/", redirect: "/home" },
    { path: "/home", component: Home },
    { path: "/about", component: About }
  ]
})

我们在routes中又配置了一个映射

path配置的是根路径: /

redirect的中文意思是从定向

也就是我们将根路径重定向到/home的路径下, 这样就可以得到我们想要的结果了, 用户打开页面就会默认跳转到首页


补充二: history模式

我们前面使用的是hash模式, 由于hash模式会在url中拼接一个井号: #会让人一部分人感觉并不舒服, 有一种地址不真实的感觉, 这个时候也可以采用另外一种模式: history模式

// 使用history模式 
import { createRouter, createWebHistory } from "vue-router";

const router = createRouter({
  // 使用history模式
  history: createWebHistory(),
  routes: [
    { path: "/", redirect: "/home" },
    { path: "/home", component: Home },
    { path: "/about", component: About }
  ]
})

history模式中, url的地址不会拼接上井号

在这里插入图片描述

当然两种模式各有优缺点, 有人喜欢hash, 觉得url结构清晰, 有人喜欢history, 不喜欢看到井号

两种模式大家无须纠结, 根据自己喜好选择即可


补充三: router-link的属性

刚刚我们有简单使用router-link的属性

router-link事实上有很多属性可以配置

to属性

用于指定点击当前的router-link跳转到哪一个路径

是一个字符串,或者是一个对象

<router-link :to="{ path: '/home' }">首页</router-link>
<router-link to="/about">关于</router-link>

replace属性

replace不用设置属性值

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

replace相当于是一种模式, 当在replace模式下, 点击路由切换时, 是没有历史记录

<router-link to="/home" replace>首页</router-link>
<router-link to="/about" replace>关于</router-link>

active-class属性

当router-link被选中是会自动添加上一个class,默认是router-link-active

例如我们想要设置当前显式页面的router-link变为红色, 我们可以直接设置router-link-active这个class

.router-link-active {
  color: red;
}

如果不想使用它默认的名字, 我们也可以通过active-class属性, 自己定义一个class名字

<router-link to="/home" active-class="home">首页</router-link>
<router-link to="/about" active-class="home">关于</router-link>

.home {
  color: red;
}

exact-active-class属性(下面路由嵌套时会讲解)

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


懒加载分包处理

当打包构建应用时,JavaScript 包会变得非常大,影响页面加载

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

也可以提高首屏的渲染效率;

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

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

而import函数就是返回一个Promise;

// 使用import函数, 打包时会进行分包处理
routes: [
  { 
    path: "/", 
    redirect: "/home" 
  },
  { 
    path: "/home",
    component: () => import("../views/Home.vue")
  },
  { 
    path: "/about", 
    component: () => import("../views/About.vue")
  }
]

打包效果如下

在这里插入图片描述

但是我们发现, 打包之后虽然分包了, 但是我们无法分清楚哪一个打包的文件是Home, 哪一个打包的文件是About

其实webpack从3.x开始支持对分包进行命名(chunk name)

 routes: [
  // 添加一个映射关系, 设置默认的展示页面
  { 
    path: "/", 
    redirect: "/home" 
  },
  { 
    path: "/home",
    component: () => import(/\* webpackChunkName: 'home' \*/"../views/Home.vue")
  },
  { 
    path: "/about", 
    component: () => import(/\* webpackChunkName: 'about'\*/"../views/About.vue")
  }
]

我们再来看一下打包效果

在这里插入图片描述

注意: 在开发中我们使用路由, 一般都是会使用它的懒加载的


路由的其他属性

前面我使用了路由中的path属性和component属性

其实路由中还有name属性和meta属性

name属性

记录路由独一无二的名称, 在页面跳转的时候也是可以指定name的(用的不多);

routes: [
  // 添加一个映射关系, 设置默认的展示页面
  { 
    // name要是独一无二, 唯一的
    name: "home",
    path: "/", 
    redirect: "/home" 
	}
]

meta属性

meta属性放一些额外的, 自定义的数据

这个自定义数据是可以在其他地方拿到的 (后面用到时在和大家介绍)

{ 
  path: "/", 
  redirect: "/home",
  // 自定义的一些数据
  meta: {
    name: "chenyq",
    age: 18,
    height: 1.88
  }
}


动态路由的使用

🍟动态路由基本匹配

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

例如,我们可能有一个 User 组件,它应该对所有用户进行渲染,我们url需要拼接上用户的ID,但是用户的ID是不同的,意味着我们路径是不能写死的;

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

routes: [
  {
    // 拼接时上:id表示路径不是写死的, 会有用户传入的id
    path: "/user/:id",
    component: () => import("../views/User.vue")
  }
]

在router-link中进行如下跳转

<router-link to="/user/123">用户:123</router-link>
<router-link to="/user/321">用户:321</router-link>

🍟获取动态路由的值

上面代码中, 我们虽然实现了/user拼接不同的id显式同一个页面

但是我们页面中展示的效果是相同的, 我们需要在User组件中根据不同的用户, 获取到不同的id进行展示

那么在User中如何获取到对应的值呢?

在template中,直接通过 $route.params获取值;

在created中,通过 this.$route.params获取值;

在setup中,我们要使用 vue-router库给我们提供的一个hook useRoute;

  • 该Hook会返回一个Route对象,对象中保存着当前路由相关的值;
  • 在template模板中,通过 $route.params获取值
<template>
  <div class="user">
    <h2>User{{ $route.params.id }}</h2>
  </div>
</template>

  • 在Options API 的 created中,通过 this.$route.params获取值
<script>
  export default {
		// Options API created中获取
    created() {
      console.log(this.$route.params.id)
    },
  }
</script>

  • 在setup中,我们要使用 vue-router库给我们提供的一个hook useRoute
<script setup>
 // vue-router库中给我们提供了一个hook函数useRoute
 import { useRoute } from 'vue-router';

 // useRoute函数会返回一个Route对象
 const route = useRoute()
 // 通过返回的Route对象可以拿到id
 console.log(route.params.id)
</script>

🍟NotFound

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

比如NotFound的错误页面中,这个时候我们可编写一个动态路由用于匹配所有的页面

在vue中, 我们可以通过/:pathMatch(.*)匹配所有的路径

routes: [
  { 
    path: "/", 
    redirect: "/home"
  },
  { 
    path: "/home",
    component: () => import("../views/Home.vue")
  },
  { 
    path: "/about", 
    component: () => import("../views/About.vue")
  },
  {
    path: "/user/:id",
    component: () => import("../views/User.vue")
  },
  {
    // \*匹配所有路由的路径
    path: "/:pathMatch(.\*)",
    component: () => import("../views/NotFound.vue")
  }
]

  • 当我们匹配不到前面路径的时候, 就会匹配最后一个路径, 显式NotFoun组件

在这里插入图片描述

如果我们想要提示用户的什么路径不正确

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

<template>
  <div>
    <h2>Not Found: 您的路径 {{ $route.params.pathMatch }} 不正确,请检查路径是否正确</h2>
  </div>
</template>


最后

今天的文章可谓是积蓄了我这几年来的应聘和面试经历总结出来的经验,干货满满呀!如果你能够一直坚持看到这儿,那么首先我还是十分佩服你的毅力的。不过光是看完而不去付出行动,或者直接进入你的收藏夹里吃灰,那么我写这篇文章就没多大意义了。所以看完之后,还是多多行动起来吧!

可以非常负责地说,如果你能够坚持把我上面列举的内容都一个不拉地看完并且全部消化为自己的知识的话,那么你就至少已经达到了中级开发工程师以上的水平,进入大厂技术这块是基本没有什么问题的了。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

  • 19
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值