一、前情提要
vue-router是vue的一个插件库(Vue.use()使用),专门用来实现SPA应用。
SPA应用理解:
1、单页面web应用(single page web application,SPA)
2、整个应用只有一个完整的页面,不会跳转新的页面,只做局部更新
3、数据要通过ajax请求获取
二、什么是路由?
一个路由就是一组对应关系(key-value)其中key为路径,value为组件或函数。
路由可以分为:
前端路由:value为组件,当路径改变时,对应的组件展示页面内容;
后端路由:value为function函数,用于处理客户端提出的请求,服务器根据请求路径找到匹配的函数处理请求,返回响应数据。
三、路由的使用
1、编写routers配置项
//专门创建整个应用的路由器
import vueRouter from 'vue-router'
//引入组件
import xxx from '../conponents/xxx'
import yyy from '../conponents/yyy '
//创建并暴漏一个路由器
export default new vueRouter({
//一组组的路由规则
routes: [
{
path: '/xxx',
component: xxx
},
{
path: '/yyy ',
component: yyy
}
]
})
2、实现切换功能 <router-link> (active-class:“active”可高亮显示。
3、指定展示位置 <router-view>
attention:
1、可将路由组件存放在pages文件夹中,普通组件存放在components文件夹
2、通过切换隐藏的路由组件实际上是被销毁了,点击时再去重新挂载
3、整个应用只有一个路由器router,每个组件的路由信息存储在各自的$route属性中
四、嵌套路由(多级路由)
配置路由规则时,使用children配置项:
routes: [
{
path: '/xxx',
component: xxx,
//子级路由
children: [
{
//path路径不带“/”
path: 'aaa',
component: aaa
},
{
path: 'sss',
component: sss
}
]
}
]
跳转路径时要写完整路径"/parent/child"
五、路由传参
1、query传参
<!-- 跳转路由并携带query参数,to的字符串写法 -->
<router-link :to="`/home/massage/detail?id=${m.id}&title=${m.title}`">
{{m.title}}</router-link>
<!-- to的对象写法 -->
<router-link
:to="{
path: '/home/massage/detail',
query: {
id: m.id,
title: m.title,
},
}"
>{{ m.title }}</router-link>
接收参数 $route.query.id }}、{{ $route.query.title}}
路径过长时,跳转路径书写时可以直接使用path代替,简化路由。或者采用 “命名路由” 的方式,配置路由规则时,给路由添加命名 name:'xxx' ,跳转时<router-link :to="{name:'xxx'}"> </router-link>
2、params传参
配置路由,声明接收params参数
children: [
{
name:'nameroute'
//使用占位符声明接收params参数
path: 'aaa/:id/:title',
component: aaa
},]
传参
<!-- 跳转路由并携带params参数,to的字符串写法 -->
<router-link :to="`/home/massage/detail/idx/titley`">
{{m.title}}</router-link>
<!-- 跳转路由并携带params参数,to的对象写法 -->
<router-link
:to="{
<!--携带params参数时,to对象里必须写命名路由配置,不能使用path配置项-->
name:'nameroute',
params: {
id:idx,
title:titley,
},
}"
></router-link>
接收参数:$route.params.id }}、{{ $route.params.title}}
3、路由的props配置:让路由组件更容易地接受收到参数
path: 'massage',
component: massage,
children: [
{
path: 'detail',
component: detail,
//props第一种写法,值为对象,该对象中所有的key-value都会以props的形式传给detail组件
props: { a: 1, b: 'zyt' }
//值为布尔值,为真就会把该路由收到的all params参数,以props的形式传给detail组件
props:true
//值为函数
props($route) {
return { id: $route.query.id, title: $route.query.title } }
}
六、缓存路由组件&两个新生命周期钩子
1、缓存:让不展示的路由组件保持挂载,不被销毁
<keep-alive include="路由组件名">
<router-view></router-view>
</keep-alive>
2、 两个钩子(捕获路由组件的激活状态
actived:路由组件被激活时触发
deactived:路由组件失活时触发
七、路由守卫(对路由进行权限控制)
1、全局守卫
//全局前置路由守卫————初始化时被调用、每次路由切换前被调用
router.beforeEach((to, from, next) => {
console.log(to, from);
// document.title = to.meta.title || '一个小测试'
// 判断当前路由是否需要权限控制
// if (to.path === '/home/news' || to.path === '/home/massage')
if (to.meta.isauth) {
if (localStorage.getItem('sex') === 'male') {
next()
} else {
alert('性别不对,没有权限查看!')
}
} else {
next()
}
})
//全局后置路由守卫————初始化时被调用、每次路由切换后被调用
router.afterEach((to, from) => {
console.log(to, from);
//修改网页title
document.title = to.meta.title || '一个小测试'
})
2、独享守卫(对其中一个路由进行权限控制)
只有beforeEnter(),可以和afterEach()搭配使用
beforeEnter: (to, from, next) => {
if (to.meta.isauth) {
if (localStorage.getItem('sex') === 'male') {
next()
} else {
alert('性别不对,没有权限查看!')
}
} else {
next()
}
}
3、组件内守卫
//进入守卫,通过路由规则,进入该组件时被调用
beforeRouteEnter (to, from, next) {
// ...
},
//离开守卫,通过路由规则,!!!离开该组件,一定要进入别的路由!!!时被调用
beforeRouteLeave (to, from, next) {
// ...
}
前、后置守卫 / 组件内守卫 区分?
当在一个路由上,切换进入另一个路由之前,应当触发——前置守卫;进入后触发——后置守卫
当在一个路由上,切换进入另一个路由之前,触发——beforeRouteEnter ; 当再进入下一个路由之前调用beforeRouteLeave
八、路由器的两种工作模式
1、对于前端来讲,hash值意为一个url里#机器后面的内容(http://localhost:8080/#/home/...)
2、hash值不会包含在HTTP请求中,不会带给服务器
3、hash模式:地址中带#,不美观;兼容性好;该地址通过第三方手机app分享会被标记为不合法
history模式:地址干净,无#,美观;兼容性相较于hash模式略差;应用部署上线需后端人员支持解决刷新页面服务端404问题。