• Vuex 状态管理


    概述

    Vuex 是一个专为 Vue.js 应用程序开发的 状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

    安装

    • 在项目根目录执行如下命令来安装 Vuex
    npm install vuex --save --registry=https://registry.npm.taobao.org
    • 修改 main.js 文件,导入 Vuex,关键代码如下:
    import Vuex from 'vuex'
    Vue.use(Vuex);

    状态管理

    我们利用路由钩子 beforeEach 来判断用户是否登录,期间会用到 sessionStorage 存储功能

    修改 Login.vue

    在表单验证成功方法内增加如下代码:

    // 设置用户登录成功
    sessionStorage.setItem('isLogin', 'true');

    修改 main.js

    利用路由钩子 beforeEach 方法判断用户是否成功登录,关键代码如下:

     1 // 在跳转前执行
     2 router.beforeEach((to, form, next) => {
     3   // 获取用户登录状态
     4   let isLogin = sessionStorage.getItem('isLogin');
     5   // 注销
     6   if (to.path == '/logout') {
     7     // 清空
     8     sessionStorage.clear();
     9     // 跳转到登录
    10     next({path: '/login'});
    11   }
    12   // 如果请求的是登录页
    13   else if (to.path == '/login') {
    14     if (isLogin != null) {
    15       // 跳转到首页
    16       next({path: '/main'});
    17     }
    18   }
    19   // 如果为非登录状态
    20   else if (isLogin == null) {
    21     // 跳转到登录页
    22     next({path: '/login'});
    23   }
    24   // 下一个路由
    25   next();
    26 });

    配置 Vuex

    • 创建 Vuex 配置文件

    在 src 目录下创建一个名为 store 的目录并新建一个名为 index.js 文件用来配置 Vuex,代码如下:

     1 import Vue from 'vue'
     2 import Vuex from 'vuex'
     3 Vue.use(Vuex);
     4 // 全局 state 对象,用于保存所有组件的公共数据
     5 const state = {
     6   // 定义一个 user 对象
     7   // 在组件中是通过 this.$store.state.user 来获取
     8   user: {
     9     username: ''
    10   }
    11 };
    12 // 实时监听 state 值的最新状态,注意这里的 getters 可以理解为计算属性
    13 const getters = {
    14   // 在组件中是通过 this.$store.getters.getUser 来获取
    15   getUser(state) {
    16     return state.user;
    17   }
    18 };
    19 // 定义改变 state 初始值的方法,这里是唯一可以改变 state 的地方,缺点是只能同步执行
    20 const mutations = {
    21   // 在组件中是通过 this.$store.commit('updateUser', user); 方法来调用 mutations
    22   updateUser(state, user) {
    23     state.user = user;
    24   }
    25 };
    26 // 定义触发 mutations 里函数的方法,可以异步执行 mutations 里的函数
    27 const actions = {
    28   // 在组件中是通过 this.$store.dispatch('asyncUpdateUser', user); 来调用 actions
    29   asyncUpdateUser(context, user) {
    30     context.commit('updateUser', user);
    31   }
    32 };
    33 export default new Vuex.Store({
    34   state,
    35   getters,
    36   mutations,
    37   actions
    38 });
    View Code
    • 修改 main.js 增加刚才配置的 store/index.js,关键代码如下:
    1 import Vue from 'vue'
    2 import Vuex from 'vuex'
    3 import store from './store'
    4 Vue.use(Vuex);
    5 new Vue({
    6   el: '#app',
    7   store
    8 });

    浏览器刷新 Vuex 数据消失

    问题描述

    Vuex 的状态存储是响应式的,当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。但是有一个问题就是:vuex 的存储的数据只是在页面的中,相当于我们定义的全局变量,刷新之后,里边的数据就会恢复到初始化状态。但是这个情况有时候并不是我们所希望的。

    解决方案

    监听页面是否刷新,如果页面刷新了,将 state 对象存入到 sessionStorage 中。页面打开之后,判断 sessionStorage 中是否存在 state 对象,如果存在,则说明页面是被刷新过的,将 sessionStorage 中存的数据取出来给 vuex 中的 state 赋值。如果不存在,说明是第一次打开,则取 vuex 中定义的 state 初始值。

    修改代码

    在 App.vue 中增加监听刷新事件

     1 export default {
     2     name: 'App',
     3     mounted() {
     4       window.addEventListener('unload', this.saveState);
     5     },
     6     methods: {
     7       saveState() {
     8         sessionStorage.setItem('state', JSON.stringify(this.$store.state));
     9       }
    10     }
    11   }

    修改 store/index.js 中的 state

    const state = sessionStorage.getItem('state') ? JSON.parse(sessionStorage.getItem('state')) : {
      user: {
        username: ''
      }
    };

    模块化

    由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割

    创建 user 模块

    在 store 目录下创建一个名为 modules 的目录并创建一个名为 user.js 的文件,代码如下:

     1 const user = {
     2   // 因为模块化了,所以解决刷新问题的代码需要改造一下
     3   state: sessionStorage.getItem('userState') ? JSON.parse(sessionStorage.getItem('userState')) : {
     4     user: {
     5       username: ''
     6     }
     7   },
     8   getters: {
     9     getUser(state) {
    10       return state.user;
    11     }
    12   },
    13   mutations: {
    14     updateUser(state, user) {
    15       state.user = user;
    16     }
    17   },
    18   actions: {
    19     asyncUpdateUser(context, user) {
    20       context.commit('updateUser', user);
    21     }
    22   }
    23 };
    24 export default user;
    View Code

    修改 store/index.js

     1 import Vue from 'vue'
     2 import Vuex from 'vuex'
     3 import user from './modules/user'
     4 Vue.use(Vuex);
     5 export default new Vuex.Store({
     6   modules: {
     7     // this.$store.state.user
     8     user
     9   }
    10 });

    备注: 由于组件中使用的是 getters 和 actions 处理,所以调用代码不变

    修改 App.vue

     1   export default {
     2     name: 'App',
     3     mounted() {
     4       window.addEventListener('unload', this.saveState);
     5     },
     6     methods: {
     7       saveState() {
     8         // 模块化后,调用 state 的代码修改为 this.$store.state.user
     9         sessionStorage.setItem('userState', JSON.stringify(this.$store.state.user));
    10       }
    11     }
    12   }
    博客园:https://www.cnblogs.com/xianquan
    Copyright ©2020 l-coil
    【转载文章务必保留出处和署名,谢谢!】
  • 相关阅读:
    2016.5.15——leetcode:Number of 1 Bits ,
    2016.5.14——leetcode-HappyNumber,House Robber
    记录学习过程
    npm 模块安装机制简介
    搭建Vue.js开发环境(window10)
    pwd 显示当前所在的工作路径
    Lucene 6.5.0 入门Demo
    java.lang.UnsupportedClassVersionError
    window.onload 和 $(document).ready(function(){}) 的区别
    plsql + 客户端 连接oracle数据库
  • 原文地址:https://www.cnblogs.com/xianquan/p/12493687.html
  • Copyright © 2020-2023  润新知