路由守卫
vue中路由守卫(路由钩子,或者 叫做 路由导航守卫)一共有三种,一个全局路由守卫,一个是组件内路由守卫,一个是router独享守卫。
路由钩子,即导航钩子,其实就是路由拦截器,vue-router一共有三类:
-
全局钩子:最常用
-
路由单独钩子
-
组件内钩子
全局钩子(全局路由守卫)
所谓全局路由守卫,就是小区大门,整个小区就这一个大门,你想要进入其中任何一个房子,都需要经过这个大门的检查。
全局路由守卫有个两个:一个是全局前置守卫beforeEach(), 一个是全局后置守卫afterEach() 。
在src/router/index.js中使用,代码如下:
// 路由实例对象
const router = new VueRouter({
// mode: 'hash', // 在访问的时候,会在访问的地址栏里 出现#符号
mode: 'history', // history 在访问的 时候 就不会出现
base: process.env.BASE_URL,
routes
})
// 给路由实例对象 添加一个 全局守卫
// 全局前置守卫
// to, from, next 参数的顺序不能变
// router.beforeEach((to, from, next)=>{
// // console.group('from---')
// // console.log(from);
// // console.group('to---')
// // console.log(to);
// // 读取信息
// let token = localStorage.getItem('token')
// console.log(token);
// if(token){ // 如果有token 我们就允许 你去访问 对应的组件
// next() //放行 ---页面执行放行
// }else{ // 如果没有token, 你 就跳到 登录页
// if(to.path === '/login'){
// next()
// }else{
// next('/login')
// }
// }
// })
每个钩子方法接收三个参数:to: Route : 即将要进入的目标 [路由对象]from: Route : 当前导航正要离开的路由next: Function : 继续执行函数
-
next():继续执行
-
next(false):中断当前的导航。
-
next(‘/‘) 或 next({ path: ‘/‘ }):跳转新页面,常用于登陆失效跳转登陆
例如:
创建 user.vue 用户中心组件,login.vue登录组件。我们 希望 通过通过 登录且 成功登录,去访问用户中心,否则,做路由拦截。
user.vue
<div>
<h1>用户中心</h1>
</div>
login.vue
<template>
<div class="login">
<h1>系统登录</h1>
<div class="login-box">
<div>
<!-- .trim 去除 文本框 两端的空格 -->
用户名: <input type="text" v-model.trim="username">
</div>
<div>
<!-- 要在type里写入password 这这样在输入密码时,才会是隐秘的密码,看不见 -->
密 码: <input type="password" v-model.trim="password">
</div>
<div>
<button @click="login">登录</button>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'login',
data() {
return {
username:'',
password:''
};
},
mounted() {
},
methods: {
login(){
let result = this.username && this.password;
if(!result){
alert('用户名和密码不能为空')
return false
}
// 如果用户名不是 admin 并且密码不是123456
// 注意: 用户名 或密码 当其中一个输入错误的话 都会有下面这个提示
if(this.username !== 'admin' || this.password !== '123456'){
alert('用户名或密码错误')
return false
}
// 在登录的时候,同时向 本地储存 存一个值 存到token
localStorage.setItem('token',Date.now())
// localStorage.token = Date.now() // 这两种写法 是等价的(同上)
// 登录成功
// $router
this.$router.push({path:'/user'})
}
},
};
</script>
<style lang="scss" scoped>
.login{
display: flex;
flex-direction: column;
align-items: center;
}
.login-box div{
margin: 10px 0;
}
.login-box input{
outline: none;
height: 26px;
padding-left: 6px;
}
.login-box button{
width: 80px;
height: 30px;
}
</style>
在路由配置文件中router/index.js 去配置 全局路由守卫(路由拦截):
// 给路由 实例对象 添加 全局守卫
// 全局前置守卫
// to,from,next 参数的顺序不能变
router.beforeEach((to, from ,next)=>{
// 读取数据
let token = localStorage.getItem('token');
console.log(token);
if(token){//如果有token,我们就 允许 你去访问 对应 的组件
next();//放行--页面执行放行
}else{//如果没有token,你 就跳到 登录页
if(to.path === '/login'){
next();
}else{
next('/login');
}
}
})
预览效果: