【前端】Vuex模块化和持久化应用示例
创始人
2024-05-08 11:29:30
0

1. 概述

Vuex作为VUE状态管理组件,能够将项目中公共数据状态进行统一管理,并且可以按照不同的业务功能将数据状态分模块管理,即数据状态模块化。

另外,对于网页刷新导致Vuex状态丢失的问题可以使用vuex-persistedstate插件配置将数据保存在localStorage或者sessionStorage中,即数据状态持久化。

同时使用secure-ls插件将明文数据加密,以防数据泄露风险。

本文测试环境如下:

Node版本:v10.14.2
Npm版本:6.4.1
package.json依赖的插件版本如下:
“vue”: “^2.2.37”,
“vue-router”: “^3.0.1”,
“vuex”: “^3.0”,
“vuex-persistedstate”: “^4.1.0”
“secure-ls”: “^1.2.6”,

2. Vuex的模块化

Vuex的模块化将按照顺序分为3个部分:Vuex组件实例化与引用、子模块的创建、模块化的使用方法。

2.1 Vuex组件实例化与引用

首先创建Vuex状态实例文件src/store/index.js,用于创建状态实例,并将根状态的四个参数(state, getters, mutations, actions),以及各个模块实例添加到modules对象参数中。详见以下代码。

// src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import user from "./modules/user";
import room from "./modules/room"// 使用Vuex组件
Vue.use(Vuex)
const state = () => ({})
const getters = {}
const mutations = {}
const actions = {}// 实例化状态对象
export default new Vuex.Store({// 根模块的四类对象state,  getters,  mutations,  actions,modules: {  // 将各个模块放入modules属性中user, room}
})

至于以上代码中引入的user,room子模块,下文将进行介绍。

接下来要将Vuex组件实例添加到Vue实例中,具体操作见如下代码。

// src/main.js
import Vue from 'vue'
import store from "./store";
/* eslint-disable no-new */
new Vue({el: '#app',router,store,components: { App },template: ''
})

2.2 子模块的创建

上文.src/store/index.js文件中,有user和room2个模块,模块之间大同小异,下面主要以user子模块进行讲解。本节主要介绍子模块的创建,具体使用方法将在2.3节有详细介绍。

// src/store/modules/user.js
// user子模块
const state = () => ({})		// 详见2.2.1小节
const getters = {}				// 详见2.2.2小节
const actions = {}				// 详见2.2.3小节
const mutations = {}			// 详见2.2.4小节
export default {namespaced: true,state,getters,mutations,actions
}

2.2.1 state,数据状态对象

state作为数据状态的存储,是一个匿名函数返回的对象。

如下代码所示,该对象中两个数据状态curTheme和curUser,其中curTheme是字符串类型,curUser是对象类型。

// src/store/modules/user.js
// state: 用户相关状态
const state = () => ({curTheme: 'light',curUser: {id: '123456',name: '张三'}
})

2.2.2 getters,计算属性对象

getters作为计算属性,类似vue组件中的computed属性。

如下代码所示,该对象中是一个个的方法函数,该函数按照顺序有(state, getters, rootState, rootGetters)四个参数。

// src/store/modules/user.js
const getters = {// 获取当前用户ID   curUserId: (state, getters, rootState, rootGetters) => {return state.curUser ? state.curUser.id : undefined},// 比对userId是否是当前用户idisCurUserId: (state, getters, rootState, rootGetters) => {return (userId) => {return userId == getters.curUserId;}},// 根据userId获取当前主题getCurThemeByUserId: (state, getters, rootState, rootGetters) => {return (userId) => {if(getters.isCurUserId(userId)) return state.curTheme;else return '';}}
}

其中,前两个参数stategetters是本模块中的数据状态对象(即2.2.1节中介绍的state对象)和计算属性对象(即本节介绍的getters对象),这两个参数是局部参数,只能访问本模块中的数据状态和计算属性对象。

后两个参数rootStaterootGetters可以用来访问根模块和其他子模块的数据状态和计算属性对象。

2.2.3 actions,异步请求对象

actions内部是也是一个个函数,主要用于执行异步请求逻辑。而且,如果需要更改数据状态,则必须通过commit调用相应的mutation对象。

另外,该函数有两个参数(context, payload),其中context是一个对象,即{state, rootState, commit, dispatch, getters, rootGetters}等6个参数(具体解释见如下代码中注释),palyload为调用时的自定义输入参数。

需要注意的是,actions中的(context, payload)参数中context是对象,所以里面的参数可以是无序的。但是getters中的(state, getters, rootState, rootGetters) 是四个参数,并且是有序的,千万注意顺序!!!

// src/store/modules/user.js
// actions,异步操作,通过mutation进行更新数据
const actions = {//context:{//         state,   		本模块数据状态对象,例如state.curTheme//         rootState,   	根模块数据状态对象,例如rootState.user.curTheme//         commit,   		用于调用mutation函数,例如commit('SET_CUR_USER', null)//         dispatch,   	用于调用action函数,例如dispatch('logout')//         getters   		本模块计算属性对象,例如getters.curUserId//		 rootGetters 	根模块计算属性对象,例如rootGetters['user/curUserId']// }// 用户登录async login ({state, rootState, commit, dispatch, getters, rootGetters}, {name, passwd})  {// 用户登录逻辑let res = await $api.login();if(!res.success) Message.error('登录失败');   },// 登出async logout({commit}) {let res = await $api.logout()},

2.2.4 mutations,数据同步对象

mutations数据同步对象,内部是一个个同步函数,该函数没有返回值,内部逻辑主要是为了修改state属性。

注意千万不要在actions或者其他地方直接设置state数据状态。若要修改state状态,必须使用commit调用mutations函数,因为只有在mutations函数中修改才能触发Vuex数据和视图同步更新。

// src/store/modules/user.js
// mutations,定义更新数据方法,同步操作
const mutations = {SET_CUR_THEME (state, curTheme) {state.curTheme = curTheme},SET_CUR_USER (state, curUser) {// curUser是对象类型,需要使用Vue.set方法赋值,数组类型也一样需要Vue.set(state, 'curUser', curUser)},
}

2.3 模块化的使用方法

Vuex模块化后不仅可以在自定义组件中使用,而且可以引入store实例使用。

2.3.1 在自定义组件中使用

// RoomGaming.vue


2.3.2 引入store实例使用

不仅在自定义组件中使用,而且可以引入store实例在任何js文件中使用。使用方法如同自定义组件中的this.$store

// ReceiveService.js
import $store from '../store'
const testFunction = (data) => {// mutations$store.commit("gamexstx/SET_CLOCKWISE", data.clockwise);$store.commit("gamexstx/SET_BOTTOM", data.bottom);$store.commit("gamexstx/SET_DEGREE", data.degree);$store.commit("gamexstx/SET_PLAYER_STATE", data.playerState);// getterslet index = $store.getters['gamexstx/curDrawIndex']let code = $store.getters['gamexstx/getCardInGroup1ByIndex'](index);// actionsawait $store.dispatch('cardxstx/playDrawCardAnim', {code, target});// stateif($store.state.gamexstx.degree > 0) return;
}

3. Vuex持久化配置

src/store/index.js中添加plugins属性,并设置keystorage属性,key是键名,storage是存储位置,可以是window.localStorage也可以是window.sessionStorage

// src/store/index.js
import createPersistedState from 'vuex-persistedstate'export default new Vuex.Store({state,getters,mutations,actions,modules: {user, room, chat, gamexstx, cardxstx},plugins: [createPersistedState({key: 'vuex',storage: window.localStorage,})]
})

因为localStorage不会随着网页刷新而丢失数据,所以将Vuex数据状态存储在此解决刷新丢失数据的问题。如下图,可以看到相应的数据存储。
在这里插入图片描述
另外,由于是明文存储,可能存在安全问题,可以使用secure-ls插件对数据进行加密存储。

// src/store/index.js
import SecureLS from "secure-ls"
var ls = new SecureLS({encodingType: "aes",    //加密类型isCompression: false,   //是否压缩encryptionSecret: "encryption",   //PBKDF2值  加密秘密
});export default new Vuex.Store({state,getters,mutations,actions,modules: {user, room, chat, gamexstx, cardxstx},plugins: [createPersistedState({// 以下使用ls加密key: 'vuex',storage: {getItem: (key) => ls.get(key),setItem: (key, value) => ls.set(key, value),removeItem: (key) => ls.remove(key),}})]
})

加密之后,控制台显示如下,可以看到vuex中内容已加密。
在这里插入图片描述

项目传送门:https://github.com/louislee92/vue-module-persistedstate

相关内容

热门资讯

最绚丽的安卓系统,最绚丽版本全... 哇,你知道吗?在安卓的世界里,有一款系统,它就像是一颗璀璨的明珠,闪耀着最绚丽的色彩。它就是——最绚...
小米系统安卓通知权限,深度解析... 亲爱的手机控们,你是否曾为手机通知栏里乱糟糟的信息而烦恼?又或者,你是否好奇过,为什么有些应用总是能...
安卓7.0系统能玩吗,体验全新... 你有没有想过,你的安卓手机升级到7.0系统后,那些曾经陪伴你度过无数时光的游戏,还能不能继续畅玩呢?...
平板安卓系统哪家好,安卓平板系... 你有没有想过,在这个科技飞速发展的时代,拥有一台性能出色的平板电脑是多么重要的事情呢?想象无论是追剧...
安卓好的点歌系统,打造个性化音... 你有没有想过,在安卓手机上,点歌系统竟然也能如此精彩?没错,就是那个我们每天都会用到,却又常常忽略的...
熊猫安卓系统直播软件,解锁互动... 你知道吗?最近有个超级酷炫的直播软件在熊猫迷们中间火得一塌糊涂!它就是熊猫安卓系统直播软件。别看它名...
安卓点播系统开发,Androi... 你有没有想过,手机里那些让你爱不释手的视频,其实背后有着一套复杂的安卓点播系统在默默支撑呢?今天,就...
安卓6.0系统加权限,深度解析... 你有没有发现,自从手机升级到安卓6.0系统后,权限管理变得超级严格呢?这可真是让人又爱又恨啊!今天,...
哪些电视带安卓系统,多款热门智... 你有没有想过,家里的电视竟然也能装上安卓系统?听起来是不是有点不可思议?没错,现在市面上就有不少电视...
苹果怎么运用安卓系统,揭秘如何... 你知道吗?最近有个大新闻在科技圈里炸开了锅,那就是苹果竟然开始运用安卓系统了!是不是觉得有点不可思议...
安卓系统能转什么系统好,探索最... 你有没有想过,你的安卓手机是不是也能换换口味,体验一下其他系统的魅力呢?没错,今天就来聊聊这个话题:...
龙之狂热安卓系统,释放龙族狂热 亲爱的手机控们,你是否曾为拥有一款独特的安卓系统而疯狂?今天,就让我带你走进一个充满奇幻色彩的龙之狂...
vivo手机安卓系统怎么升级系... 亲爱的手机控们,你是不是也和我一样,对手机的新功能充满期待呢?尤其是vivo手机的用户,是不是也在想...
鸿蒙2.0退回安卓系统,一场系... 你知道吗?最近科技圈里可是炸开了锅,因为华为的鸿蒙2.0操作系统竟然要退回安卓系统了!这可不是一个简...
安卓系统怎么复制卡,安卓系统卡... 你有没有遇到过这种情况:手机里的照片、视频或者重要文件,突然想备份到电脑上,却发现安卓系统的卡复制功...
app兼容低安卓系统,打造全民... 你有没有发现,现在手机APP更新换代的速度简直就像坐上了火箭!不过,你知道吗?有些APP可是特别贴心...
中间安卓系统叫什么,中间安卓系... 你有没有想过,安卓系统里竟然还有一个中间的版本?没错,就是那个让很多手机用户既熟悉又陌生的版本。今天...
安卓怎么用os系统,利用And... 你有没有想过,你的安卓手机其实可以变身成一个功能强大的操作系统呢?没错,就是那个我们平时在电脑上使用...
pe系统安卓能做么,探索安卓平... 亲爱的读者,你是否曾好奇过,那款在安卓设备上大受欢迎的PE系统,它究竟能做什么呢?今天,就让我带你一...
安卓 打印机系统,安卓打印机系... 你有没有想过,家里的安卓手机和打印机之间竟然能建立起如此紧密的联系?没错,就是那个安卓打印机系统!今...