6.路由
6.1.介绍
6.1.1.vue-router
vue
中的一个插件库,专门用来实现SPA应用。
6.1.2.SPA应用
单页Web应用
(single page web application,SPA)。
整个应用只有一个完整的页面。
点击页面中的导航链接不会刷新页面,只会做页面的局部更新。
数据需要通过ajax请求获取。
6.1.3.路由
一个路由就是一组映射关系(key -- value)
key
为路径,value
可能是function
或component
。
后端路由
理解:value
是function
, 用于处理客户端提交的请求。
工作过程:服务器接收到一个请求时, 根据请求路径找到匹配的函数来处理请求, 返回响应数据。
前端路由
value
是component
,用于展示页面内容。
工作过程:当浏览器的路径改变时, 对应的组件就会显示。
6.2.基本路由
使用之前安装
vue-router
vue-router3安装:
npm i vue-router@3
,这个版本匹配vue2
vue-router4安装:
npm i vue-router
,这个版本匹配vue3
使用
-
安装
vue-router
-
在
src
下新建一个文件夹router
,创建一个文件index.js
,配置如下信息// 引入VueRouter import VueRouter from "vue-router"; // 引入route的组件,要配显示的组件 import Home from '../components/Home' import About from '../components/About' // 创建并且暴露VueRouter export default new VueRouter({ // 配置路由 routes:[ // 配置About路由 { // 路由的访问路径 path: '/about', // 路由的访问组件 component: About }, // 配置Home路由 { // 路由的访问路径 path: '/home', // 路由的访问组件 component: Home } ] })
-
在
main.js
中引入VueRouter
和router(刚才新建的index.js)
-
然后使用
VueRouter
:Vue.use(VueRouter)
-
配置
router
new Vue({ render: h => h(App), // 配置router router }).$mount('#app')
-
-
在
app
组件中进行显示即可
效果图
代码示例
App
main.js
index.js
6.3.注意点
1.路由组件通常存放在pages文件夹,一般组件通常存放在components文件。
- .路由组件:用于处理应用程序路由的特殊组件
- .一般组件:一个通用的组件
2.通过切换,隐藏了的路由组
件,默认
是被销毁掉的,需要的时候再去挂载。
3.每个组件都有自己的$route
属性,里面存储着自己的路由信息。
4.整个应用只有一个router
,可以通过组件的$router
属性获取到
6.4.嵌套(多级)路由
使用和基本路由大致相似,主要配置以下点
-
在一级路由里面配置下一级的路由,下一级的路由路径不要带斜杠
// 配置Home路由 { // 路由的访问路径 path: '/home', // 路由的访问组件 component: Home, // 配置二级路由 children:[ // 注意:多级路由的路径不需要加`/` { path: 'news', component: News, }, { path: 'message', component: Message } ] }
-
多级路由的访问路径需要带上父路由的路径·
//一级路径的访问路径 <xxx class="xxx" to="/Home/> <xxx class="xxx" to="/home/news"/> //二级路径的访问路径
效果图
代码示例
index.js
About
Message
Home
6.5.路由传参
6.5.1.query
使用
-
传递参数
<!-- 模板字符串方式:用反引号``包裹起来,不要漏了绑定to <!-- 问号后面携带的计算参数,使用${}的方式动态传递参数,多个参数使用&分割 <xxx :to="`/访问路径?参数名字1=${参数1}&参数名字2=${参数2}`" /> <!-- 对象写法,同样是要绑定to,但是双引号里面使用对象的形式 <!-- path:访问的路径 <!-- query:携带的参数 <xxx :to="{ path: '访问路径', query:{ 参数名字1: 参数1, 参数名字2: 参数2 } }" />
-
接收参数
$route.query.参数名字1 $route.query.参数名字2
效果图
代码示例
index.js
Detail
Message
6.5.2.params
使用
-
配置路由
{ // 路由的访问路径:这里需要配置占位符: :参数名字1/:参数名字2.... path: '/xxx/:参数名字1/:参数名字2', // 路由的访问组件 component: xxx }
-
传递参数
<!-- 模板字符串方式:不要漏了绑定to <!-- 直接写传递的参数即可,使用${}的方式动态传递参数 <xxx :to="/访问路径/${参数1}/${参数2`" /> <!-- 对象写法,同样是要绑定to,但是双引号里面使用对象的形式 <!-- name:访问的路由名字 <!-- params:携带的参数 <xxx :to="{ name: '访问路径', params:{ 参数名字1: 参数1, 参数名字2: 参数2 } }" />
-
接收参数
$route.params.参数名字1 $route.params.参数名字2
注意:当使用params
方法传递参数时,若使用to
的对象写法,则不能使用path
配置项,必须写成name
配置项!name
是什么,往下看!!!!!!
6.6.命名路由、props、replace
6.6.1命名路由
作用:使用多级路由时可以简化路径
使用
-
配置路由时给路由起一个名字
routes:[ // 配置About路由 { //给路由起名字 name: '路由名字', // 路由的访问路径 path: '/about', // 路由的访问组件 component: About },
-
访问时需要写成对象的写法才能使用
name
<!-- 对象写法,同样是要绑定to,但是双引号里面使用对象的形式 <!-- name:路由名字(访问的路由路径) <xxx :to="{ name: '路由名字', }" />
代码示例
index.js
Message
6.6.2.props
作用:可以让路由组件更方便的接收参数
使用:在index.js
配置路由时使用一个全新的配置:props
//写法1:值为对象,该对象中所有的key-value的组合最终都会通过props传给Detail组件
props:{参数名字1:参数1,参数名字2:参数2.....}
//第二种写法: 值为true,则把路由收到的所有`params`参数通过props传给Detail组件
//这种写法只能收到params参数,因为这个参数可以在配置路径时使用占位符,因此可以获取到占位符的参数
props:true
//第三种写法: props值为函数,该函数返回的对象中每一组key-value都会通过props传给Detail组件
//函数的参数为:$route ,函数的返回值为一个函数
props($route){
return {参数名字1:参数1,参数名字2:参数2.....}
}
代码示例
前两种没有第三种好,不做示例
6.6.3.router-link中的replace属性
1.作用:控制路由跳转时操作浏览器历史记录的模式
2.浏览器的历史记录有两种写入方式:push
和replace
,push
是追加历史记录,replace
是替换当前记录。
路由跳转时候默认为push
3.如何开启replace
模式:<router-link replace ......>News</router-link>
6.7.导航、缓存、生命钩子
6.7.1.编程式路由导航
作用:不借助router-link
实现路由跳转,让路由更加灵活
this.$router.push(跳转的路径,携带的参数)
:相当于点击路由链接(可以返回到当前路由界面)
this.$router.replace(跳转的路径,携带的参数)
: 用新路由替换当前路由(不可以返回到当前路由界面)
下面三个方法使用方式是一样的,不做示例
this.$router.back()
:请求(返回)上一个记录路由
this.$router.go(-1)
: 请求(返回)上一个记录路由
this.$router.go(1)
:请求下一个记录路由
代码示例
6.7.2.缓存路由组件
作用:让不展示的路由组件保持挂载,不被销毁。
使用
<!-- 这个配置项可以指定组件名不被销毁,include="组件名"
如果不写这个配置项,那keep-alive包裹的全部组件都会不被销毁
如果有多个::include="['组件名1,'组件名2']" -->
<keep-alive include="组件名">
要缓存的组件
</keep-alive>
效果图
代码示例
home
news
即使切换到message
组件在切回news
组件,输入框内的数据也还存在
6.7.3.两个新的生命钩子
作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态。
activated
:路由组件被激活时触发deactivated
:路由组件失去激活时触发
效果图
代码示例
6.8.路由守卫
对路由进行权限控制
6.8.1.全局前置路由守卫
初始化时执行、每次路由切换前执行
使用
- 创建
VueRouter
并接收对象,先不要进行暴露 - 用刚才接收的对象调用
全局前置路由守卫(beforeEach)
的方法,方法有三个参数to
:即将要跳转的目标路由对象。from
:当前导航正要离开的路由对象。next
:必须被调用以 resolve 这个钩子。可选参数包括一个处理后的路由对象或者false
中止当前导航。
效果图
代码示例
6.8.2.全局后置路由守卫
初始化时执行、每次路由切换后执行
使用:使用和前置大致相同,只是执行的时机不同
- 创建
VueRouter
并接收对象,先不要进行暴露 - 用刚才接收的对象调用
全局后置路由守卫(afterEach)
的方法,方法有三个参数to
:即将要跳转的目标路由对象。from
:当前导航正要离开的路由对象。- 后置没有
next
方法,因为已经跳转完了,不需要这个方法
6.8.3.独享路由守卫
初始化时执行、每次路由切换前执行
这个守卫的使用配置以及使用时机都是一样的
使用:在需要守卫的路由里面配置独享路由守卫(beforeEnter)
的方法,方法有三个参数
to
:即将要跳转的目标路由对象。from
:当前导航正要离开的路由对象。next
:必须被调用以 resolve 这个钩子。可选参数包括一个处理后的路由对象或者false
中止当前导航。
效果图
代码示例
6.8.4.组件内路由守卫
初始化时执行、每次路由切换前执行
使用:在需要守卫的路由里面配置组件内路由守卫
的方法
方法有两个:进入组件时beforeRouteEnter
,离开组件时beforeRouteLeave
,两个方法都有三个参数
to
:即将要跳转的目标路由对象。from
:当前导航正要离开的路由对象。next
:必须被调用以 resolve 这个钩子。可选参数包括一个处理后的路由对象或者false
中止当前导航。
效果图
代码示例
6.8.5.区别
作用以及执行时机
全局前置路由守卫:应用级别的路由守卫,用于拦截所有路由跳转,在路由守卫解析完毕并确定了要跳转的目标路由之后,但该路由所对应的组件尚未被加载时执行。
独享路由守卫:指仅针对某个具体路由或者路由组的路由守卫,只有当路由的路径与其匹配时才会触发。
组件内进入路由守卫:指在组件内部定义的路由守卫,只有该组件被访问时才会触发。
全局后置路由守卫:应用级别的路由守卫,用于在路由跳转完成之后执行一些操作,比如页面统计或日志记录等,而不会阻止路由的跳转。
组件内离开路由守卫:指在组件内部定义的路由守卫,用于控制离开该组件的路由是否合法,类似于组件内进入路由守卫。
分组总结
进入前
全局前置路由守卫和独享路由守卫都是用于防止未授权的访问,在路由跳转发生之前执行一些操作;
组件内进入路由守卫只是针对当前组件的路由守卫,用于控制进入该组件的路由是否合法。
进入后
全局后置路由守卫会在路由跳转成功后立即执行,而不会对路由本身进行任何限制;
组件内离开路由守卫则是用于判断是否可以离开当前组件,如果返回 false,则会阻止路由跳转,并保持当前组件的状态。
6.9.工作模式
路由中有两种工作模式:
history
和hash
1.对于一个url
来说,什么是hash值? #
号及其后面的内容就是hash值。
2.hash
值不会包含在HTTP
请求中,即:hash值不会带给服务器。
3.区别
- hash模式
- 地址中永远带着
#
号,不美观 。 - 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法。
- 兼容性较好。
- 地址中永远带着
- history模式
- 地址干净,美观。
- 兼容性和hash模式相比略差。
- 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题。