文章目录
- 一.什么是单页面应用?
- 二.什么是路由?
- 生活中的路由和Vue中的路由
- 三.VueRouter(重点)
- 0.引出
- 1.介绍
- 2.下载与使用(5个基本步骤+2个核心步骤)
- 2.1 五个基本步骤
- 2.2 两个核心步骤
- 四.路由的封装抽离
- 五.声明式导航
- 1.导航链接
- 特点一:能跳转
- 特点二:能高亮
- 2.两个高亮类名
- 2.1.区别
- 2.2.为什么支持模糊匹配的类用得更多?
- 2.3.自定义高亮类名
- 3.跳转传参
一.什么是单页面应用?
-
定义和特点:所有功能都在一个HTML中实现
-
示例:网易云音乐
-
多页面应用:京东和淘宝
-
区别:两者的导航栏跳转方式明显不同
-
对比:
-
- 单页只有一个HTML页面,按需更新性能高,开发效率快,用户体验好,但学习成本高,首屏加载慢,SEO较差
-
- 多页即多个HTML页面,整页更新的特点让其性能较低,开发效率一般,用户体验一般,学习成本中等,但首屏加载快,SEO较好
*SEO:搜索引擎优化,可以理解为搜索结果的友好度
- 多页即多个HTML页面,整页更新的特点让其性能较低,开发效率一般,用户体验一般,学习成本中等,但首屏加载快,SEO较好
-
使用场景:
-
- 单页:系统类网站,内部网站,文档类网站,移动端网站
-
- 多页:公司官网,电商类网站
二.什么是路由?
由于单页面应用的按需更新的特点,我们必须明确访问路径和组件的对应关系
这就需要用到路由,它实际上是一种映射关系
生活中的路由和Vue中的路由
路由器:IP和设备之间的映射关系
Vue中的路由:路径和组件之间的映射关系
示例:
http://localhost:8080#home路径 映射到 Home.vue组件
http://localhost:8080#comment路径 映射到 Comment.vue组件
http://localhost:8080#search路径 映射到 Search.vue组件
三.VueRouter(重点)
0.引出
在单页面应用中,点击导航栏的不同标签,
首先,地址栏中的地址要发生变化.其次,导航栏下方的组件也要对应变化
–Vue官方提供了一个插件可实现以上功能,即VueRouter
1.介绍
- 作用:修改地址栏地址时,切换显示匹配的组件
- 本质:Vue官方的一个路由插件,是一个第三方包
2.下载与使用(5个基本步骤+2个核心步骤)
2.1 五个基本步骤
- 下载:下载VueRouter模块到当前工程项目中(Vue.2对应的版本是3.6.5)*
安装命令:yarn add vue-router@3.6.5
注:此命令我按照报错,最后用了这个命令:
npm install vue-router@3.6.5 -g
对于安装版本的匹配,有个口诀叫"233 344",即:
Vue2+VueRouter3.x+Vuex3.x
"344"同理
- 引入
main.js==>若不考虑路由的封装和抽离,所有路由相关代码可先堆在main.js中
import VueRouter from 'vue-router'
- 安装注册
//由于VueRouter是Vue的插件,所以必须先安装注册后才能使用
Vue.use(VueRouter)//内部会对组件进行全局的注册,即插件的初始化
- 创建路由对象
const router=new VueRouter();//此时的路由对象和Vue实例还没有建立关联
- 注入:将路由对象注入到new Vue实例中,建立关联
new Vue({
render:h=>h(App),
//router:router可简写如下:
router
}).$mounted("#app");
//注入完成,代表着这个Vue实例已经被路由对象接管了
//效果:地址栏最后会多出一个"#"
完整代码:main.js
//1.下载:在根目录文件下下载:npm install vue-router@3.6.5 -g
main.js
//2.引入
import VueRouter from "vue-router"
//3.安装注册
Vue.use(VueRouter);//VueRouter插件初始化
//4.创建路由对象
const router=new VueRouter();//后续可以在里面添加路由规则
//5.注入
new Vue({
render:h=>h(app),
router,//router:router,简写成router,(router:rOther)
}).$mount("#app")//当前vue实例已被路由对象所管理
//成功标志:地址栏多了"#"
2.2 两个核心步骤
- 项目代码
//App.vue
<div class="footer_warp">
<a>发现音乐</a>
<a>我的音乐</a>
<a>好友</a>
</div>
//新建Views文件夹下的FindMusic.vue,MyMusic.vue和MyFriends.vue三个组件,
//内容随意,引入过程略
- step1:配置规则
//main.js或router/index.js
import FindMusic from "..."
...
const router =new VueRouter({
routes:[//配置规则
{path:'/FindMusic',component:FindMusic},
{path:'/MyMusic',component:MyMusic},
{path:'/MyFriends',component:MyFriends},
//此处可直观看到路由的定义:path和component之间的映射
});
*path中的路径没有"."在前面,不要写成相对路径
- step2:配置导航
<a href="#/FindMusic"">发现音乐</a>
<a href="#/MyMusic">我的音乐</a>
<a href="#/MyFriends">好友</a>
<div>
<!-- 这个标签的位置决定了组件内容展示的位置-->
<router-view></router-view>
</div>
最终效果:点击不同的a标签,地址栏显示不同的"#"后的内容
四.路由的封装抽离
把所有的路由配置都放在main.js显然是不合适的,因此要将路由模块抽离出来,更利于维护
- 步骤
把刚刚在main.js 中写的路由相关的代码挪到新建的router/index.js中然后在main,js中导入
import router from "./router/index.js"
- 注意事项
- 把代码放入index.js 后,相对路径会发生变化,此时要么调整成正确的相对路径,要么使用"@"(代表src文件夹),写入绝对路径
- 需要在index.js中重新引入Vue,因为使用到了
Vue.use(VueRouter)
,其实main.js也有,只是引用语句import Vue from "vue"
在main,js中是自动生成的 - 最后需将路由对象导出:
export default router;
五.声明式导航
在Vue2中:
声明式导航就是<router-link to=""></router-link>
,<router-link to=""></router-link>
就是声明式导航
与声明式导航相对的是编程式导航
1.导航链接
使用vue-router的全局组件<router-link to=""></router-link>
代替a标签,可以实现导航高亮效果(当前在哪个tag,它就有不同颜色
特点一:能跳转
<router-link to="/FindMusic">发现音乐</router-link>
to不可省略且不用在路径中加"#",对比a标签:
<a href="#/FindMusic"">发现音乐</a>
特点二:能高亮
声明式导航能实现自动高亮,默认提供高亮类名,可以通过高亮类名设置高亮样式
(在控制台能看到选中的a标签自动获得两个类名)
route-link本质上还是a标签,在控制台查看元素,发现渲染出来的还是<a></a>
2.两个高亮类名
<router-link to=""></router-link>
会自动给当前导航添加两个高亮类名,
分别叫:router-link-exact-active
和router-link-active
2.1.区别
- router -link-active
这个用得多,它是模糊匹配的
如:a href="#/my"
标签中有这个类,那么它将匹配所有以my开头的路径:/my /my/a /my/b
- router-link-exact-active
这个类时精确匹配的,写的什么就匹配什么
2.2.为什么支持模糊匹配的类用得更多?
场景:网易云音乐在"发现音乐"的一级导航栏下面还有二级导航栏:推荐,排行榜,歌单等等
此时我们对页面有一个需求,
即用户在二级菜单下来回点击的时候,一级导航栏"发现音乐"要保持高亮状态
这时候就是模糊匹配中的/my/a和/my/b情况(/FindMusic/、 /FindMusic/TopList 和/FindMusic/PlayList
)
2.3.自定义高亮类名
这两个类名太长了,可以在router路由对象中进行定制:
//main.js或index.js
const router=new VueRouter({
routes:[...],
linkActiveClass:"新类名1",//比如"active"
linkExactActiveClass:"新类名2",//比如:"exact-active"
});
//style
.active{}
.exact-active{}