Vue3.0----路由(第六章)

一、前端路由的概念与原理

1. 什么是路由

路由(英文:router)就是对应关系。路由分为两大类:

① 后端路由

② 前端路由

2. 回顾:后端路由

后端路由指的是:请求方式、请求地址与 function 处理函数之间的对应关系。在 node.js 课程中,express 路由的基本用法如下:


const express = require('express')
const router = express.Router()

router.get('/userlist', function(req,res) { /*路由的处理函数*/ })
router.post('/adduser' ,function(req,res){/*路由的处理函数*/ })

module.exports = router

3. SPA 与前端路由

SPA 指的是一个 web 网站只有唯一的一个 HTML 页面,所有组件的展示与切换都在这唯一的一个页面内完成。此时,不同组件之间的切换需要通过前端路由来实现。

结论:在 SPA 项目中,不同功能之间的切换,要依赖于前端路由来完成!

4. 什么是前端路由

通俗易懂的概念:Hash 地址组件之间的对应关系

5. 前端路由的工作方式

①用户点击了页面上的路由链接

②导致了URL 地址栏中的Hash 值发生了变化

前端路由监听了到 Hash 地址的变化

④前端路由把当前Hash 地址对应的组件渲染都浏览器中

 结论:前端路由,指的是Hash 地址组件之间对应关系

6. 实现简易的前端路由

步骤1:导入并注册MyHome、MyMovie、MyAbout 三个组件。示例代码如下:

import MyHome from './ components/MyHome.vue'
import MyMovie from './ components/MyMovie.vue '
import MyAbout from './ components/MyAbout.vue'
export default {
components: {
MyHome,MyMovie,MyAbout ,
},

步骤2:通过 标签的is 属性,动态切换要显示的组件。示例代码如下:

<template>
<h1>App 组件</h1>
<component :is="comName"></component></template>
export default {data() {
return {
comName: 'my-home ',//要展示的组件的名称
   }
  },
 }

步骤3:在组件的结构中声明如下 3 个 链接,通过点击不同的 链接,切换浏览器地址栏中的 Hash 值:

<a href="#/ home">Home</a>&nbsp;
<a href="#/movie">Movie</a>&nbsp;
<a href="#/ about" >About</a>

步骤4:在 created生命周期函数中监听浏览器地址栏中 Hash 地址的变化,动态切换要展示的组件的名称:

created() {
window.onhashchange - () =>{switch (location.hash) {
case '#/ home ' : //点击了“首页"的链接
this.comName = 'my-home '
break
case '#/ movie' : //点击了“电影"的链接
this.comName = 'my-movie'
break
case '#/about ' : //点击了“关于"的链接
this.comName = 'my-about '
break
}
}},

二、vue-router 的基本使用

1. 什么是 vue-router

vue-router是 vue.js 官方给出的路由解决方案。它只能结合 vue 项目进行使用,能够轻松的管理 SPA 项目中组件的切换。

vue-router 目前有3.x的版本和4.x的版本。其中:

⚫vue-router 3.x 只能结合vue2进行使用

⚫vue-router 4.x 只能结合vue3进行使用

vue-router 3.x 的官方文档地址:https://router.vuejs.org/zh/

vue-router 4.x 的官方文档地址:https://next.router.vuejs.org/

3. vue-router 4.x 的基本使用步骤

①在项目中安装 vue-router②定义路由组件

③声明路由链接占位符

④创建路由模块

导入并挂载路由模块

3.1 在项目中安装 vue-router

在 vue3 的项目中,只能安装并使用 vue-router 4.x。安装的命令如下:

npm install vue-router@next -s

3.2 定义路由组件

在项目中定义MyHome.vue、MyMovie.vue、MyAbout.vue三个组件,将来要使用 vue-router 来控制它们的展示与切换:

3.3 声明路由链接占位符

可以使用<router-link> 标签来声明路由链接,并使用<router-link>标签来声明路由占位符。示例代码如下:

<template>
<h1>App组件</h1>
<!--声明路由链接-->
<router-link to=" /home">首页</router-link>&nbsp;
<router-link to=" /movie">电影</router-link>&nbsp;
<router-link to="/ about">关于</router-link>
<!--声明路由占位符-->
<router-view></router-view></ template>

3.4 创建路由模块

在项目中创建 router.js 路由模块,在其中按照如下4 个步骤创建并得到路由的实例对象:①从 vue-router 中按需导入两个方法

②导入需要使用路由控制的组件

③创建路由实例对象

④向外共享路由实例对象

⑤在 main.js 中导入并挂载路由模块

从 vue-router 中按需导入两个方法

// 1.从 vue-router中按需导入两个方法
//createRouter方法用于创建路由的实例对象
//createwebHashHistory用于指定路由的工作模式(hash模式>
import { createRouter, createWebHashHistory } from 'vue-router'

导入需要使用路由控制的组件

// 2.导入组件,这些组件将要以路由的方式,来控制它们的切换
import Home from './ components/MyHome.vue'
import Movie from './components/MyMovie.vue'
import About from './components/MyAbout. vue '

创建路由实例对象

// 3.创建路由实例对象
const router = createRouter({
// 3.1 通过 history属性指定路由的工作模式
history: createwebHashHistory(),
// 3.2通过routes数组,指定路由规则
routes: [
// path 是 hash 地址,component是要展示的组件
{ path: '/home ' ,component: Home },
{ path: '/movie', component: Movie },
{ path: 'labout ' , component: About },
],
}

向外共享路由实例对象

// 4.向外共享路由实例对象,
//供其它模块导入并使用
export default router

在 main.js 中导入并挂载路由模块

import { createApp } from 'vue '
import App from './App. vue'
import './index.css'
// 1.导入路由模块
import router from ' ./router'
const app = createApp(App)
// 2.挂载路由模块
//app.use()方法用来挂载"第三方的插件模块”
app.use(router)
app.mount('#app')

三、vue-router 的高级用法

1. 路由重定向

路由重定向指的是:用户在访问地址 A 的时候,强制用户跳转到地址 C ,从而展示特定的组件页面。通过路由规则的redirect属性,指定一个新的路由地址,可以很方便地设置路由的重定向:

const router = createRouter({
history: createwebHashHistory(),
routes: [
//其中,path 表示需要被重定向的"原地址",redirect表示将要被重定向到的“新地址"
{path: '/' ,redirect: '/home' },
{ path: '/home ', component: Home },
{ path: ' /movie',component: Movie },
{ path: 'labout ' , component: About },
]
})

2. 路由高亮

可以通过如下的两种方式,将激活的路由链接进行高亮显示:

①使用默认的高亮 class 类

自定义路由高亮的 class 类

2.1 默认的高亮 class 类

被激活的路由链接,默认会应用一个叫做router-link-active的类名。开发者可以使用此类名选择器,为激活的路由链接设置高亮的样式:

/*在index.css全局样式表中,重新router-link-active的样式*/.
router-link-active {
background-color: red;
color : white;
font-weight: bold;
}

2.2 自定义路由高亮的 class 类

在创建路由的实例对象时,开发者可以基于linkActiveClass属性,自定义路由链接被激活时所应用的类名:

const router = createRouter({
   history: createwebHashHistoryo.
//指定被激活的路由链接,会应用router-active 这个类名,
//默认的router-link-active类名会被覆盖掉
  linkActiveClass: 'router-active',
 routes: [
   { path: '/',redirect: '/home},
   { path: '/home', component: Home },
   { path: '/movie',component: Movie },
   { path: '/about', component: About },
    ],
  })

 3. 嵌套路由

通过路由实现组件的嵌套展示,叫做嵌套路由。

 

①声明子路由链接子路由占位符

②在父路由规则中,通过children属性嵌套声明子路由规则

3.1 声明子路由链接子路由占位符

<template>
<h3>MyAbout组件</h3>
<!--在关于页面中,声明两个子路由链接-->
<router-link to=" /about/tab1">tab1</router-link>&nbsp;
<router-link to=" /about/tab2">tab2</router-link>
!--在关于页面中,声明tab1和tab2的路由占位符-->
<router-view></router-view>
</template>

3.2 通过children属性声明子路由规则

在 router.js 路由模块中,导入需要的组件,并使用children 属性声明子路由规则。示例代码如下:

import Tab1 from './ components/tabs/MyTab1.vue '
import Tab2 from './ components/tabs/MyTab2.vue '
const router = createRouter({
routes: [
{ //about页面的路由规则(父级路由规则)
path: ' labout',
component: About,
children: [  //通过children属性嵌套子级路由规则
{ path: 'tab1 ',component: Tab1 },//访问/about/tab1时,展示 Tab1 组件
{ path: 'tab2',component: Tab2 },//访问/about/tab2时,展示 Tab2组件
 ],
  },
   ],
})

注意:子路由规则的 path 不要以 / 开头

4. 动态路由匹配

思考:有如下 3 个路由链接

<router-link to=" / movie/1">电影1</router-link>
<router-link to=" / movie/2">电影2</router-link>
<router-link to=" / movie/3">电影3</router-link>

定义如下 3 个路由规则,是否可行???

 { path: '/movie/1 ',component: Movie }
 { path: '/movie/2 ',component: Movie }
 { path: ' /movie/3 ', component: Movie }

缺点:路由规则的复用性差。

4.1 动态路由的概念

动态路由指的是:把 Hash 地址中可变的部分定义为参数项,从而提高路由规则的复用性。在 vue-router 中 使用英文的冒号(:)来定义路由的参数项。示例代码如下:

//路由中的动态参数以︰进行声明,冒号后面的是动态参数的名称
{ path: '/movie/ : id' , component: Movie }
//将以下 3个路由规则,合并成了一个,提高了路由规则的复用性
{ path: '/movie/1 ', component: Movie }
{ path: '/movie/2 ' ,component: Movie }
{ path: '/movie/3 ' ,component: Movie }

4.2 $route.params 参数对象

通过动态路由匹配的方式渲染出来的组件中,可以使用$route.params 对象访问到动态匹配的参数值

<template>
<!-- $route.params是路由的“参数对象”-->
<h3>MyMovie组件--- {
   
   {$route.params.id}}</h3>
</template>
<script>
export default {
name: 'MyMovie ' ,
}
</script>

4.3 使用 props 接收路由参数

为了简化路由参数的获取形式,vue-router 允许在路由规则中开启 props 传参。示例代码如下:

// 1、在定义路由规则时,声明props: true选项,
//即可在 Movie 组件中,以 props的形式接收到路由规则匹配到的参数项
{ path: '/movie/ : id ', component: Movie, props : true}
<template>
<!-- 3、直接使用props中接收的路由参数-->
     <h3>MyMovie组件--- {
   
   {id}}</h3>
</template>
<script>
export default {
props: [ 'id']// 2、使用props接收路由规则中匹配到的参数项
</script>

5. 编程式导航

通过调用 API 实现导航的方式,叫做编程式导航。与之对应的,通过点击链接实现导航的方式,叫做声明式导航。例如:

  • 普通网页中点击 <a> 链接、vue 项目中点击<router-link> 都属于声明式导航
  • 普通网页中调用location.href 跳转到新页面的方式,属于编程式导航

5.1 vue-router 中的编程式导航 API

vue-router 提供了许多编程式导航的 API,其中最常用的两个 API 分别是:

①this.$router.push('hash 地址')

  • 跳转到指定 Hash 地址,从而展示对应的组件

②this.$router.go(数值 n)

  • 实现导航历史的前进、后退

5.2 $router.push

调用 this.$router.push() 方法,可以跳转到指定的 hash 地址,从而展示对应的组件页面。示例代码如下:

<template>
   <h3>MyHome组件</h3>
   <button @click="gotoMovie(3)">go to Movie</button>
</template>
<script>
export default {
   methods: {
   gotoMovie(id) { // id参数是电影的id值this.$router.push( ' /movie/${id} `)},
   },
}
</script>

5.2 $router.go

调用 this.$router.go() 方法,可以在浏览历史中进行前进和后退。示例代码如下:

<template>
  <h3>MyMovie组件--- {
   
   {id}}</h3>
  <button @click="goBack">后退</button>
</template>
<script>
export default {props: [ 'id'l,methods: {
  goBack() { 
    this.$router.go(-1) 
   }//后退到之前的组件页面},
}
</ script>

6. 命名路由

通过name 属性为路由规则定义名称的方式,叫做命名路由。示例代码如下:

{
path: ' /movie/ : id" ,
//使用name属性为当前的路由规则定义一个“名称”
name: 'mov ' ,
component: Movie,
props: true,
}

注意:命名路由的name 值不能重复,必须保证唯一性

6.1 使用命名路由实现声明式导航

为 标签动态绑定 to 属性的值,并通过name 属性指定要跳转到的路由规则。期间还可以用

params 属性指定跳转期间要携带的路由参数。示例代码如下:

<template>
  <h3>MyHome组件</h3>
  <router-link :to="{ name: 'mov', params: { id: 3 }}">go to Movie</router-link>
</template>
<script>
  export default {
   name: 'MyHome ' ,
</script>

6.2 使用命名路由实现编程式导航

调用push 函数期间指定一个配置对象name是要跳转到的路由规则、params是携带的路由参数:

<template>
   <h3>MyHome组件</h3>
   <button @click="gotoMovie(3)">go to Movie</button>
</template>
<script>
export default {
   methods: {
   gotoMovie(id) {
   this.$router.push(i name: 'mov ', params : { id: 3 }})
   },
 },
}
</script>

7. 导航守卫

导航守卫可以控制路由的访问权限。示意图如下:

 

 7.1 如何声明全局导航守卫

全局导航守卫会拦截每个路由规则,从而对每个路由进行访问权限的控制。可以按照如下的方式定义全局导航守卫:

//创建路由实例对象
const router = createRouter({ ... })

//调用路由实例对象的 beforeEach函数,声明"全局前置守卫"
// fn 必须是一个函数,每次拦截到路由的请求,都会调用fn进行处理
/因此 fn叫做“守卫方法“
router.beforeEach(fn)

7.2 守卫方法的 3 个形参

全局导航守卫的守卫方法中接收 3 个形参,格式为:

//创建路由实例对象
const router = createRouter({ ... })
//全局前置守卫
router.beforeEach((to,from,next) =>{
// to 目标路由对象
// from当前导航正要离开的路由对象l l next是一个函数,表示放行
}

注意:

①在守卫方法中如果不声明 next 形参,则默认允许用户访问每一个路由

②在守卫方法中如果声明了 next 形参,则必须调用 next() 函数,否则不允许用户访问任何一个路由!

7.3 next 函数的 3 种调用方式

参考示意图,分析 next 函数的 3 种调用方式最终导致的结果:

直接放行:next()

强制其停留在当前页面:next(false)

强制其跳转到登录页面:next('/login')

7.4 结合 token 控制后台主页的访问权限

//全局前置守卫
router.beforeEach((to,from,next) =>{
const token = localStorage.getItem( 'token ' )    // 1.读取 token
if (to.path === ' /main' 8& !token) {     // 2.想要访问“后台主页”且token值不存在
// next(false) // 3.1不允许跳转
next( ' / login')    //3.2强制跳转到“登录页面”}else {
   next()   // 3.3直接放行,允许访问“后台主页”
}
})

视频:

黑马程序员Vue全套视频教程,从vue2.0到vue3.0一套全覆盖,前端学习核心框架教程_哔哩哔哩_bilibili

此文章是本人学习视频自我总结,如有侵犯还望原谅。侵权必删。

猜你喜欢

转载自blog.csdn.net/QQ675396947/article/details/127540518