VueRouter路由深入浅出
VueRouter 介绍:
Vue Router
是 Vue.js官方的路由管理器:
极大地简化了在 单页面应用程序 SPA-Single Page Application
: 中构建导航和页面切换的复杂性;
单页面应用程序 SPA
单页面应用程序SPA,Single Page Application
:
在用户首次访问时加载整个应用程序或核心资源,之后页面切换通过JavaScript
动态更新内容,而不需要重新加载整个页面;
用户体验: 提供流畅的导航体验,页面切换快,类似于原生应用,因为内容通常是异步加载的;
技术实现: 依赖前端路由技术,如Vue Router
、React Router
等,来管理页面视图的切换;
前后端分离: 前端负责渲染和交互,后端专注于数据处理和API
服务;
多页面应用程序 MPA
多页面应用程序MPA,Multi Page Application
:
每个功能或内容块对应一个独立的HTML页面,用户导航到新页面时,
浏览器会发起新的HTTP请求,加载完整的HTML文档及相关的CSS、JavaScript等资源;
用户体验: 页面切换涉及完整的页面刷新,可能会感觉较慢,因为:每个页面都是独立加载的;
SEO友好: 因为每个页面都是独立的HTML文件,搜索引擎更容易抓取和索引内容
开发方式: 前端和后端的界限不那么明显,通常后端会直接参与视图的渲染;
总结:
单页应用类网站:系统类网站 / 内部网站 / 文档类网站 / 移动端站点,如:网易云音乐 https://music.163.com/
多页应用类网站:公司官网 / 电商类网站,如:京东 https://jd.com/
Vue中的路由:
Vue中的路由,即前端路由技术,它处理的是用户在:单页面应用程序SPA
中的导航;
Vue Router允许开发者定义不同的URL路径,并将这些路径与特定的Vue组件关联起来:
当用户导航
到一个新的URL时,不是加载整个新页面,而是动态地替换当前视图中的内容,展示与新URL相关联的组件;
Vue路由的基本使用:
安装与初始化:
通过NPM
或CDN
获取:Vue Router
,vue2.0对应的路由版本:VueRouter3.x
#下载 VueRouter 模块到当前工程,版本3.6.5
yarn add vue-router@3.6.5 #yarn安装
npm install vue-router@3.6.5 --save #npm安装
注意:根据Vue版本匹配路由版本: Vue2—VueRouter3.x-Vuex3.x
、Vue3-VueRouter4.x-Vuex4.x
创建对应路由组件
本案例以:网易云网站,举例: 在src/views/定义路由组件.vue
文件 为了规范代码通常在:
src/views文件夹
定义:页面组件 - 页面展示 - 配合路由用;src/components文件夹
定义:复用组件 - 展示数据 - 常用于复用;
自定义路由页面组件: 这里就不帖代码了;
src/views/FindMusic.vue
发现音乐,路由模块;src/views/MyFriend.vue
我的朋友,路由模块;src/views/MyMusic.vue
我的音乐,路由模块;
主应用引入\配置路由
main.js: 文件中引入并使用刚创建的路由器实例;
import Vue from 'vue' import App from './App.vue' Vue.config.productionTip = false
//1.下载 v3.6.5 yarn add vue-router@3.6.5
//2.引入vue-router npm包
import VueRouter from 'vue-router';
// 引入自定义组件页面 views目录) 配规则;
import FindMusic from './views/FindMusic';
import MyFriend from './views/MyFriend';
import MyMusic from './views/MyMusic';
//3.安装注册VueRouter插件初始化
Vue.use(VueRouter);
//4.创建路由对象,定义路由规则
const router = new VueRouter({
//route: 一条路由规则 { path: 路径, component: 组件 }
routes: [
{ path: '/findMusic', component: FindMusic },
{ path: '/myFriend', component: MyFriend },
{ path: '/myMusic', component: MyMusic },
]
})
//5.注入到new Vue中,建立关联
new Vue({
render: h => h(App),
router
}).$mount('#app')
在模板中使用路由
App.vue: 模板目录中通过:<router-view></router-view>
标签来渲染匹配的组件;
- 运行Demo:
http://localhost:8080/#/
,#/
表示项目的路由已经被Vue-Router管理了;
<template>
<div>
<div class="footer_wrap">
<a href="#/findMusic">发现音乐</a>
<a href="#/myFriend">我的朋友</a>
<a href="#/myMusic">我的音乐</a>
</div>
<div class="top">
<!-- 路由出口 → 匹配的组件所展示的位置 -->
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {};
</script>
<style><!-- 省略样式代码 --></style>
路由的封装抽离:
路由的封装抽离是Vue.js项目开发中的一个最佳实践:
它涉及到将路由配置和管理从应用的主入口文件通常是:main.js
中分离出来,以提高代码的可维护性和可读性;
1. 创建路由器模块: 在项目的src目录下创建一个router
文件夹、文件夹内创建一个index.js
文件,这是路由器的配置中心;
2.导入Vue和Vue Router: 在src/router/index.js
中,首先需要:导入Vue和Vue Router库、定义路由:
//1.下载 v3.6.5 yarn add vue-router@3.6.5
//2.引入vue-router npm包
import Vue from 'vue'
import VueRouter from 'vue-router';
// 引入自定义组件页面 views目录) 配规则;
import FindMusic from '../views/FindMusic';
import MyFriend from '../views/MyFriend';
import MyMusic from '../views/MyMusic';//3.安装注册VueRouter插件初始化
Vue.use(VueRouter);
//4.创建路由对象,定义路由规则
const router = new VueRouter({
//route: 一条路由规则 { path: 路径, component: 组件 }
routes: [
{ path: '/findMusic', component: FindMusic },
{ path: '/myFriend', component: MyFriend },
{ path: '/myMusic', component: MyMusic },
]
})
//对外暴漏router对象;
export default router;
3.在主入口文件中引入路由器: 在main.js
中:导入之前创建的路由器实例,并将其注入到Vue实例中;
import Vue from 'vue'
import App from './App.vue'//引入并配置路由对象;
import router from './router/index';
Vue.config.productionTip = false;
//5.注入到new Vue中,建立关联
new Vue({
render: h => h(App),
router
}).$mount('#app');
Vue路由的进阶使用⏫:
声明式导航-导航链接
声明式导航: 它允许开发者通过在模板中使用<router-link>
组件来定义导航链接,从而实现页面间的切换;
<router-link>
组件: 它替代了传统的<a>
标签,用于创建导航链接,通过设置to(必须)
属性指定目标路由;
- 路径匹配:
to
属性可以是字符串,表示路径,不需要加#
,Vue Router会处理路由跳转; - 自定义样式: 可以通过这些类名来为激活的链接应用特定的样式,例如高亮显示;
- 这种方式使得导航逻辑更加清晰,代码更加简洁,易于理解和维护;
<template>
<div>
<div class="footer_wrap">
<router-link to="/findMusic">发现音乐</router-link>
<router-link to="/myFriend">我的朋友</router-link>
<router-link to="/myMusic">我的音乐</router-link>
</div>
<div class="top">
<!-- 路由出口 → 匹配的组件所展示的位置 -->
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {};
</script>
<style>
<!-- 省略样式代码 -->
.footer_wrap a.router-link-active { background-color: purple; }
</style>
<router-link>
默认会添加两个CSS类名来表示链接的激活状态:
.router-link-exact-active
通常在,精确匹配 整个路径时添加;.router-link-active
会在链接对应的路由被激活时添加,适用于 模糊匹配 、设置高亮;
为什么 <router-link>
默认添加两个 CSS 类名?
<router-link>
默认添加两个CSS类名,是为了提供两种不同级别的激活状态样式控制:
router-link-active:这个类的设计是为了实现包含匹配的激活逻辑
- 这意味着当路由路径是某个
<router-link>
路径的前缀时,该类会被激活 - 例如:当前路由是
/users/123
,那么所有指向/users/xxx
链接都会被标记为活动状态 - 这种设计考虑到了嵌套路由的场景,使得:父级菜单在子路由被访问时也能保持高亮,增强了导航的上下文感知;
router-link-exact-active:相对地,这个类仅在路径完全匹配时才被激活,提供了更精确的控制;
声明式导航-自定义类名
Vue Router为了提供更多的定制性,开发者可以自定义<router-link>
激活时的CSS类名;
在你的Vue应用初始化时,可以通过以下方式来配置这些类名:
const router = new VueRouter({
routes: [...], // 路由配置
linkActiveClass: 'custom-active', // 自定义模糊匹配激活类名
linkExactActiveClass: 'custom-exact-active' // 自定义精确匹配激活类名
});
声明式导航-查询传参
声明式导航是Vue Router中通过<router-link>
组件实现的一种导航方式:
既然是导航,那么就会有不同的组件页面进行展示: 如:百度搜索,用户输入内容进行搜索,程序根据内容展示不同的结果;
为了方便操作,通常在: 跳转到另一个路由时,将一些数据作为查询参数附加到URL中,以便接收页面可以访问这些参数;
对此,<router-link>
提供两种传参方式: 查询参数传参、动态路由传参;
查询参数传参:
查询参数传参,比较适合传:多个参数 在<router-link>
的to
属性中:直接在路径后面使用问号(?)添加查询参数;
格式为: to="/route?param1=value1¶m2=value2
views/VHome.vue: 搜索模块页面,导航views/Search.vue
带参请求
<template>
<div class="home">
<div class="logo-box"></div>
<div class="search-box">
<input type="text">
<button>搜索一下</button>
</div>
<div class="hot-link">
热门搜索:
<router-link to="/search?key=Java慈祥">Java慈祥</router-link>
<router-link to="/search?key=热爱学习">热爱学习</router-link>
<router-link to="/search?key=如何成为前端大牛">如何成为前端大牛</router-link>
</div>
</div>
</template>
<script>
export default { name: 'VHome' }
</script>
<style></style>
接收参数: 在目标组件中,你可以通过$route.query.属性名
来访问这些参数传递值: views/Search.vue
<template>
<div class="search">
<!-- 在目标组件中,你可以通过$route.query对象来访问这些参数 -->
<p>搜索关键字: {{ $route.query.key }} </p>
<p>搜索结果: </p>
<ul>
<li>.............</li>
<li>.............</li>
<li>.............</li>
<li>.............</li>
</ul>
</div>
</template>
<script>
export default {
name: 'VSearch',
created () {
// 在created中,获取路由参数
// this.$route.query.参数名 获取
console.log(this.$route.query.key);
}
}
</script>
<style></style>
动态路由传参:
动态路由传参,优雅简洁:适合传单个参数 动态路由通过,在路径中使用冒号 :前缀
的占位符来定义;
动态路由传参可选符
动态路由存在问题: 配了路由 path: "/search/:words"
为什么按下面步骤操作,会未匹配到组件,显示空白;
/search/:words
表示,必须要传参数,如果不传参数,也希望匹配,可以加个可选符 "?"
Vue路由—重定向🔃
Vue Router的路由重定向是一种机制,它允许在用户尝试访问某个路径时自动将他们导航到另一个路径:
可以用来简化URL结构、实现默认页面或处理不存在的页面等场景:
在Vue Router的配置中,通过redirect
属性来实现重定向;
//创建路由对象,定义路由规则
const router = new VueRouter({
routes: [
{ path: '/', redirect: "/search" },
{ path: '/search/:words?', component: VSearch },
],
});
Vue路由—404 配置
实际开发中,经常遇到访问到未定义目录,而出现空白页面情况: 为了用户体验,友好提示,通常会对此类页面进行友好提示;
//事先定义好一个404页面
//路由配置文件中引入页面组件
import NotFound from '@/views/NotFound';
//创建路由对象,定义路由规则
const router = new VueRouter({
routes: [
{ path: '/', redirect: "/search" },
{ path: '/search/:words?', component: VSearch },
//建议配在路由最后,程序自上而下匹配规则 * 表示匹配所有路径;
{ path: '*', component: NotFind }
],
});
注意事项:
- 确保在Vue应用中定义了404组件,并且在路由配置中正确导入
- 对于history模式,服务器配置是关键,确保所有未定义的路径都返回应用的入口文件
- 在开发环境中,Vue CLI通常会自动处理路由,但在生产环境部署时,服务器配置是必须的
Vue路由—模式设置
Vue Router 提供了两种路由模式来管理应用的URL行为: hash模式
history模式
Hash模式: 默认
在URL中使用#
来标记路由的变化,如http://localhost:8080/#/home
- 兼容性好,适用于所有现代浏览器以及大部分的老浏览器,它是基于浏览器的原生功能;
- 这种模式依赖于浏览器的锚点(hashchange)事件,不需要服务器端的任何配置;
- 缺点:URL中出现的
#
不太美观,且在某些场景可能与页面内的实际锚点冲突;
History模式: 利用HTML5的History APIpushState, replaceState
来管理历史记录,从而提供无#
的URL;
- 优点:提供了更干净、更
RESTful
的URL,用户体验更好,路由看起来更像传统的服务器端路由; - 缺点:需要服务器端的配合,确保直接访问或刷新非根URL时;
//事先定义好一个404页面
//路由配置文件中引入页面组件
import NotFound from '@/views/NotFound';
//创建路由对象,定义路由规则
const router = new VueRouter({
//History模式
mode: "history",
routes: [
{ path: '/', redirect: "/search" },
{ path: '/search/:words?', component: VSearch },
//建议配在路由最后,程序自上而下匹配规则 * 表示匹配所有路径;
{ path: '*', component: NotFind }
],
});
编程式导航:
Vue的编程式导航是指通过JavaScript代码
直接控制路由的跳转:而不是通过HTML元素<router-link>
触发;
路由跳转(两种)
需求: 点击搜索按钮
根据输入框,搜索对应数据;
在Vue 2中,通常在组件内部通过this.router</code>来访问路由器实例,并使用其方法进行导航; </p><h5 id="4tgmh" name="path%E8%B7%AF%E5%BE%84%E8%B7%B3%E8%BD%AC%E8%AF%AD%E6%B3%95%EF%BC%9A">path路径跳转语法:</h5><p><strong>main.JS设置:</strong> <code>{ path: '/路径', component: 组件模块 }</code></p><p><strong>query传参:</strong> <code>http://localhost:8080/路径?参数名=值</code>,接受参数的方式是:<code>route.query.参数名
//简单写法 query传参
this.$router.push('/路径?参数名1=参数值1&参数2=参数值2');
//完整写法 query传参
this.$router.push({
path: '/路径',
query: {
参数名1: '参数值1',
参数名2: '参数值2'
}
})
动态路由传参: http://localhost:8080/路径/参数值
,接受参数的方式是:$route.params.参数值
main.JS设置: { path: '/路径/:参数值?', component: 组件模块 }
//简单写法
this.$router.push('/路径/参数值')
//完整写法
this.$router.push({ path: '/路径/参数值' });
name 命名路由跳转:
name命名传参和 Path路径传参类似: 因为Vue页面请求是模块化的,所以可以给请求定义名称,更方便进行跳转;
在/src/router/index.js路由规则: 声明路径、组件关系时,支持定于别名,方便跳转使用;
创建路由对象,定义路由规则
const router = new VueRouter({
//History模式
mode: "history",
//route: 一条路由规则 { path: 路径, component: 组件 }
routes: [
//重定向默认home页;
{ path: '/', redirect: "/home" },// { path: '/search', component: VSearch }, //query参数传递 // { path: '/search/:words?', component: VSearch }, //动态参数传递 { path: '/search/', component: VSearch, name: 'search' }, //组件别名 query参数传递 // { path: '/search/:words?', component: VSearch, name: 'search' }, //组件别名 动态参数传递 //建议配在路由最后,程序自上而下匹配规则 * 表示匹配所有路径; { path: '*', component: NotFound }
],
})
query传参: http://localhost:8080/路径?参数名=值
,接受参数的方式是:$route.query.参数名
没有简单写法:
//query传参
this.$router.push({
name: '路由名字',
query: { 参数名1: '参数值1', 参数名2: '参数值2' }
})
动态路由传参: http://localhost:8080/路径/参数值
,接受参数的方式是:$route.params.参数值
//动态路由
this.$router.push({
name: '路由名字',
params: { 参数名: '参数值' }
})
代码管理:
本代码已经使用Git进行管理: 公众号回复:VueRouter