路由:主要是可以实现单页面应用
1.1-路由及工作原理介绍
-
前端路由和后端路由不是同一个东西,不要搞混淆
-
后端路由:
url地址
和后端逻辑
的对应关系 -
前端路由:
url地址
和组件
的对应关系
-
-
1.前端中的路由 : 不同的路径对应加载不同的页面,且页面不会跳转
-
路由的功能类似于tab切换,但是更加的高级,性能更好
-
-
2.路由的工作原理 :
监听网页hash值变化
-
(1)修改网页的hash值
-
hash值原本的作用是来做锚点定位的,它有一个特点就是页面不会跳转
-
-
(2)给window注册onhashchange事件,监听hash值变化
-
当页面hash变化时,就会执行这个事件处理函数,然后就可以根据不同hash值加载不同页面
-
-
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!--
1.前端中的路由 : 不同的路径对应加载不同的页面,且页面不会跳转
2.路由的工作原理 : 监听网页hash值变化
(1)修改网页的hash值
* hash值原本的作用是来做锚点定位的,它有一个特点就是页面不会跳转
(2)给window注册onhashchange事件,监听hash值变化
* 当页面hash变化时,就会执行这个事件处理函数,然后就可以根据不同hash值加载不同页面
-->
<!-- 1.点击按钮:修改地址栏的hash值 -->
<button onclick="window.location.hash = '#/a'">按钮1</button>
<button onclick="window.location.hash = '#/b'">按钮2</button>
<button onclick="window.location.hash = '#/c'">按钮3</button>
<div id="box">
我是组件
</div>
<script>
//2.给页面注册hash值变化事件
window.onhashchange = function(){
if(window.location.hash == '#/a'){
box.innerHTML = '<p>我是组件A</p>';
}else if(window.location.hash == '#/b'){
box.innerHTML = '<p>我是组件B</p>';
}else if(window.location.hash == '#/c'){
box.innerHTML = '<p>我是组件C</p>';
}
};
</script>
</body>
</html>
1.2-单页面应用SPA介绍
-
singal page application
目标: 了解什么是单页面应用, 以及前端路由作用
单页面应用: 所有功能在一个页面上实现
前端路由: 实现业务场景切换
经典单页面应用案例:网易云音乐
单页面-多页面对比
对比部分 | 单页应用 | 多页面应用 |
---|---|---|
组成 | 一个html文件多个组件组成 | 多个html文件 |
静态资源共用 | 共用,一次性加载完毕 | 不共用,每个页面都加载一遍 |
刷新方式 | 页面局部刷新 | 整页加载 |
url模式 | itcast.com/#/pageone | itcast.com/pageone.html |
用户体验 | 用户体验良好 | 页面切换加载缓慢体验较差 |
数据传递 | 容易 | 依赖url传参,cookie,localStorage |
搜索引擎优化 | 不利于seo优化,需要ssr优化(服务端渲染) | 支持良好 |
使用场景 | 追求高体验 不要求seo | 高度要求seo |
开发成本 | 较高 需要依赖专业的框架, 开发效率高 | 较低 重复代码多, 开发效率低 |
优点:
-
整体不刷新页面,用户体验更好
-
数据传递容易, 开发效率高
缺点:
1.3-vue路由使用流程
给vue添加路由有三种方式
以下两种实际开发推荐(自动配置一条龙服务)
(1)vueui 创建脚手架的勾选 vue-router选项
(2)在根目录执行: vue add router
这个命令可以让你原本没有配置路由的项目,一键配置。与vueui作用一致
以下方式实际开发不推荐,但是学习vue路由必须要掌握的(工作中可以不写,但是不能不知道)
(1)手动根据官方文档完整配置路由6个步骤
(2)能够使用模块化语法把路由封装到 ./router/index.js 文件中
-
路由完整配置六个流程
- 1.导入组件
- 2.创建routes路由规则(路径和页面一一对应)
- 3.创建路由对象
- 4.把路由对象挂载到App.vue
- 5.在页面写路由导航router-link (生成a标签)
- 6.在页面写路由出口router-view (生成占位盒子,用于显示页面内容)
-
vue路由官方文档:Vue Router
-
vue本身不提供路由功能,而是由vue团队提供的
Vue Router
插件完成,因此Vue Router
也称之为vue全家桶中的一员
-
-
最简单的一键生成路由的方式:使用
vue ui
创建项目的时候,只需要勾选Router
选项即可-
什么
导包
,什么配值
,全部给你一条龙搞定!
-
-
开发成本高(需要学习路由)
-
首次加载会比较慢一点。不利于seo搜索引擎优化
总结: 单页面应用, 用户体验好, 开发效率高
url
和组件的对应关系
-
不同于功能类的
组件
,路由管理的组件
一般放在/views
目录1.1
/views
目录:放组件的地方,这里的组件一般对应页面级别(整个页面)
1.2
/components
目:也是放组件的地方,这里的组件一般对应需要复用的页面局部内容
-
路由管理的
组件
都是页面级别
-
一般路由管理跳转的组件都是页面级别,放入views文件夹中
-
-
属性:
-
path
:地址 -
component
:组件 -
name
:类似于组件的name
属性,可以省略
-
-
1.传统导入: 不管这个组件你用不用,都会加载
-
2.懒加载导入:只有访问的时候才会导入,不访问就不导入
-
牺牲时间换空间:第一次加载慢一点点
(一丢丢)
,但是可以节省内存空间
-
-
3.两者选择取决于这个页面一般用户访问的多不多。 多就用传统导入,少就用懒加载导入
手动加个页面
-
views
目录下添加一个组件,比如list.vue
-
在
/router/index.js
中导入组件
并配置规则 -
在
App.vue
中顶部添加一个router-link
并设置to
属性即可 -
切换到浏览器,点击切换看看
<template>
<div class="list-container">
<h2>列表页</h2>
<ul>
<li>新闻1</li>
<li>新闻2</li>
<li>新闻3</li>
<li>新闻4</li>
</ul>
</div>
</template>
<script>
export default {
name: 'list'
}
</script>
<style>
.list-container {
overflow: hidden;
}
</style>
-
前端路由指的是
地址
和什么的对应关系?组件(页面)
-
router-link
的作用?路由跳转
-
router-view
的作用?路由内容显示
-
路由管理的
页面(组件)
一般放在哪个目录下?/views文件夹
1.4-路由模式
官网介绍:不同的历史模式 | Vue Router
路由有两种模式
-
hash路由例如: http://localhost:8080/#/home
-
history路由例如: http://localhost:8080/home (以后上线需要服务器端支持, 否则找的是文件夹)
const router = new VueRouter({
mode: 'hash',
base: process.env.BASE_URL,
routes
})
1.5-路由重定向
路由重定向官方文档:重定向和别名 | Vue Router
-
重定向应用场景
: 页面输入根路径/ , 自动跳转到首页 -
注意点
: 重定向只是修改路径, 还需要单独去设置路由匹配规则
const routes = [
{
path: '/',
/*
(1)重定向只是修改页面路径。 输入 / 会重定向到 /find
(2)只有component才会让vue去寻找路由匹配页面。所以设置了重定向,还需要单独设置匹配规则
*/
redirect: "/find"
},
{
path: '/find',
name: 'find',
component: find
},
]
1.6-404重定向
-
1.
*
的作用类似于通配符:表示任意路径 -
2.默认情况下,当我们输入网址的时候。 vue会从
routes数组中
依次去匹配路径,如果上面的全部无法匹配就会跳转*
对应的组件页面-
这一点跟nodejs那个404的原理基本类似
-
const routes = [
// ...省略了其他配置
// 404在最后(规则是从前往后逐个比较path)
{
path: "*",
component: NotFound
}
]
02-vue路由跳转传参
共四种方式,常用的只有两种。学习阶段四种都要学习,重点掌握其中两种即可
第一种:
发送参数(跟之前ajaxget参数类似)
<router-link to="/path?key=value"></router-link>
接收参数: $route.query.key
第二种:
发送参数:其实跟第一种底层原理是一样,但是用js来写的。(相当于 a标签href和window.location.href一样,底层原理都是修改地址栏href. 区别是一个是a标签,一个是js代码)
this.$router.push({path: "/path", query: {key: value}})
接收参数:$route.query.key
跳转方法 | 传参位置 | 路由规则 | 接收 |
---|---|---|---|
<router-link to="/path?key=value"></router-link> | /path?key=value | 无特殊 | $route.query.key |
<router-link to="/path/值"></router-link> | /path/值 | /path/:key | $route.params.key |
this.$router.push({path: "/path", query: {key: value}}) | query的对象 | 无特殊 | $route.query.key |
this.$router.push({name: "com", params: {key: value}) | params的对象 | 路由规则需要name属性 | $route.params.key(注意,这种在内存中保存) |
1.1-vue动态路由匹配(声明式导航)
-
动态路由匹配官方文档:带参数的动态路由匹配 | Vue Router
-
动态路由匹配(又叫声明式导航)介绍
-
作用
:实现get方式传参-
看起来像是get传参,实际上是给
组件传值
-
-
-
动态路由匹配传参分为三个流程
-
1.定义路由规则
-
2.传递参数
-
3.接收参数
-
-
1.定义路由规则
-
两个都要写哟,否则只能params传参,无法query传参
-
{
path: '/friend',
name: 'friend',
component: friend
},
{
path: '/friend/:name/:age',
name: 'friend',
component: friend
},
2.传递参数
-
标准写法(query传参): /path?参数名=值
-
简洁写法(params传参): /path/参数值1/参数值2
3.接收参数
-
如果是标准写法,这样接收参数:
$route.query.参数名
-
如果是简洁写法,这样接收参数:
$route.params.参数名
1.2-vue路由的编程式导航
声明式导航和编程式导航区别
1.声明式导航: 通过a标签href跳转传参
* 需要在路由中单独配置: /path:/参数名 * params参数在url可以看到(url传参),刷新不会消失2.编程式导航:通过js代码来跳转传参
不需要在路由单独配置
params参数在url看不见(内存传参),刷新会消失
-
编程式导航官方文档:编程式导航 | Vue Router
-
编程式导航介绍
-
1.作用 : 使用js代码是做路由跳转 (替代router-link)
-
2.语法 :
-
$router.push('路径')
-
$router.push({name:'组件name'})
-
-
3.应用场景:如果希望满足条件才跳转,就可以使用编程式导航
-
router-link :相当于a标签,只要点击就会跳转,没有逻辑
-
$router.push('路径'):相当于window.location.href,使用js来做业务逻辑
-
-
1.3-编程式导航传参
-
官方文档:路由属性
-
动态路由匹配介绍
-
1.作用 : 跳转路由时给组件传参
-
类似于以前跳转页面window.location.href传参
-
-
2.语法
-
语法1:通过
路径传参(刷新页面还在)
,写在query中-
// 分开写,变成 /地址?key=value this.$router.push({ path: '路由地址', query: { key: 'value' }}) // 直接写 this.$router.push({ path: '路由地址?key=value&key2=value2'})
-
对应路由接收
this.$route.query.key 取值
-
-
语法2:通过
params传参(内存传递,刷新页面就不在了)
-
// 通过路径跳转 this.$router.push({ path: '路由地址', query: { key: 'value' }}) // 通过名字跳转 this.$router.push({name: '路由name' , params: { key: 'value' }})
-
对应路由接收
this.$route.params.key 取值
-
-
-
3.应用场景:相当于跳转 页面(组件的html) 传参
-
this.$router
和this.$route
是否一样?
-
不是
-
this.$router
,可以用来跳转 -
this.$route
,可以获取参数
03-二级路由(嵌套路由)
嵌套路由官方文档:嵌套路由 | Vue Router
1.为什么要有二级路由
-
点击导航栏切换页面的时候(PC端导航栏一般在顶部,移动端导航栏一般在底部),如果该页面又需要出现导航栏。这个时候就需要嵌套路由.
-
2.配置二级路由规则
-
二级路由页面,一般会放在
./views/子目录
中
-
-
./router/index.js中导入二级路由页面
-
注意路径别写错了哈
-
二级路由path有/和没有/区别
如果有/,例如 /Ranking : 可以省略一级路由路径,直接通过 /Ranking访问二级路由
如果没有/,例如 Ranking : 不可以省略一级路由路径,需要通过 /find/Ranking访问二级路由
04-路由导航守卫
1.1-路由导航守卫语法介绍
刚开始接触路由导航守卫你会发现和axios拦截器有点像,实际上它们是两个不同的东西。
1.相同点
(1)都是钩子函数(回调函数的一种,到某个时机了自动触发)
(2)都是起到拦截作用
2.不同点
(1)功能不同 : axios拦截器
拦截网络请求
, 导航守卫拦截路由跳转
(2)应用场景不同 :
axios拦截器一般用于发送token
导航守卫用于
页面跳转权限管理
(有的页面可以无条件跳转,例如商城首页可以无条件跳转。有的页面需要满足条件才能跳转,例如购物车页面就需要用户登录才可以跳转)
-
官网文档:路由导航守卫
-
1.什么是路由导航守卫? : 通俗来讲,就是
路由跳转
的时候需要执行
的一个回调函数
-
路由导航:就是路由跳转的意思
-
守卫:类似于
门卫
,你做某件事之前会对你进行一个检查
-
-
2.为什么要有路由导航守卫
-
在项目开发中,并不是每一个路由跳转都是
明确
的。 例如很多页面跳转需要登录判断,如果你有登录,则跳转到指定页面,没有登录则跳转到登录页面。-
举例子:我想进小区(个人信息),门卫(导航守卫)会检查我有没有做核酸(是否登录),如果做了就让我进去(跳转个人信息)。没做就让我去核酸点(登录页面)做完核算才可以进去。
-
-
-
3.路由导航守卫有哪些?
-
前置守卫:跳转前执行
-
后置勾子:跳转后执行
-
-
导航守卫语法介绍(
导航守卫需要创建完路由对象之后才能使用
):-
==一定要注意,在导航守卫中必须要调用
next()
否则你的路由无法跳转==
-
1.2-使用导航守卫完成登录页面跳转
项目开发中,并不是每一个页面都需要做登录页面跳转的。以网易云为例
1.首页: 不需要登录判断,任何用户都能访问
2.我的朋友:需要做登录判断。
-
实现登录页面路由导航守卫
-
一般判断页面最好用
组件的name属性
,因为path有时候后面会拼接参数-
这个地方可以提现name属性作用哟
-
-
路由导航守卫一定要写在创建router之后哈
-
因为这个给router挂载的钩子
-
-
05-组件缓存keep-alive
-
官方文档:动态组件 & 异步组件 — Vue.js
1.为什么要有组件缓存
(1)路由切换时, 消失的页面, 会被销毁, 触发destroyed
(2)再切换回来, 重新创建, 所有代码重新执行, 效率不
1.1-组件缓存基本使用
-
给router-view外面包裹Vue自带的keep-alive标签即可
-
默认情况下,会缓存所有组件
1.2-缓存指定组件
-
在keep-alive的时候, 使用include/exclude区分即可
1.3-组件缓存勾子
-
问题:组件不执行销毁/初始化创建的方法了, 如何知道组件被失去激活/激活呢?
-
使用组件缓存勾子即可
-
activated --- 组件被激活状态
-
deactivated --- 组件被失去激活状态
-