以下为vue后台管理项目中使用vuex的一点总结,截取了其中部分代码,如有什么错误,还望指出。

1. token 存储

  1. 登陆成功之后,需要把获取到的 token 存储到 vuex 中,配合 axios(或其他 ajax 库)的拦截器每次请求前加到 header 中传给后台。不过光放在 vuex 是不行的,因为考虑到浏览器会刷新,当用户手动刷新了浏览器之后,vuex 中的状态就会重置。所以当刷新页面之后,由于 token 丢失,后台接收不到 token 会返回 401 到前台,而前台检测到状态 401 则会跳转到登录页,所以每次刷新就会回到登录每次刷新就会回到登录。

为了解决这个问题,要配合:

  • 本地存储 localStorage 或者 sessionStorage
  • 对象的 get, set 属性。
  1. /* state.js */
  2. export default {
  3. get UserToken() {
  4. return sessionStorage.getItem("token");
  5. },
  6. set UserToken(value) {
  7. sessionStorage.setItem("token", value);
  8. }
  9. }
  10. /* mutation.js */
  11. export default {
  12. LOGIN_IN(state, token){
  13. state.UserToken = token;
  14. },
  15. LOGIN_OUT(state){
  16. state.UserToken = null;
  17. }
  18. }
  19. /* axios response拦截器 */
  20. instance.interceptors.response.use(function (response) {
  21. return response.data;
  22. }, function (error) {
  23. if (error.response.status == 401){
  24. Message({
  25. type: "warning",
  26. message: "授权失败,请重新登录"
  27. });
  28. store.commit("LOGIN_OUT");
  29. router.replace({path: '/login'})
  30. }else{
  31. return Promise.reject(error);
  32. }
  33. });
  1. 可以发现,这样一来,虽然我们从 vuex 中取数据,但实际上我们操作的都是 sessionStorage。由于 sessionStorage 在浏览器关闭之前都是有效的,即使是刷新了,还是能从 sessionStorage 获取到 token,从而防止了刷新回到登陆的问题。

2. 用户权限

  1. 登陆之后会从后台获取到当前用户的权限数组,同样的我们也是存储到 vuex 里,不过这个就不需要什么 get set 了,直接存就可以了。
  1. /* state.js */
  2. export default {
  3. permissionList: null
  4. }
  5. /* menuNav.vue */
  6. <template>
  7. <div class="navList">
  8. <ul>
  9. <li v-for="item in permissionList">{{item.name}}</li>
  10. </ul>
  11. </div>
  12. </template>
  13. <script>
  14. export default {
  15. computed: {
  16. permissionList() {
  17. return this.$store.state.permissionList;
  18. }
  19. }
  20. }
  21. </script>

权限有2个问题需要考虑:

  • 刷新后vuex存放的权限数组丢失;

  • 用户手动输入地址进入没有权限的路由,比如没有 /admin 路由的用户在浏览器修改了路由为 /admin

    对于第一个问题,可以在每个路由进入前判断是否存在权限数组,

    如果没有:则去获取;

    如果有:就进行第二个问题的判断。

    为此,我们需要对在路由的配置时,标识路由是否需要权限,如果需要,并且当前用户没有权限,则不让其进入。

    由于后台返回的权限数组很可能是存在二级,三级,为了方便用数组进行权限判断,可以配合store.getters,用递归的方式将其转化为一维数组并存到store.getters中,在进入每个路由前通过Array.includes来判断是否存在当前权限。

  1. router.beforeEach((to, from, next) => {
  2. /* 判断路由是否需要登录,如果需要且无token回到登录 */
  3. if (to.matched.some(record => record.meta.requiresAuth)) {
  4. if (!store.state.UserToken) {
  5. next({
  6. path: '/login'
  7. })
  8. } else {
  9. /* 如果没有权限列表先获取 */
  10. if (!store.state.permissionList) {
  11. store.dispatch("fetchPermissionList", next());
  12. } else {
  13. var userAllPermission = store.getters.userAllPermission;
  14. /* 判断是否存在*/
  15. var isExist = userAllPermission.includes((item) => {
  16. return to.name==item.name
  17. });
  18. /* 有当前路由的权限才进入,否则404 */
  19. if (isExist) {
  20. next();
  21. } else {
  22. next({path:'/404'});
  23. }
  24. }
  25. }
  26. } else {
  27. /* 除了登录页,无需权限的都可进入 */
  28. if(to.path!="/login"){
  29. next();
  30. }else{
  31. /* 有token不再进去登录页,回到之前的页面 */
  32. if(store.state.UserToken){
  33. next(from.fullPath);
  34. }
  35. }
  36. }
  37. })

当然,也可以通过this.$router.addRoutes来动态添加路由。

3. 多个页面通用数据

  1. 项目中通常会有一些各个页面共用的数据,比如省份城市列表。为了减少请求,城市都是等到点击对应的省份时才去获取的。
  2. 类似这种东西,就可以放到vuex中来维护,页面都共享一份数据,这样一来无疑可以减少一些不必要的请求。否则,如果每个页面都存一份单独的数据,假设A页面请求了广东省的城市,B,C页面需要时,由于每个页面的数据是单独的,BC又分别需要去请求一次。而放到vuex来维护,则只需要请求一次就可以共享了。
  1. /* state.js */
  2. export default {
  3. province:[]
  4. }
  5. /* mutation */
  6. export default {
  7. SET_PROVINCE(state, provincelist){
  8. state.province = provincelist;
  9. }
  10. }
  11. /* action.js */
  12. export default {
  13. /* 获取所有省份 */
  14. fetchProvinceList({
  15. commit,
  16. state,
  17. }) {
  18. axios
  19. .get(`/cityRegions`)
  20. .then(res => {
  21. if (res.status == 0) {
  22. /* 组装element-ui组件需要的格式 */
  23. let province = res.data.map(item => {
  24. return {
  25. value: item.id,
  26. label: item.regionName,
  27. children: []
  28. };
  29. });
  30. commit("SET_PROVINCE", province);
  31. }
  32. })
  33. },
  34. /* 获取省份下的城市 */
  35. fetchCityList({
  36. commit,
  37. state,
  38. }, id) {
  39. /* 找到当前点击的省份 */
  40. var parent = state.province.find(item => {
  41. return item.value == id;
  42. });
  43. /* 如果已经有子级城市就不再请求 */
  44. if (parent.children && parent.children.length <= 0) {
  45. axios
  46. .get(`/cityRegions?pId=${id}`)
  47. .then(res => {
  48. if (res.status == 0) {
  49. var city = res.data;
  50. city = city.map(item => {
  51. return {
  52. value: item.id,
  53. label: item.regionName
  54. };
  55. });
  56. parent.children = city.length > 0 ? city : null;
  57. }
  58. })
  59. }
  60. }
  61. }

vuex在项目中使用的一点总结的更多相关文章

  1. 关于vuex的项目中数据流动方式

    vue的核心是数据驱动,所有数据变更的时机很重要,也就是watch的内容,一般是数据逻辑的操作.在使用vuex的项目中,我们在vuex中只是发请求.拿数据,在视图中来进行逻辑的操作.数据的更新. 1. ...

  2. vue项目中使用组件化开发

    最近在使用vue-cli结合webpack打包工具开发一个后台管理系统,使用vue难免需要运用组件化思想,而这也正是vue的一大特点. 在之前做的vue项目中,稍微有一点组件化的思想,可能是对组件化不 ...

  3. 对某项目中Vuex用法的分析

    上周五刚发布一个线上版本,趁着新的需求和bug还没到来,决定分析一下正在维护的一个使用Vue 2.0 开发的后台管理系统中Vuex部分代码.这部分代码不是我写的,加上我一直在“使用”现成的而不是“搭建 ...

  4. Vue项目中使用Vuex + axios发送请求

    本文是受多篇类似博文的影响写成的,内容也大致相同.无意抄袭,只是为了总结出一份自己的经验. 一直以来,在使用Vue进行开发时,每当涉及到前后端交互都是在每个函数中单独的写代码,这样一来加大了工作量,二 ...

  5. BUI Webapp用于项目中的一点小心得

    接触BUI也有一段时间,也用在了移动端的项目开发中,总的来说,该框架用起来也挺灵活的,控件可以自由定制,前提是自己能认真地学习该框架的api,因为api里面说的东西比较详细,如果没有仔细看的,可能有些 ...

  6. vue项目中使用vuex

    1.运行 cnpm i vuex -S 2.导入包 import Vuex from 'vuex' 3.注册vuex到vue中 Vue.use(vuex) 4. var store = new Vue ...

  7. 【每天学一点-01】 在SpringBoot项目中使用Swagger2

    今天在做毕设的时候,发现在前后端分离的情况下,去调用接口数据时很不方便,然后回想过去,和同学一起做项目的时候,他负责后端,我负责前端,当时调用他的弄好的接口可以说是非常方便,主要是可以通过UI页面直接 ...

  8. day 87 Vue学习六之axios、vuex、脚手架中组件传值

      本节目录 一 axios的使用 二 vuex的使用 三 组件传值 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 axios的使用 Axios 是一个基于 promise 的 HT ...

  9. vuejs学习——vue+vuex+vue-router项目搭建(三)

    前言 vuejs学习——vue+vuex+vue-router项目搭建(一) vuejs学习——vue+vuex+vue-router项目搭建(二) 为什么用vuex:组件之间的作用域独立,而组件之间 ...

随机推荐

  1. 依赖反转原则DIP 与 asp.net core 项目结构

    DIP 依赖反转原则 Dependency Inversion Principle 的定义如下: 高级别的模块不应该依赖于低级别的模块, 他们都应该依赖于抽象. 假设Controller依赖于Repo ...

  2. ATM+购物商城完整版

    一,需求:模拟实现一个ATM + 购物商城程序 要求如下: 1.额度15000或者自定义 2.实现购物商城,买东西加入购物车,调用信用卡接口结账 3.可以提现,手续费5% 4.支持多账户登陆 5.支持 ...

  3. UML类图二

    在软件系统中,类并不是孤立存在的,类与类之间存在各种关系,对于不同类型的关系,UML提供了不同的表示方式.       1. 关联关系 关联(Association)关系是类与类之间最常用的一种关系, ...

  4. XeLaTeX中文模板

    XeLaTeX对中文的支持很友好,可以直接调用系统已安装字体进行文档的撰写.其中需要引用字体的名字,开始遇到了写问题,经常发现字体未引用,现在大概明白了. 引用字体的时候,如果不加中括号,就需要引用字 ...

  5. 边框0.5px的实现方法

    原理: css3 的缩放   ---->    transform: scale() 完整代码如下: <!DOCTYPE html> <html lang="en&q ...

  6. linux修改时区

    Linux修改时区 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任 CentOS6: 查看以前的时区: [root@localhost mysq ...

  7. LNMP+FARM+DNS

    LNMP 1.安装Nginx前的环境. # yum -y install gcc gcc-c++ pcre-devel zlib-devel openssl-devel   2.添加www系统用户,在 ...

  8. 06_java 时间获取练习_Date\SimpleDateFormat\Calendar类练习

     1.获取当前的日期,并把这个日期转换为指定格式的字符串,如2088-08-08 08:08:08 import java.text.SimpleDateFormat; import java.uti ...

  9. from提交表单后 数据提交到后台 但不跳转页面 可用iframe

    可以页面事先加载被隐藏的iframe标签,或者等到需要的时候通过js生成,再提交,提交之前,form的target指向iframe(我是要实现新页面生成的时候程半透明状态,所以用了后者的方法) 代码如 ...

  10. linux服务器中毒可疑进程sfewfesfs CPU80%

    我用的是wdlinux, 难免会有漏洞,不知怎么就被莫名其妙地给入侵了,而且还频繁发包.下面是我查看攻击机器的整个过程. 首先跟客户要了root密码登录看,第一个命令是就top cd /proc/25 ...