跟路由有关的第一个知识点: 路由守卫
这个东西很重要,开发当中用的很多
御前侍卫:保护君王的安全
我们路由守卫和御前侍卫干的活是一样的,只不过:
路由守卫:保护路由的安全(权限)。
有些时候不是所有的导航项不是可以随便点击的
你得符合了一些要求才可以点
提出要求
home和About随便点击,但是News和Message只能是有school是bilibili的才可以访问
要求是点击News或者Message的时候帮我校验一下school是不是bilibili。是就可以访问下面的内容,如果不是就不能访问
解决要求
这事得跟路由器商量商量:
就是以后有人访问的这个路由是/home/news就让路由帮我们做一件事,你去localStorage中的那个school你帮我读取出来看看是不是bilibili,如果是,组件正常呈现;如果不是就别呈现了。所以
router > index.js
//我让每一个路由都有名字
export default new VueRouter({
routes:[
//想在哪里进行二次跳转,就写在个配置里(用children)
{
name: 'zhuye',
path: '/home',
component: Home,
children:[
{
name: 'xinxi',
path: 'news',//注意路由底层给你加了'/'如果自己加'/'有可能还显示不出效果
component:News,
},
{
name: 'xiaoxi',
path: 'message',
component: Message,
children:[
{
name: 'xiangqing',
path: 'detail/:id/:name',
component: Detail,
props($route){
return {id: $route.query.id, name: $route.query.name}
}
}
]
}
]
},
{
name:'guanyu',
path: '/about',
component: About
}
]
})
About和Home都是一级路由,但是你这样写就瞬间把路由器暴露出去了(export default ...)所以你先要接住路由器(const router)
const router = new VueRouter({
routes:[...]
})
//暴露之前跟它商量商量
//加一个路由守卫
//借助自身身上特别的API了,叫做'beforeEach'
//before: ...之前
//Each:每一个;每一次;每一人
//我们要做的就是每一次切换之前,都会帮你调用一个。。函数
//这个有点像setTimeout,我调setTimeout是指定一个定时器的回调函数,那我调beforEach的回调函数的目的是指定路由每次切换时的一次回调函数就是()=>{}这个
//全局前置路由守卫--初始化的时候被调用,每次调用路由切换之前被调用
router.beforeEach(()=>{
console.log('@')//测试
})
export default router
只要你形成路由的跳转(A -> B),那么router.beforEach中的函数就会被调用的,而且这是在切换进行之前调用的
你点击Home组件内容没出来,待会儿再说
但是只要你切换,它就调beforeEach里面的方法
为什么什么都没有,就要研究里面的参数了:
- to(字面意思:你要去哪)
- from(字面意思:你来自于哪)
输出to,from
router.beforeEach((to,from)=>{
console.log('to=',to,'from=',from)//测试
})
一上来的这一次不用关心(因为起点终点是一致的):
to= {name: null, meta: {…}, path: '/', hash: '', query: {…}, …}
from= {name: null, meta: {…}, path: '/', hash: '', query: {…}, …}
我们点击(切换)到home:
to= {name: 'zhuye', meta: {…}, path: '/home', hash: '', query: {…}, …}
from= {name: null, meta: {…}, path: '/', hash: '', query: {…}, …}
把你要去的目标路由信息都给你了
还是去不了,因为就这里的路由守卫的内容 把你所有的都给拦住了
这时next就有用了
- next(放行)
你没有说放行,它不敢往下走
router.beforeEach((to,from,next)=>{
console.log('to=',to,'from=',from)//测试
next()
})
你这么一写就可以了
接下来就只要判断你什么时候放行,什么时候不放行就可以了
动态决定是否放行
第一步:
router.beforeEach((to,from,next)=>{
console.log('to=',to,'from=',from)//测试
if(localStorage.getItem('school')==='bilibili'){
next()
}
})
如果没有school-bilibili是连home和about都不能看,但我的需求是这俩个随意都能看,你得问问人家,你去哪,如果去home和about我不管你,只要你去news和message我就要管你
第二步:
你得判断to里面的path或者name:
router.beforeEach((to,from,next)=>{
console.log('to=',to,'from=',from)//测试
if(to.path === '/home/news' || to.path === '/home/message'){
if(localStorage.getItem('school')==='bilibili'){
next()
}else{
alert('学校名不对,无权限查看')
}
}else{
next()
}
})
路由前如果拦截,你会发现路径是不变的
用名字决定
router.beforeEach((to,from,next)=>{
console.log('to=',to,'from=',from)//测试
if(to.name === 'xinxi' || to.name === 'xiaoxi'){
if(localStorage.getItem('school')==='bilibili'){
next()
}else{
alert('学校名不对,无权限查看')
}
}else{
next()
}
})
配置自定义属性
if(to.name === 'xinxi' || to.name === 'xiaoxi')
是不是觉得这段很鸡肋,如果要写12个100个是不是裂开?
能否在路由的配置项里面加一个配置来判断?
在路由的配置项里面,一个一个配置项都是写好的
我们先看this.$router:
mounted(){
console.log('%%%',this.$route)
}
%%
{name: 'xinxi', meta: {…}, path: '/home/news', hash: '', query: {…}, …}
fullPath: "/home/news"
hash: ""
matched: (2) [{…}, {…}]
meta: {}
name: "xinxi"
params: {}
path: "/home/news"
query: {}
[[Prototype]]: Object
加一点自己独有的配置,怎么放?告诉你: 往meta里面放
我们管这个meta叫路由元信息:
{
name:'guanyu',
path: '/about',
component: About,
meta:{
//这里可以不写,拿不出来就是undefined,undefined说明是假
isAuth: false//isAuth:是否授权
}
}
isAuth谁需要权限的校验,我就放在谁那
这里是News和Message需要,所以:
{
name: 'xinxi',
path: 'news',//注意路由底层给你加了'/'如果自己加'/'有可能还显示不出效果
component:News,
meta:{isAuth:true}
},
{
name: 'xiaoxi',
path: 'message',
component: Message,
children:[
{
name: 'xiangqing',
path: 'detail/:id/:name',
component: Detail,
props($route){
return {id: $route.query.id, name: $route.query.name}
}
}
],
meta:{isAuth:true}
}
那么路由守卫里面就可以这么写:
router.beforeEach((to,from,next)=>{
console.log('to=',to,'from=',from)//测试
if(to.meta.isAuth){//判断是否鉴权
if(localStorage.getItem('school')==='bilibili'){
next()
}else{
alert('学校名不对,无权限查看')
}
}else{
next()
}
})
这就是前置路由守卫,切换前被调用