vue-router: vue3路由管理器

一、基本介绍

1. 单页应用程序介绍

1> 概念: 整个应用只有一个入口网页文件(就是项目中的index.html文件), 换句话说, 项目所有的功能都集中在一个 html 文件中进行实现的.

2> 举例:

单页面应用程序: 网易云音乐, 知乎...(页面是局部刷新,不会加载整个网站)

多页面应用程序: 京东,淘宝,门户网站...(一个网页应用文件跳转到另一个网页应用文件,重新加载整个页面,整个页面会全部刷新)

3> 单页面应用 VS 多页面应用

什么是SEO: 搜索引擎优化, Search Engine Optimization 的简称, 可以通过优化网站的内容和结构,提高网站在搜索引擎中的排名, 从而增加网站的流量和曝光度的一种技术. 简而言之, 就是当用户进行搜索的时候, 可以把网站出现在搜索结果的前列, 增加更多的潜在用户

开发分类实现方式用户体验网站性能开发效率学习成本首屏加载是否利于SEO

单页面应用

一个html文件不利于
多页面应用多个html文件利于

单页应用类网站:系统类网站 / 内部网站 / ⽂档类网站 / 移动端站点

多页应用类网站:公司官网 / 电商类网站

2. 路由介绍

1> 什么是路由: 路由其实就是一个映射(对应)关系

比如: 生活中的路由就是设备和ip地址的映射关系, 不同的设备连接到同一个路由器,会得到一个唯一的ip地址

2> vue3中的路由指的是什么: 路径和页面(组件)的映射关系(路径变了,页面会变), 简而言之: 就是访问不同的路径, 要显示不同的页面(组件)

3> 在vue3中如何实现路由切换: 借助 vue-router 第三方模块, 它也是vue3的官方路由管理器(实现访问不同路径,显示不同页面)

4> 介绍 vue-router: vue3的官方路由管理器

我们可用去官网来看看它的介绍: Vue.js - 渐进式 JavaScript 框架 | Vue.js

点击进去看

3. 组件存放目录

页面和组件存放目录的问题:

1> 背景: 因为vue3 + vue-router 开发项目是一个单页面应用程序, 而又要在单页面程序中实现切换, 其实是借助 vue 文件来实现切换的, 在这里就进而我们之前学习的组件的扩展名一样了, 为了区分便于管理, 就需要进行不同的划分和存储.

2> 关于 vue 文件的分类

1) 页面组件: 一个做好的,大的,成型的页面, 比如京东的首页.. 只是用来做大块的展示, 无需复用, 配合路由切换.

2) 复用组件: 之前我们学习的组件就是复用组件, 它是一个个独立的小型页面, 可复用的, 用来组装页面组件的

3> 存放目录的问题:

1) 页面组件: 存放在 src/views 目录下 

2) 复用组件: 存放在 src/components 目录下

关系: 若干个复用组件组装-> 页面组件

小结:

页面组件 -> src/views -> 配合路由切换

复用组件 -> src/components-> 组装页面组件

二、基本使用和模块封装

1. vue-router 的基本使用(4+2)

1> 4个固定步骤 

1) 下载 vue-router 模块: npm i vue-router

2) 导入相关函数, 在main.js中编写代码

3) 创建路由实例

4) 注册让路由规则生效

createRouter 创建路由实例, createWebHashHistory()创建的模式是哈希模式, 后面路径会带上 # 

最后我们发现我们的url多了个#

2> 2个核心步骤

vue3 中路由的本质就是 路径和组件(页面)的对应关系, 这个规则需要通过路由表自行配置

1) 创建页面,配置规则: 

2) 给定出口: 在根组件上写<router-view/>

运行结果: 输入不同的路径,展示映射的组件页面

 具体代src/Find.vue, Friend.vue,My.vue

<script setup>

</script>
<template>
    <div class="find">
        <p>发现音乐</p>
        <p>发现音乐</p>
        <p>发现音乐...</p>
    </div>
</template>

<style scoped></style>
<script setup>

</script>
<template>
    <div class="friend">
        <p>朋友的音乐</p>
        <p>朋友的音乐</p>
        <p>朋友的音乐...</p>
    </div>
</template>

<style scoped></style>
<script setup>

