路由守卫,又叫导航守卫。
有全局的,单个路由独享的,或者组件级的。
下面是我写的全局前置守卫。
重点:参数或查询的改变并不会触发进入/离开的导航守卫
全局守卫主要分为一下几个步骤:
1.配置登录页面
例如:login.vue 是我们的登录页面
在 /src/router/index.js 配置我们的路由守卫页面
注意:路由守卫页面为一级路由
{
path: '/login',
name: 'Login',
component: () =>
import ('../views/Login')
}
2.配置路由守卫标识 配置路由元信息 meta
例如:home.vue 是要守卫的页面
{
path: '/home',
name: 'Home',
meta: { islogin: true }, // 配置路由守卫标识 代表当前路由需要守卫 需要登陆权限
component: () =>
import ('../views/Home')
},
3.当进入路由页面时判断当前路由是否需要守卫
配置全局前置守卫函数: router.beforeEach()
router.beforeEach((to, from, next) => {
// ...
})
参数:
to:即将要进入的目标 路由对象
from:当前导航正要离开的的路由
next:函数,决定是否展示你要看到的路由页面
4.判断当前用户的登陆状态
islogin:true 登陆直接查看
islogin:false 未登录 拦截到的登陆页面 login.vue 本地存储localStorage
router.beforeEach((to, from, next) => {
// 判断即将进入的路由对象是否需要守卫
if (to.meta.islogin) { // 需要守卫
// 判断当前用户的登陆状态 登陆 直接查看next() 未登录 拦截到登陆页
if (localStorage.getItem('token')) { // 登陆凭证token
next();
} else { // 未登录
next({
path: '/login',
query: {
topath: to.fullPath
}
});
}
} else {
next(); // 接着执行
}
})
5.实现登陆功能 进行表单处理
先写后端
const bodyParser = require('body-parser');
module.exports = {
devServer:{
before(app){
// 使用中间件解析post传参
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:false}));
app.post('/loginbtn',(req,res)=>{
// 获取用户名和密码
let obj = req.body;
console.log(obj);
// 根据前端的用户信息判断是否可以登陆 admin 123
if(obj.name == 'admin' && obj.pwd == '123'){ // 用户信息正确
res.send({
code: 1,
token: '666',
text:'login success'
})
}else{ // 用户信息不正确
res.send({
code: 0,
text:'login fail'
})
}
})
}
}
}
再写前端
<template>
<div>
<h2>登陆页面</h2>
<div class="box">
用户名:<input type="text" placeholder="请输入用户名" v-model="user">
</div>
<div class="box">
密码:<input type="text" placeholder="请输入密码" v-model="pwd">
</div>
<!-- 登陆按钮绑定点击事件->获取用户名和密码->是否可以登陆 -->
<button @click='gologin'>登陆</button>
</div>
</template>
<script>
// 引入axios
import axios from 'axios'
export default {
data(){
return {
user:'',// 用户名
pwd:'', // 密码
}
},
methods:{
// 点击登陆
gologin(){
// 获取用户信息
console.log(this.user);
let obj = {
name:this.user,
pwd:this.pwd
}
// 判断当前用户是否可以登陆
axios.post('/loginbtn',obj).then(res=>{
console.log(res.data);
})
}
}
}
</script>
6.跳转路由拦截之前的页面 this.$router.push(路由路径)
axios.post('/loginbtn',obj).then(res=>{
console.log(res.data);
if(res.data.code == 1){ // 成功
// 存登陆凭证 跳转路由拦截之前的页面
localStorage.setItem('token',res.data.token);
this.$router.push(this.$route.query.topath);
}else{
alert('请检查你的用户名和密码');
}
})
另外:
全局后置守卫:
router.afterEach((to,from)=>{}) 只有两个参数
to:进入到哪个路由去
from:从哪个路由离开。
组件内守卫:
到达这个组件时:beforeRouteEnter:(to,from,next)=>{}
beforeRouteEnter:(to,from,next)=>{
next(vm=>{
// 通过 `vm` 访问组件实例
alert("hello" + vm.name);
})
}
离开这个组件时,beforeRouteLeave:(to,from,next)=>{}
beforeRouteLeave:(to,from,next)=>{
if(confirm("确定离开此页面吗?") == true){
next();
}else{
next(false);
}
}