目录
token
用户登录后,网页需要存储用户信息、检测用户权限等。成功调用登录接口后,在请求头添加token以方便后续操作。
可以在封装axios的request拦截器中添加,具体看axios封装那篇文章https://blog.youkuaiyun.com/takobee5411/article/details/131100558
用vuex存储token等信息
用localStorage+Vuex存储token等信息
引入vuex
vuex后面会开一篇新的文章写,这里就大概描述:
vuex文章链接占位
在main.js中引入,通过npm install vuex@3添加。(vue2引入vuex3,vue3引入vuex4)
import store from './store'; // npm install vuex@3
new Vue({
el: '#app',
store,
})
在src目录下创建store/index.js文件。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = { // 全局管理的数据存储
isLogin: '0',
ser: null,
token: localStorage.getItem('token') ? localStorage.getItem('token') : '', // token
user: {},
};
export default new Vuex.Store({
// 数据
state,
// 方法
getters: { // 监听数据变化
getStorage(state) { // 获取本地存储的登录信息
if (!state.token) {
state.token = JSON.parse(localStorage.getItem(token))
}
if (!state.user) {
state.user = JSON.parse(localStorage.getItem(user))
}
return state.token
}
},
mutations: {
setToken(state, value) { // 设置存储token
state.token = value;
localStorage.setItem('token', value);
},
setUser(state, value) { // 设置存储用户信息
state.user = value;
localStorage.setItem('user', JSON.stringify(value))
},
removeStorage(state, value) { // 删除token
localStorage.removeItem('user');
localStorage.removeItem('token');
},
}
})
存储token等信息
在登录页面添加以下代码:该登录接口返回的是token,此时用setToken方法将token存储进vuex。获取用户信息的接口是通过请求头添加token校验返回用户信息的,拿到之后通过setUser方法存储。
// 登录
gotoIndex() {
let params = {
account: this.account,
password: this.pas,
};
userApi
.login(params)
.then((res) => {
if (res.data.code === 0) {
this.$store.commit("setToken", res.data.data);
this.getUser();
} else {
this.$message.error("登录失败,账号或密码错误", err);
}
})
.catch((err) => {
this.$message.error("登录失败", err);
});
},
// 获取用户信息
getUser() {
userApi
.getUser()
.then((res) => {
if (res.data.code === 0) {
// console.log("r", res.data.data);
this.$store.commit("setUser", res.data.data);
// console.log("res", this.$store.state.user); 用户信息用这个
setTimeout(() => {
this.$router.push({ name: "Index" });
}, 100);
} else {
this.$message.error("用户信息获取失败");
}
})
.catch((err) => {
this.$message.error("用户信息获取失败", err);
});
},
在页面中获取用户信息
在需要用到信息的页面中利用localStorage.getItem("user")或者在vuex里写一个获取用户信息的方法直接调用。
data() {
return {
userMessage: JSON.parse(localStorage.getItem("user")),
};
},
退出登录状态
loginOut() {
this.$store.commit("removeStorage");
this.$router.push({ name: "Login" });
},
路由router
Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用变得轻而易举。功能包括:嵌套路由映射,动态路由选择,模块化、基于组件的路由配置…
引入router
在main.js中引入,通过npm install router@3添加。(vue2引入router3,vue3引入router4)
import router from './router'; // npm install router@3
new Vue({
el: '#app',
router,
store,
})
基本路由配置
在src目录下创建router/index.js文件。
//router/index.js
import Vue from 'vue'
//配置路由相关的信息
import VueRouter from 'vue-router'
//通过Vue.use(插件),安装插件
Vue.use(VueRouter)
import leftRoute from './leftRoute.js'; // 装子路由用的,本来想子路由和路由分开写,index里写顺了就没写这个文件
// 解决重复点击相同路由报错
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
//配置映射关系
const routes = [{
path: '/',
redirect: '/login', // 重定向
},
{
path: '/login',
name: 'Login',
component: () => import('../views/page/Login.vue'),
meta: {
title: '登录'
}
},
{
path: '/back',
name: 'Back',
component: () => import('../views/main/layout.vue'),
redirect: {
name: 'Home'
},
meta: {
title: '后台管理',
loginRequired: true,
},
children: [{
path: '/index',
name: 'Index',
meta: {
title: "首页",
// 下面这些都是看自己添加的,也是自己命名的,比如这里的loginRequired,就是我命名的,用来判断打开该页面前是否需要导航守卫拦截
keepAlive: false,
loginRequired: true,
//authKey:AuthStore.authKeyMap.mlAccountIn.key,
auth: true,
},
component: () => import("../views/main/index.vue"),
},
{
path: '/information',
name: 'Information',
meta: {
title: "基本信息",
keepAlive: false,
loginRequired: true,
auth: true,
},
component: () => import("../views/main/information.vue"),
},
]
},
]
//创建VueRouter对象
const router = new VueRouter({
//es6增强写法
routes,
mode: 'history', // 去掉网页链接中的#号
linkActiveClass: 'active'
})
//导出后在main.js导入并挂载
export default router
router-view与router-link
在App.vue中添加以下代码:
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
name: "App",
};
</script>
<style>
</style>
在侧导航栏中添加以下代码:(大概使用方式,具体写法因情况而定)
<template>
<el-container>
<el-header class="head" style="height: 40px">
<page-title></page-title>
</el-header>
<el-container>
<el-aside width="240px">
<!-- aside部分 -->
<el-row class="tac">
<el-col :span="12">
<el-menu
default-active="1"
class="el-menu-vertical-demo"
@open="handleOpen"
@close="handleClose"
>
<router-link to="index" class="menu">
<el-menu-item index="1">
<i class="el-icon-camera"></i>
<span slot="title">首页</span>
</el-menu-item>
</router-link>
<router-link to="information" class="menu">
<el-menu-item index="2">
<i class="el-icon-edit-outline"></i>
<span slot="title">基本信息</span>
</el-menu-item></router-link
>
</el-menu>
</el-col>
</el-row>
</el-aside>
<el-main>
<!-- main部分 -->
<router-view />
</el-main>
</el-container>
</el-container>
</template>
<script>
import pageTitle from "@/views/pageTitle/pageTitle.vue";
export default {
components: { pageTitle },
methods: {
handleOpen(key, keyPath) {
// console.log(key, keyPath);
},
handleClose(key, keyPath) {
// console.log(key, keyPath);
},
},
};
</script>
<style scoped>
.el-menu >>> {
border: none;
}
.el-col-12 >>> {
width: 100%;
}
.menu {
text-decoration: none;
color: rgb(90, 83, 83);
}
.el-card__body,
.el-main >>> {
padding: 0;
}
</style>
导航守卫
在main.js中配置(或者直接在router文件中配置)
// 路由导航守卫
router.beforeEach((to, from, next) => {
if (to.matched.some(m => m.meta.loginRequired)) { // 需要登录
// if (window.localStorage.token && window.localStorage.isLogin === '1') {
if (window.localStorage.token) {
next()
} else if (to.path !== '/login') {
let token = window.localStorage.token;
if (token === 'null' || token === '' || token === undefined) {
next({
path: '/login'
})
alert("未找到账户信息,请登录")
}
} else {
next()
}
} else { // 不需要登录
next()
}
})