</script>
<template>
    <div class="my">
        <p>我的音乐</p>
        <p>我的音乐</p>
        <p>我的音乐...</p>
    </div>
</template>

<style scoped></style>

 App.vue

<script setup>
    
</script>

<template>
    <!-- 提供的一个内置全局组件,是路由的出口 -->
     <!-- 相当于一个占位符, 输入路径对应的组件,就会把这个占位符替换成那个组件 -->
<router-view/>
</template>

<style scoped>

</style>

main.js


// 按需导入 createApp 函数
import { createApp } from 'vue'
// 导入 App.vue
import App from './App.vue'
// 1. 下载包: npm i vue-router
// 2.导入 2 个相关函数
import { createRouter, createWebHashHistory } from 'vue-router'
// 导入 3 个页面组件
import Find from './views/Find.vue'
import Friend from './views/Friend.vue'
import My from './views/My.vue'
// 3. 创建路由实例
const router = createRouter({
	// 知名路由模式: 当前创建的是哈希模式, 路径后会带 #
	history: createWebHashHistory(),
	// 配置路由规则
	routes: [
		//一个规则就是一个对象,定义切换页面的路径
		{
			path:'/find',
			component: Find
		},
		{
			path:'/my',
			component: My
		},
		{
			path:'/friend',
			component: Friend
		}
	]
})
// 创建应用
const app = createApp(App)
// 4. 注册路由实例: 让路由表规则生效
app.use(router)
// 指定渲染的位置
app.mount('#app')

2. vue-router的基本原理(很重要)

vue-router的运作原理: 当路径(url)发生变化的时候, 相应的页面是如何渲染出来的?

当浏览器的url地址变化时, 会于routers 数组(路由表规则) 中的path进行匹配, 如果命中了 url 和

path 值一样, 那么就会把相应的组件渲染到 <router-view/>的位置; 否则, 则显示空白页面

3. 抽离和封装路由模块

1> 为什么要封装路由模块?

如果把所有和路由相关的代码全写在 main.js 中, 这样会让 main.js 中的代码显得很臃肿. 为了方便后期对路由代码的管理和维护, 最好的方式就是把路由相关的代码单独封装到一个模块中, 这也是一种模块化开发的思想.

2> 如何封装?

1. 新建src/router/index.js, 然后把之前写在 main.js 中的路由代码全部 转移到 router.js 中进行管理, 并导出 router 实例

注意: @代表 src下的绝对路径, 找到了 src, 就可以从它下面找到任何模块

2. 在main.js中导入router实例, 并注册

三、声明式导航和传参

1. 声明式导航

引入: 用户不可能需要记住我们的src地址然后进行输入, 才能实现跳转, 这样不合理, 因此引入了router-link来实现点击链接进行跳转. 

1> 什么是声明式导航: 就是点击链接跳转页面

2> 如何实现:  <router-link to="/path值">xxx</router-link>

3> router-link的本质: 就是 a 标签, to属性会变成href属性

4> 相比a标签, router-link 的优势: 自带激活/高亮类名, 很方便实现高亮样式

2. 俩个激活类名的区别

当导航链接处于激活时, vue-router会自动给当前的a标签添加俩个类名: router-link-active, router-link-exact-active, 这俩个类名有什么区别:

1> router-link-active: 模糊匹配, 当浏览器#后面放入url地址包含to属性值的时候, 则会给当前的 a 标签添加此类名

2> router-link-exact-active: 精确匹配, 当浏览器#后面的url地址等于to属性值的时候, 就会给当前的a 标签添加此类名

3> 相等是一种特殊的包含关系, 只要#后面的url地址等于to属性值, 此时既是相等关系,也是特殊的包含关系,则这俩个类名都会有

3. 声明式导航-传查参数

引入: 有这么一个场景, 我们在发现音乐页面要去朋友页, 并且携带id, 方便后续进行查询操作, 此时我们就需要把 id 作为参数进行传递--> 跳转路由进行传参

声明式导航传参: 

1> 传参的类型: 查询参数传参, 动态路由传参

查询参数传参:

1) 如何传递:

1. 传字符串: <router-link to="/path?参数名1=值1&参数2=值2"></router-link>  

2. 传对象:    <router-link :to="{path:'/paht值',query:{参数名: 值}}"></router-link>

3. 即使给to传递的是对象, 最终还是会变成字符串的格式, 因此传递的方法是一样的

