全局钩子(全局路由守卫)
vue中路由守卫(路由钩子,或者 叫做 路由导航守卫)一共有三种,一个全局路由守卫,一个是组件内路由守卫,一个是router独享守卫。
路由钩子,即导航钩子,其实就是路由拦截器,vue-router一共有三类:
-
全局钩子:最常用
-
路由单独钩子
-
组件内钩子
6.4.3.1 全局钩子(全局路由守卫)
所谓全局路由守卫,就是小区大门,整个小区就这一个大门,你想要进入其中任何一个房子,都需要经过这个大门的检查。 全局路由守卫有个两个:一个是全局前置守卫beforeEach(), 一个是全局后置守卫afterEach() 。
在src/router/index.js中使用,代码如下:
// 给路由实例对象添加全局守卫
// 全局前置守卫
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');
}
}
})
export default router
每个钩子方法接收三个参数: to: Route : 即将要进入的目标 [路由对象] from: Route : 当前导航正要离开的路由 next: Function : 继续执行函数
-
next():继续执行
-
next(false):中断当前的导航。
-
next(‘/‘) 或 next({ path: ‘/‘ }):跳转新页面,常用于登陆失效跳转登陆
例如:
创建 user.vue 用户中心组件,login.vue登录组件。我们 希望 通过通过 登录且 成功登录,去访问用户中心,否则,做路由拦截。
user.vue
<template>
<div>
<h1>用户中心</h1>
</div>
</template>
login.vue
<template>
<div class="login">
<h1>系统登录</h1>
<div class="login-box">
<div>
<!-- v-model.trim后面加上.trim是为了去除表单修饰符 -->
用户名:<input type="text" v-model.trim="username">
</div>
<div>
密 码:<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;
}
.login-box button{
width: 80px;
height: 30px;
}
</style>
在路由配置文件中router/index.js 去配置 全局路由守卫(路由拦截):
// 给路由实例对象添加全局守卫
// 全局前置守卫
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');
}
}
// console.group('from---');
// console.log(from);
// console.group('to---');
// console.log(to);
})
路由单独钩子(router独享守卫)
使用:在路由配置中单独加入钩子,在src/router/index.js中使用,代码如下:
创建one.vue组件:
<template>
<div>
<h1>我是首页组件中的子组件--one.vue</h1>
</div>
</template>
在src/router/index.js中, 在one组件中单独加 钩子:
const routes = [
// 定向
{
path:'/home',
redirect:'/'
},
{
path: '/',
name: 'home',
component: HomeView,
// 嵌套路由(子路由)
children:[
{
path:'/home/one',
component:one,
// 路由单独钩子(router独享守卫)
beforeEnter:(to,from,next)=>{
console.log('进入前执行');
next();
}
}
]
},
在HomeView.vue组件中,访问子组件:
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png">
<router-link to="/home/one">访问one组件</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'HomeView',
components: {
}
}
</script>
预览: