vue路由登录拦截(vue router登录权限控制)

时间:2023-03-09 04:06:25
vue路由登录拦截(vue router登录权限控制)

实现原理:

哪些路由需要验证需要在路由文件router/index.js中指定:

    {
path: '/',
component: Home,
name: 'Home',
iconCls: 'fa fa-address-card',
leaf: true,//只有一个节点
children: [
{
path: '/chart',
component: Chart,
name: 'Chart',
iconCls: 'el-icon-s-flag',
meta: { // 在路由配置中加入meta:{requireAuth: true}
requireAuth: true
}
}
]
}

vue路由登录拦截(vue router登录权限控制)

用户有没有登录需要给其指定状态,当用户登录了,我们用localStorage在Login.vue文件中为其状态指定为1:

            that.$axios({
method: 'post',
url: 'http://localhost:9999/article/check_login_status/',
data: param
})
.then((res) => {
if(res.data.ret){
localStorage.setItem("islogin", 1); // 指定登录状态
that.$router.push({path: "/table"});
}else{
that.$message('用户名或密码错误!');
return false;
}
})
.catch((e) => {
console.log(err);
});

vue路由登录拦截(vue router登录权限控制)

退出时需要在Home.vue中为其指定状态为0:

localStorage.setItem("islogin", 0);

vue路由登录拦截(vue router登录权限控制)

路由拦截需要用到导航守卫,关键代码如下:

router.beforeEach((to, from, next) => {
let islogin = localStorage.getItem("islogin");
islogin = Boolean(Number(islogin)); if(to.path == "/login"){
if(islogin){
next("/table");
}else{
next();
}
}else{
// requireAuth:可以在路由元信息指定哪些页面需要登录权限
if(to.meta.requireAuth && islogin) {
next();
}else{
next("/login");
}
}
})

vue路由登录拦截(vue router登录权限控制)

全部代码:

router/index.js:

import Vue from 'vue'
import Router from 'vue-router'
const Home = () => import('@/components/HelloWorld')
const Badge = () => import('@/components/Badge')
const Progress = () => import('@/components/Progress')
const Table = () => import('@/components/Table')
const Tag = () => import('@/components/Tag')
const Chart = () => import('@/components/Chart')
const NotFound = () => import('@/components/NotFound')
const Login = () => import('@/components/Login')
const Tabs = () => import('@/components/Tabs')
const Rate = () => import('@/components/Rate')
const Form = () => import('@/components/Form') Vue.use(Router) let router = new Router({
routes: [
{
path: '/',
component: Home,
name: '导航一',
iconCls: 'el-icon-s-flag',
leaf: false,
children: [
{
path: '/tabs',
component: Tabs,
name: 'Tabs',
iconCls: 'el-icon-star-on',
meta: { // 在路由配置中加入meta:{requireAuth: true}
requireAuth: true
}
},
{
path: '/rate',
component: Rate,
name: 'Rate',
iconCls: 'el-icon-star-on',
meta: { // 在路由配置中加入meta:{requireAuth: true}
requireAuth: true
}
}
]
},
{
path: '/',
component: Home,
name: 'Home',
iconCls: 'fa fa-address-card',
leaf: true,//只有一个节点
children: [
{
path: '/badge',
component: Badge,
name: 'Badge',
iconCls: 'el-icon-s-help',
meta: { // 在路由配置中加入meta:{requireAuth: true}
requireAuth: true
}
}
]
},
{
path: '/',
component: Home,
name: 'Home',
iconCls: 'fa fa-address-card',
leaf: true,//只有一个节点
children: [
{
path: '/table',
component: Table,
name: 'Table',
iconCls: 'el-icon-upload',
meta: { // 在路由配置中加入meta:{requireAuth: true}
requireAuth: true
}
}
]
},
{
path: '/',
component: Home,
name: 'Home',
iconCls: 'fa fa-address-card',
leaf: true,//只有一个节点
children: [
{
path: '/tag',
component: Tag,
name: 'Tag',
iconCls: 'el-icon-s-cooperation',
meta: { // 在路由配置中加入meta:{requireAuth: true}
requireAuth: true
}
}
]
},
{
path: '/',
component: Home,
name: 'Home',
iconCls: 'fa fa-address-card',
leaf: true,//只有一个节点
children: [
{
path: '/progress',
component: Progress,
name: 'Progress',
iconCls: 'el-icon-s-order',
meta: { // 在路由配置中加入meta:{requireAuth: true}
requireAuth: true
}
}
]
},
{
path: '/',
component: Home,
name: 'Home',
iconCls: 'fa fa-address-card',
leaf: true,//只有一个节点
children: [
{
path: '/chart',
component: Chart,
name: 'Chart',
iconCls: 'el-icon-s-flag',
meta: { // 在路由配置中加入meta:{requireAuth: true}
requireAuth: true
}
}
]
},
{
path: '/',
component: Home,
name: 'Home',
iconCls: 'fa fa-address-card',
leaf: true,//只有一个节点
children: [
{
path: '/form',
component: Form,
name: 'Form',
iconCls: 'el-icon-s-flag',
meta: { // 在路由配置中加入meta:{requireAuth: true}
requireAuth: true
}
}
]
},
{
path: '/login',
name: 'Login',
component: Login,
hidden: true,
meta: { // 在路由配置中加入meta:{requireAuth: true}
requireAuth: true
}
},
{
path: '*',
hidden: true,
redirect: { path: '/404' }
},
{
path: '/404',
hidden: true,
name: '',
component: NotFound
}
]
}) export default router router.beforeEach((to, from, next) => {
let islogin = localStorage.getItem("islogin");
islogin = Boolean(Number(islogin)); if(to.path == "/login"){
if(islogin){
next("/table");
}else{
next();
}
}else{
// requireAuth:可以在路由元信息指定哪些页面需要登录权限
if(to.meta.requireAuth && islogin) {
next();
}else{
next("/login");
}
}
})