2) 接收参数:

        import {useRoute) from 'vue-router'  导入函数

        const route = useRoute() 创建对象

        console.log(route.query.参数名) 打印对象

 传字符串:

传递对象:

具体代码:

App.vue

<script setup>

</script>

<template>
    <!-- 提供的一个内置全局组件,是路由的出口 -->
    <!-- 相当于一个占位符, 输入路径对应的组件,就会把这个占位符替换成那个组件 -->
    <nav>
        <router-link to="/find">发现音乐</router-link>
        <router-link to="/my">我的音乐</router-link>
        <!-- 查询参; 传字符串 -->
        <!-- <router-link to="/friend?id=1008&name=小白">朋友</router-link> -->
        <!-- 查询参: 传对象, 这里虽然是对象的写法, 但是最后还是会被转化为字符串 -->
        <router-link 
        :to="{
            path:'/friend',
            query:{
                id: 1008,
                name: 小白
            }
        }"
        >朋友</router-link>
         
    </nav>
    <router-view />
</template>

<style scoped>
/* nav {
    display: flex; 
} */
nav a {
    /* display: flex; */
    color: #333;
    text-decoration: none;
}

/* 选中第二个 */
nav a:nth-child(2) {
    margin: 0 80px;
}
/* 激活的显示特殊样式 */
nav a.router-link-active {
    background: red;
    color: #fff;
}
</style>

Friend.vue

<script setup>
import { useRoute } from 'vue-router';
const route = useRoute()
console.log(route.query)
</script>
<template>
    <div class="friend">
        <p>朋友的音乐</p>
        <p>朋友的音乐</p>
        <p>朋友的音乐...</p>
        <p>当前朋友的id = {{ route.query.id }}</p>
        <p>当前朋友的名字 = {{ route.query.name }}</p>
    </div>

</template>

<style scoped></style>

动态路由传参

语法: <router-link to ="/friend/10010"> 朋友 </roouter-link>

1> 先改写路由表的 path 值: /friend/:参数名 比如: path 值: /friend/:frd

2> 传参: 

1. 传字符串: <router-link to ="/friend/100"> 朋友</router-link>

2. 传对象: <router-link :to:"{name:'friend',params:{fid:100}}"></router-link>

3. 即使传递的是对象格式, 最终也会变成字符串形式传参

3> 取值: 

import {useRoute} from 'vue-route'

const route = useRoute()

console.log(route.params.fid)

传字符串

传对象

具体代码:

index.js

// 1. 下载包: npm i vue-router
// 2.导入 2 个相关函数
import { createRouter, createWebHashHistory } from 'vue-router'
// 导入 3 个页面组件
import Friend from '@/views/Friend.vue'
import Find from '@/views/Find.vue'
import My from '@/views/My.vue'
// 3. 创建路由实例
const router = createRouter({
	// 知名路由模式: 当前创建的是哈希模式, 路径后会带 #
	history: createWebHashHistory(),
	// 配置路由规则
	routes: [
		//一个规则就是一个对象,定义切换页面的路径
		{
			path:'/find',
			component: Find
		},
		{
			path:'/my',
			component: My
		},
		{	name: 'Friend',
			path:'/friend/:frd',
			component: Friend
		}
	]
})
//进行默认导出
export default router

App.vue

<script setup>

</script>

<template>
    <!-- 提供的一个内置全局组件,是路由的出口 -->
    <!-- 相当于一个占位符, 输入路径对应的组件,就会把这个占位符替换成那个组件 -->
    <nav>
        <router-link to="/find">发现音乐</router-link>
        <router-link to="/my">我的音乐</router-link>
        <!-- 动态路由传参: 字符串格式  -->
        <!-- <router-link to="/friend/1001">朋友</router-link> -->
         <!--动态路由传参: 传对象格式 -->
         <router-link 
         :to="{
            name:'Friend',  
            params:{
                frd:1223
            }  
         }">
         朋友</router-link>
         
    </nav>
    <!-- 路由的出口 -->
    <router-view />
</template>

<style scoped>
/* nav {
    display: flex; 
} */
nav a {
    /* display: flex; */
    color: #333;
    text-decoration: none;
}

