vuex在项目中使用的一点总结
以下为vue后台管理项目中使用vuex的一点总结,截取了其中部分代码,如有什么错误,还望指出。
1. token 存储
登陆成功之后,需要把获取到的 token 存储到 vuex 中,配合 axios(或其他 ajax 库)的拦截器每次请求前加到 header 中传给后台。不过光放在 vuex 是不行的,因为考虑到浏览器会刷新,当用户手动刷新了浏览器之后,vuex 中的状态就会重置。所以当刷新页面之后,由于 token 丢失,后台接收不到 token 会返回 401 到前台,而前台检测到状态 401 则会跳转到登录页,所以每次刷新就会回到登录每次刷新就会回到登录。
为了解决这个问题,要配合:
- 本地存储 localStorage 或者 sessionStorage
- 对象的 get, set 属性。
/* state.js */
export default {
get UserToken() {
return sessionStorage.getItem("token");
},
set UserToken(value) {
sessionStorage.setItem("token", value);
}
}
/* mutation.js */
export default {
LOGIN_IN(state, token){
state.UserToken = token;
},
LOGIN_OUT(state){
state.UserToken = null;
}
}
/* axios response拦截器 */
instance.interceptors.response.use(function (response) {
return response.data;
}, function (error) {
if (error.response.status == 401){
Message({
type: "warning",
message: "授权失败,请重新登录"
});
store.commit("LOGIN_OUT");
router.replace({path: '/login'})
}else{
return Promise.reject(error);
}
});
可以发现,这样一来,虽然我们从 vuex 中取数据,但实际上我们操作的都是 sessionStorage。由于 sessionStorage 在浏览器关闭之前都是有效的,即使是刷新了,还是能从 sessionStorage 获取到 token,从而防止了刷新回到登陆的问题。
2. 用户权限
登陆之后会从后台获取到当前用户的权限数组,同样的我们也是存储到 vuex 里,不过这个就不需要什么 get set 了,直接存就可以了。
/* state.js */
export default {
permissionList: null
}
/* menuNav.vue */
<template>
<div class="navList">
<ul>
<li v-for="item in permissionList">{{item.name}}</li>
</ul>
</div>
</template>
<script>
export default {
computed: {
permissionList() {
return this.$store.state.permissionList;
}
}
}
</script>
权限有2个问题需要考虑:
刷新后vuex存放的权限数组丢失;
用户手动输入地址进入没有权限的路由,比如没有 /admin 路由的用户在浏览器修改了路由为 /admin;
对于第一个问题,可以在每个路由进入前判断是否存在权限数组,
如果没有:则去获取;
如果有:就进行第二个问题的判断。
为此,我们需要对在路由的配置时,标识路由是否需要权限,如果需要,并且当前用户没有权限,则不让其进入。
由于后台返回的权限数组很可能是存在二级,三级,为了方便用数组进行权限判断,可以配合store.getters,用递归的方式将其转化为一维数组并存到store.getters中,在进入每个路由前通过Array.includes来判断是否存在当前权限。
router.beforeEach((to, from, next) => {
/* 判断路由是否需要登录,如果需要且无token回到登录 */
if (to.matched.some(record => record.meta.requiresAuth)) {
if (!store.state.UserToken) {
next({
path: '/login'
})
} else {
/* 如果没有权限列表先获取 */
if (!store.state.permissionList) {
store.dispatch("fetchPermissionList", next());
} else {
var userAllPermission = store.getters.userAllPermission;
/* 判断是否存在*/
var isExist = userAllPermission.includes((item) => {
return to.name==item.name
});
/* 有当前路由的权限才进入,否则404 */
if (isExist) {
next();
} else {
next({path:'/404'});
}
}
}
} else {
/* 除了登录页,无需权限的都可进入 */
if(to.path!="/login"){
next();
}else{
/* 有token不再进去登录页,回到之前的页面 */
if(store.state.UserToken){
next(from.fullPath);
}
}
}
})
当然,也可以通过this.$router.addRoutes来动态添加路由。
3. 多个页面通用数据
项目中通常会有一些各个页面共用的数据,比如省份城市列表。为了减少请求,城市都是等到点击对应的省份时才去获取的。
类似这种东西,就可以放到vuex中来维护,页面都共享一份数据,这样一来无疑可以减少一些不必要的请求。否则,如果每个页面都存一份单独的数据,假设A页面请求了广东省的城市,B,C页面需要时,由于每个页面的数据是单独的,B,C又分别需要去请求一次。而放到vuex来维护,则只需要请求一次就可以共享了。
/* state.js */
export default {
province:[]
}
/* mutation */
export default {
SET_PROVINCE(state, provincelist){
state.province = provincelist;
}
}
/* action.js */
export default {
/* 获取所有省份 */
fetchProvinceList({
commit,
state,
}) {
axios
.get(`/cityRegions`)
.then(res => {
if (res.status == 0) {
/* 组装element-ui组件需要的格式 */
let province = res.data.map(item => {
return {
value: item.id,
label: item.regionName,
children: []
};
});
commit("SET_PROVINCE", province);
}
})
},
/* 获取省份下的城市 */
fetchCityList({
commit,
state,
}, id) {
/* 找到当前点击的省份 */
var parent = state.province.find(item => {
return item.value == id;
});
/* 如果已经有子级城市就不再请求 */
if (parent.children && parent.children.length <= 0) {
axios
.get(`/cityRegions?pId=${id}`)
.then(res => {
if (res.status == 0) {
var city = res.data;
city = city.map(item => {
return {
value: item.id,
label: item.regionName
};
});
parent.children = city.length > 0 ? city : null;
}
})
}
}
}
vuex在项目中使用的一点总结的更多相关文章
- 关于vuex的项目中数据流动方式
vue的核心是数据驱动,所有数据变更的时机很重要,也就是watch的内容,一般是数据逻辑的操作.在使用vuex的项目中,我们在vuex中只是发请求.拿数据,在视图中来进行逻辑的操作.数据的更新. 1. ...
- vue项目中使用组件化开发
最近在使用vue-cli结合webpack打包工具开发一个后台管理系统,使用vue难免需要运用组件化思想,而这也正是vue的一大特点. 在之前做的vue项目中,稍微有一点组件化的思想,可能是对组件化不 ...
- 对某项目中Vuex用法的分析
上周五刚发布一个线上版本,趁着新的需求和bug还没到来,决定分析一下正在维护的一个使用Vue 2.0 开发的后台管理系统中Vuex部分代码.这部分代码不是我写的,加上我一直在“使用”现成的而不是“搭建 ...
- Vue项目中使用Vuex + axios发送请求
本文是受多篇类似博文的影响写成的,内容也大致相同.无意抄袭,只是为了总结出一份自己的经验. 一直以来,在使用Vue进行开发时,每当涉及到前后端交互都是在每个函数中单独的写代码,这样一来加大了工作量,二 ...
- BUI Webapp用于项目中的一点小心得
接触BUI也有一段时间,也用在了移动端的项目开发中,总的来说,该框架用起来也挺灵活的,控件可以自由定制,前提是自己能认真地学习该框架的api,因为api里面说的东西比较详细,如果没有仔细看的,可能有些 ...
- vue项目中使用vuex
1.运行 cnpm i vuex -S 2.导入包 import Vuex from 'vuex' 3.注册vuex到vue中 Vue.use(vuex) 4. var store = new Vue ...
- 【每天学一点-01】 在SpringBoot项目中使用Swagger2
今天在做毕设的时候,发现在前后端分离的情况下,去调用接口数据时很不方便,然后回想过去,和同学一起做项目的时候,他负责后端,我负责前端,当时调用他的弄好的接口可以说是非常方便,主要是可以通过UI页面直接 ...
- day 87 Vue学习六之axios、vuex、脚手架中组件传值
本节目录 一 axios的使用 二 vuex的使用 三 组件传值 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 axios的使用 Axios 是一个基于 promise 的 HT ...
- vuejs学习——vue+vuex+vue-router项目搭建(三)
前言 vuejs学习——vue+vuex+vue-router项目搭建(一) vuejs学习——vue+vuex+vue-router项目搭建(二) 为什么用vuex:组件之间的作用域独立,而组件之间 ...
随机推荐
- windows下 python3.5+tensorflow 安装
个人随笔,备忘参考 首先最近的tensorflow 对python3.5.x友好,我先装了Python3.6,查其他的一些博客说出现问题,后来重装3.5.0.下载用迅雷,超快. 安装比较简单,官网下载 ...
- WP-player——WordPress的一款好用的音乐插件
作者的主页:http://webjyh.com/wp-player/ 安装:在WordPress后台搜索安装即可,或者去作者的主页下载安装. 使用方法:这个插件是通过短代码调用的,安装好插件之后便可以 ...
- OSI七层模型对应的协议
osi七层模型对应的协议 author:headsen chen 2017-10-21 11:44:47 个人原创,转载请注明作者,出处.否则依法追究法律责任 1,物理层:带信号的,同轴电缆, ...
- centos上的grub文件修改
centos上的grub文件修改 author:headsen chen 2017-10-10 17:36:42 个人原创,转载请注明作者和出处,否则追究法律责任 1,centos6上的修改:vim ...
- FTP站点设置
0x00前言: 应老师今天教的和题目所需 有了今天的博文 0x01准备: windows server 2008 FTP服务 0x02正文: 1.先安装FTP服务 先打开--服务器管理 点击--添加角 ...
- QC的使用简介
目录一.站点管理员的操作(后台)1.登录2.创建域3.创建项目4.新建用户5.QC的一些其他信息的修改(非 常用)二.项目管理员对项目的配置管理(前台)1.登录2.修改用户个人信息及密码3.项目成员设 ...
- 理解C语言中几个常见修饰符
写在前面 今天下午一个同事问「register」关键字是什么作用?噢,你说的是「register」啊,它的作用是……脑袋突然断片儿,我擦,啥意思来着,这么熟悉的陌生感.做C语言开发时间也不短了,不过好 ...
- 【Python】 关于import和package结构
关于import语句 python程序需要使用某个第三方模块的话要用import语句,其实就是把目标模块的内容加载到内存里.当然,在加载之前,python会按照一定的顺序寻找sys.path中的目录. ...
- linux小白成长之路8————访问Docker中的mysql
[内容指引] 本篇实战演示如何操作Docker中的mysql数据库,包含以下五个知识点: 登录容器: 登录mysql: 运行SQL指令创建数据库: 退出mysql: 退出容器: 1.登录容器 我们在上 ...
- C语言中的atan和atan2
本文内容为转载,是在阅读 RTKLIB源码时意识到的这个问题,原文地址为:https://www.cnblogs.com/dutlei/archive/2013/01/14/2860332.html ...