vue路由登录拦截(vue router登录权限控制)

Login.vue:

<template>
<el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm login-container">
<el-form-item label="用户名" prop="username">
<el-input v-model="ruleForm.username" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" v-model="ruleForm.password" autocomplete="off"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
<el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>
</el-form>
</template> <script>
export default {
data() {
return {
ruleForm: {
username: '',
password: ''
},
rules: {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 3, max: 8, message: '长度在 3 到 8 个字符', trigger: 'blur' }
]
}
};
},
methods: {
submitForm(formName) {
let that = this; let param = new URLSearchParams();
param.append('username', that.ruleForm.username);
param.append('password', that.ruleForm.password); this.$refs[formName].validate((valid) => {
if (valid) {
that.$axios({
method: 'post',
url: 'http://localhost:9999/article/check_login_status/',
data: param
})
.then((res) => {
if(res.data.ret){
localStorage.setItem("islogin", 1);
console.log(localStorage.getItem("islogin"));
that.$router.push({path: "/table"});
}else{
that.$message('用户名或密码错误!');
return false;
}
})
.catch((e) => {
console.log(err);
});
} else {
console.log('error submit!!');
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
}
}
}
</script> <style scoped>
.login-container {
/*box-shadow: 0 0px 8px 0 rgba(0, 0, 0, 0.06), 0 1px 0px 0 rgba(0, 0, 0, 0.02);*/
-webkit-border-radius: 5px;
border-radius: 5px;
-moz-border-radius: 5px;
background-clip: padding-box;
margin: 180px auto;
width: 350px;
padding: 35px 35px 15px 35px;
background: #fff;
border: 1px solid #eaeaea;
box-shadow: 0 0 25px #cac6c6;
.title {
margin: 0px auto 40px auto;
text-align: center;
color: #505458;
}
.remember {
margin: 0px 0px 35px 0px;
}
} </style>

vue路由登录拦截(vue router登录权限控制)

Home.vue:

<template>
<div id="app">
<el-container>
<el-header>Header <el-button @click="loginOut">退出</el-button></el-header>
<el-container>
<el-aside width="200px">
<el-row class="tac">
<el-col :span="24">
<el-menu
:default-active="$route.path"
router unique-opened
class="el-menu-vertical-demo"
@open="handleOpen"
@close="handleClose"> <template v-for="(item, index) in $router.options.routes" v-if="!item.hidden">
<!--二级菜单-->
<template v-if="!item.leaf" >
<el-submenu :index="index+''">
<template slot="title">
<i :class="item.iconCls"></i>
<span>{{item.name}}</span>
</template>
<el-menu-item-group>
<el-menu-item :index="child.path" :key="index" v-for="(child, index) in item.children">
{{child.name}}
</el-menu-item>
</el-menu-item-group>
</el-submenu>
</template> <!--一级菜单-->
<template v-else>
<el-menu-item :index="child.path" :key="child.path" v-for="(child, index) in item.children">
<i :class="child.iconCls"></i>
<span slot="title">{{child.name}}</span>
</el-menu-item>
</template>
<!-- <subMenu v-else :data="item" :key="key"></subMenu> -->
</template> </el-menu>
</el-col>
</el-row>
</el-aside> <el-main>
<el-row>
<el-col :span="24">
<div class="grid-content" style="padding: 20px;">
<router-view/>
</div>
</el-col>
</el-row> </el-main>
</el-container>
</el-container>
</div>
</template> <script>
import {mapState, mapGetters, mapActions} from 'vuex' export default {
name: 'App',
methods: {
handleOpen(key, keyPath) {
//console.log(key, keyPath);
},
handleClose(key, keyPath) {
//console.log(key, keyPath);
},
...mapActions('People', ['asyncSetName']),
asyncSetAge(){
this.$store.dispatch("People/asyncSetAge", 1);
},
asyncSetAddress(){
this.$store.dispatch("People/asyncSetAddress", "中国湖南长沙");
},
asyncSetJob(){
this.$store.dispatch("People/asyncSetJob", "P9");
},
loginOut(){
localStorage.setItem("islogin", 0);
this.$router.push("/login");
}
},
computed: {
...mapState('People', ['name', 'age', 'address', 'job']),
...mapState('Product', {
productName: 'name',
count: 'count',
price(state){return state.price},
mount: state => state.mount
}),
}
}
</script> <style>
body{
margin: 0;
}
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
} .el-row {
margin-bottom: 20px;
&:last-child {
margin-bottom: 0;
}
}
.el-col {
border-radius: 4px;
}
.bg-purple-dark {
background: #99a9bf;
}
.bg-purple {
background: #d3dce6;
}
.bg-purple-light {
background: #e5e9f2;
}
.grid-content {
border-radius: 4px;
min-height: 36px;
}
.row-bg {
padding: 10px 0;
background-color: #f9fafc;
} .el-header, .el-footer {
background-color: #235d8b;
color: #ffffff;
text-align: left;
line-height: 60px;
position: absolute;
top: 0;
left: 0;
height: 60px;
width: 100%;
z-index: 100;
} .el-aside {
background-color: #4175a4;
color: #ffffff;
text-align: left;
height: 100%;
z-index: 10;
position: absolute;
left: 0;
top: 0;
padding-top: 80px;
} .el-main {
background-color: #FFFFFF;
color: #333;
text-align: left;
height: 100%;
position: absolute;
left: 0;
top: 0;
padding-top: 80px;
padding-left: 210px;
width: 100%;
} body > .el-container {
margin-bottom: 40px;
} .el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {
line-height: 260px;
} .el-container:nth-child(7) .el-aside {
line-height: 320px;
}
.el-menu-vertical-demo{
background:#4175a4;
}
</style>

vue路由登录拦截(vue router登录权限控制)

django代码:views.py

@csrf_exempt
def check_login_status(request):
return_dict = {"ret": False} if request.method == "POST":
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'admin' and password == '123456':
return_dict['ret'] = True return HttpResponse(json.dumps(return_dict), content_type="application/json")

vue路由登录拦截(vue router登录权限控制)