/* 选中第二个 */
nav a:nth-child(2) {
    margin: 0 80px;
}
/* 激活的显示特殊样式 */
nav a.router-link-active {
    background: red;
    color: #fff;
}
</style>

Friend.vue

<script setup>
import { useRoute } from 'vue-router';
const route = useRoute()
console.log(route)
</script>
<template>
    <div class="friend">
        <p>朋友的音乐</p>
        <p>朋友的音乐</p>
        <p>朋友的音乐...</p>
        <p>当前朋友id={{ route.params.frd }}</p>
    </div>

</template>

<style scoped></style>

查询参 VS 动态参

声明式导航俩种传参方式的对比:

1. 查询参: 适用于传递多个参数

传: /path?参数名1=值1&参数名2=值2

取: route.query.参数名

2. 动态参: 需要改写路由规则表的path值, 比如 /path/:参数名1/参数名2 这种传参看起来比较好看

传: /path/具体值1/具体值2   传入的具体值会给参数名进行赋值

取: route.params.参数名

四、更多的配置

问题: 网页打开时, url默认路径是/, 没有匹配到组件的时候, 会出现空白, 此时我们就需要去想办法配置一下vue-router

vue-router的更多配置:

1. 重定向

当路由匹配了某个path, 强制跳转到另一个path

当前我们代码存在俩个问题:

1> 项目默认打开, 访问的时候, 出现空白页面

2> 控制台出现了黄色警告(没有匹配到路由表中 / 路径)

解决方法: 使用重定向, 在路由表的开头添加一个能够匹配/根路径的路由规则即可.

2. 404页面 

需求: 输入错误的url, 路由规则无法命中页面, 此时我们就报错404

解决: 配置 404 规则

1) 创建404页面, 添加结构+样式+行为

2) 在路由表末尾, 添加一个 404 路由规则, {path: '/:pathMach(.*)*',component:_404} 

    生效规则: 如果路由能够正常命中则显示相应的页面, 否则才会匹配到404的规则, 显示 Not Found页面

创建404页面

在路由表末尾, 添加一个 404 路由规则

结果: 输入错误的url

3. 路由的模式

默认采用的是哈希模式, 特点是路径上会携带一个很丑的#, 为了去除这个#, 可以更路由模式, 改成 history 模式, 这样路径看起来就会更自然美观

注意: 在 Vite开发环境下, 我们可以正常使用历史模式进行切        换路由; 但是当项目打包上线的时候, 要想使用历史模式, 那么需要服务器支持和配置. 也就是说, 在开发模式下, 直接使用历史模式即可

展示效果:

代码:

index.js

// 1. 下载包: npm i vue-router
// 2.导入 2 个相关函数
import { createRouter, createWebHashHistory,createWebHistory } from 'vue-router'
// 导入 3 个页面组件
import Friend from '@/views/Friend.vue'
import Find from '@/views/Find.vue'
import My from '@/views/My.vue'
import _404 from '@/views/404.vue'
// 3. 创建路由实例
const router = createRouter({
	// 知名路由模式: 当前创建的是哈希模式, 路径后会带 #
	// history: createWebHashHistory(), //创建哈希模式
	history:  createWebHistory(),//创建历史模式
	// 配置路由规则
	routes: [
		//一个规则就是一个对象,定义切换页面的路径
		{//默认打开页面, 会访问 / 根路径, 这里借助了 redirect 让其强制跳转到 /find 发现音乐
			path:'/',
			redirect: '/find'    //强制跳转到/find
		},
		{
			path:'/find',
			component: Find
		},
		{
			path:'/my',
			component: My
		},
		{
			path:'/friend',
			component: Friend
		},
		{
			// 不能命中就显示404
			//配置404规则
			path: '/:pathMach(.*)*',
			component: _404
		}
	]
})
//进行默认导出
export default router

main.js


// 按需导入 createApp 函数
import { createApp } from 'vue'
// 导入 App.vue
import App from './App.vue'
// 默认导入: index.js可以省略,其他js不能省略
import router from './router'
// 创建应用
const app = createApp(App)
// 4. 注册路由实例: 让路由表规则生效
app.use(router)
// 指定渲染的位置
app.mount('#app')

 404.vue

<script setup>
import router from '@/router';


</script>
<template>
    <div class="_404">
        <h4>Not Found</h4>
        <p>访问不到这个页面,请检查url</p>
        <RouterLink to="/">点击回到首页</RouterLink>
    </div>
</template>



<style scoped></style>

<!-- {path: '/pathMach(.*)*',component:_404}  -->

五、编程式导航和传参

引入: 之前的声明式导航需要我们手动点击后才会进行链接的跳转, 但是先在我们需要实现自动跳转,如: 登录成功后自动跳转到首页

1. 编程式导航介绍

1> 什么是编程式导航?

通过 js 代码进行主动跳转页面, 相对于之前的声明式导航是被动跳转的.

需求: 在发现音乐页, 挂载完毕后, 延迟2s, 自动跳转到朋友页

2> 语法:

1) 获取 router 路由实例

import{useRouter} from 'vue-router'

const router = useRouter() // router是路由实例, 也就是createRouter()的返回值

const route = useRoute()// route 是当前激活的路由对象, 用来获取路由参数的

获取路由对象

2) router.push(字符串/对象)

使用push把path传入作为默认自动跳转的路径

代码:

index.js

// 1. 下载包: npm i vue-router
// 2.导入 2 个相关函数
import { createRouter, createWebHashHistory,createWebHistory } from 'vue-router'
// 导入 3 个页面组件
import Friend from '@/views/Friend.vue'
import Find from '@/views/Find.vue'
import My from '@/views/My.vue'
import _404 from '@/views/404.vue'
// 3. 创建路由实例
const router = createRouter({
	// 知名路由模式: 当前创建的是哈希模式, 路径后会带 #
	// history: createWebHashHistory(), //创建哈希模式
	history:  createWebHistory(),//创建历史模式
	// 配置路由规则
	routes: [
		//一个规则就是一个对象,定义切换页面的路径
		{//默认打开页面, 会访问 / 根路径, 这里借助了 redirect 让其强制跳转到 /find 发现音乐
			path:'/',
			redirect: '/find'    //强制跳转到/find
		},
		{
			path:'/find',
			component: Find
		},
		{
			path:'/my',
			component: My
		},
		{
			path:'/friend',
			name: 'Friend',
			component: Friend
		},
		{
			// 不能命中就显示404
			//配置404规则
			path: '/:pathMach(.*)*',
			component: _404
		}
	]
})
//进行默认导出
export default router

find.vue

<script setup>
// 需求: 在发现音乐页, 挂载完毕后, 延迟2s, 自动跳转到朋友页
import { useRouter } from 'vue-router';
import { onMounted } from 'vue';
// 获取路由实例
const router = useRouter()
//挂载完毕
onMounted(() => {
    // 延迟2s
    setTimeout(() => {
        // 字符串
        // router.push('/friend')
        // 传对象 path 属性
        // router.push({
        //     path: '/friend'
        // })
        //传对象 name 属性
        router.push({
            name:'Friend'
        })
    }, 2000)
})
</script>
<template>
    <div class="find">
        <p>发现音乐</p>
        <p>发现音乐</p>
        <p>发现音乐...</p>
    </div>
</template>

<style scoped></style>

2. 编程式导航传参

编程时导航传参和声明式导航传参是一样的

1> 复习声明式导航的传参:

<router-link to="字符串/对象"></router-link>

1)查询参:

/path?参数名=值 {path:'/path',query:{参数名:值}}   使用 route.query.参数名 拿到参数

2)动态参:

{path:'/friend/:id,name:'Friend'} /friend/666 {name:'Friend',params:{id:666}}}  使用 route.query.参数名 拿到参数

2> 编程式导航传参:

1) 查询参:

router.push('path?参数名=值')  字符串

router.push({path:'/path',query:{参数名:值}}) 对象

2) 动态参:

router.push('/path/具体值') 字符串

router.push({}name:'路由规则名称',params:{参数名:值}) 对象

查询参-字符串

查询参-对象 

动态参-字符串

动态参-对象

代码:

index.js

// 1. 下载包: npm i vue-router
// 2.导入 2 个相关函数
import { createRouter, createWebHashHistory,createWebHistory } from 'vue-router'
// 导入 3 个页面组件
import Friend from '@/views/Friend.vue'
import Find from '@/views/Find.vue'
import My from '@/views/My.vue'
import _404 from '@/views/404.vue'
// 3. 创建路由实例
const router = createRouter({
	// 知名路由模式: 当前创建的是哈希模式, 路径后会带 #
	// history: createWebHashHistory(), //创建哈希模式
	history:  createWebHistory(),//创建历史模式
	// 配置路由规则
	routes: [
		//一个规则就是一个对象,定义切换页面的路径
		{//默认打开页面, 会访问 / 根路径, 这里借助了 redirect 让其强制跳转到 /find 发现音乐
			path:'/',
			redirect: '/find'    //强制跳转到/find
		},
		{
			path:'/find',
			component: Find
		},
		{
			path:'/my',
			component: My
		},
		{
			path:'/friend/:id',
			// path:'/friend',
			name: 'Friend',
			component: Friend
		},
		{
			// 不能命中就显示404
			//配置404规则
			path: '/:pathMach(.*)*',
			component: _404
		}
	]
}) 
//进行默认导出
export default router

Find.vue

<script setup>
// 需求: 在发现音乐页, 挂载完毕后, 延迟2s, 自动跳转到朋友页
import { useRouter } from 'vue-router';
import { onMounted } from 'vue';
// 获取路由实例
const router = useRouter()
//挂载完毕
onMounted(() => {
    // 延迟2s
    setTimeout(() => {
        //查询参
        // 1) 字符串
        // router.push('/friend?id=666')
        // 2) 对象
        // router.push({
        //     path: '/friend',
        //     query: {
        //         id: 777
        //     }
        // })
        //
        //动态参:
        // 1) 字符串
        // router.push('/friend/888')
        // 2) 对象
        router.push({
            name: 'Friend',
            params: {
                id: 999
            }
        })

    }, 2000)
})
</script>
<template>
    <div class="find">
        <p>发现音乐</p>
        <p>发现音乐</p>
        <p>发现音乐...</p>
    </div>
</template>

<style scoped></style>

Friend.vue

<script setup>
import { useRoute } from 'vue-router';
const route = useRoute()
</script>
<template>
    <div class="friend">
        <p>朋友的音乐</p>
        <p>朋友的音乐</p>
        <p>朋友的音乐...</p>
        <!-- 获取查询参数 -->
        <!-- <p>当前朋友的id={{ route.query.id }}</p> -->
         <!--获取动态路由参数 -->
        <p>当前朋友的id={{ route.params.id }}</p>
    </div>

</template>

<style scoped></style>

六、嵌套和守卫

1. 路由的嵌套

引入: 实现在一个路由页面, 进行另一套路由的切换, 比如: 网易云 音乐的发现音乐页 

路由嵌套: 一个路由页面, 还可以实现路由切换

1> 准备2级页面(创建 vue 页面, 填充结构+样式+行为), 并在路由规则表中进行配置2级路由规则(添加children 选项, 进行配置, 借助 redirect 防止空白页面出现)

2> 在相应的1级页面中给定2级路由出口 <router-view/>

实现点击跳转效果

实现默认重定向

具体代码:

index.js

// 1. 下载包: npm i vue-router
// 2.导入 2 个相关函数
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
// 导入 4 个一级路由组件页面
import Friend from '@/views/Friend.vue'
import Find from '@/views/Find.vue'
import My from '@/views/My.vue'
import _404 from '@/views/404.vue'
// 导入 3 个二级路由页面组件
import Recommend from '@/views/Recommend.vue'
import TopList from '@/views/TopList.vue'
import PlayList from '@/views/PlayList.vue'

// 3. 创建路由实例
const router = createRouter({
	// 知名路由模式: 当前创建的是哈希模式, 路径后会带 #
	// history: createWebHashHistory(), //创建哈希模式
	history: createWebHistory(),//创建历史模式
	// 配置路由规则
	routes: [
		//一个规则就是一个对象,定义切换页面的路径
		{//默认打开页面, 会访问 / 根路径, 这里借助了 redirect 让其强制跳转到 /find 发现音乐
			path: '/',			//第一次重定向
			redirect: '/find'    //强制跳转到/find
		},
		{//一级路由必须加/
			path: '/find',
			component: Find,
			redirect: '/find/recommend', //第二次重定向
			children: [
				// 在谁下面切换就在谁里面设置嵌套
				//配置路由嵌套
				// 二级路由开始, path 不加/,但是访问这个路径还是需要/
				{
					// 推荐
					path: 'recommend',
					component: Recommend
				},
				{	//排行榜
					path: 'topList',
					component: TopList
				},
				{	// 播放列表
					path: 'playList',
					component: PlayList
				}
			]
		},
		{
			path: '/my',
			component: My
		},
		{

			name: 'Friend',
			component: Friend
		},
		{
			// 不能命中就显示404
			//配置404规则
			path: '/:pathMach(.*)*',
			component: _404
		}
	]
})
//进行默认导出
export default router

PlayList.vue

<script setup>
        
</script>
<template>
<div class="PlayList">
    <p>播放列表</p>
    <p>播放列表</p>
    <p>播放列表...</p>
</div>
</template>


<style scoped>

</style>

Recommend.vue

<script setup>

</script>
<template>
    <div class="Recommend">
        <p>推荐页面</p>
        <p>推荐页面</p>
        <p>推荐页面...</p>
    </div>
</template>


<style scoped></style>

TopList.vue

<script setup>

</script>
<template>
    <div class="TopList">
        <p>排行榜</p>
        <p>排行榜</p>
        <p>排行榜...</p>
    </div>
</template>


<style scoped></style>

2. 路由的守卫

引入: 我们在没有登录的时候去访问其他页面是不被允许的, 因此我们需要一个进行权限判断的机制->路由守卫

路由守卫: 全称叫做全局前置守卫, 简而言之就是在每个页面访问之前对其做判断, 只有通过了才能放行, 否则将其打回去(和spring里面的拦截器一样)

语法:

router.beforeEach((to,from) => {

俩个参数含义:

// to: 要去的路由对象

// from: 当前的路由对象

三种情况:

// 如果放行, 返回 true 或者 undefined 或者 不写

// 如果不放行, 返回 false 

// 重定向到某个指定路由, return 路径

})

 需求: 在登录的情况下, 是不可以访问我的音乐页的, 其他的正常访问.

具体代码:

index.js

// 1. 下载包: npm i vue-router
// 2.导入 2 个相关函数
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
// 导入 4 个一级路由组件页面
import Friend from '@/views/Friend.vue'
import Find from '@/views/Find.vue'
import My from '@/views/My.vue'
import _404 from '@/views/404.vue'
// 导入 3 个二级路由页面组件
import Recommend from '@/views/Recommend.vue'
import TopList from '@/views/TopList.vue'
import PlayList from '@/views/PlayList.vue'
// 模拟用户是否登录
const isLogin = false;
// 3. 创建路由实例
const router = createRouter({
	// 知名路由模式: 当前创建的是哈希模式, 路径后会带 #
	// history: createWebHashHistory(), //创建哈希模式
	history: createWebHistory(),//创建历史模式
	// 配置路由规则
	routes: [
		//一个规则就是一个对象,定义切换页面的路径
		{//默认打开页面, 会访问 / 根路径, 这里借助了 redirect 让其强制跳转到 /find 发现音乐
			path: '/',			//第一次重定向
			redirect: '/find'    //强制跳转到/find
		},
		{//一级路由必须加/
			path: '/find',
			component: Find,
			redirect: '/find/recommend', //第二次重定向
			children: [
				// 在谁下面切换就在谁里面设置嵌套
				//配置路由嵌套
				// 二级路由开始, path 不加/,但是访问这个路径还是需要/
				{
					// 推荐
					path: 'recommend',
					component: Recommend
				},
				{	//排行榜
					path: 'topList',
					component: TopList
				},
				{	// 播放列表
					path: 'playList',
					component: PlayList
				}
			]
		},
		{
			path: '/my',
			component: My
		},
		{

			name: 'Friend',
			component: Friend
		},
		{
			// 不能命中就显示404
			//配置404规则
			path: '/:pathMach(.*)*',
			component: _404
		}
	]
})
// 守卫路由
router.beforeEach((to, from) => {
	console.log(to)
	console.log(from)
	// return undefined/true; 放行
	// return false; //不放行, 页面会显示空白
	//  需求: 在登录的情况下, 是不可以访问我的音乐页的, 其他的正常访问.
	if(isLogin === false && to.path === '/my'){
		//没有登录, 不能放行
		alert('请先登录')
		return false;
	}else{
		//其他情况, 一律放行
		return true;
	}
})
//进行默认导出
export default router

总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值