前言
下文引用一个简单的用户登录状态信息缓存例子,使用vuex
中的modules
选项对用户状态信息进行分模块维护的,使用plugins
插件选项,注册一个用来同步state
中的用户状态和本地缓存数据同步更新。
了解vuex的modules和plugins选项
modules
:用来解决当项目比较复杂时,单一的状态树所导致store
对象变得臃肿所导致的维护困难问题,每个模块都可以拥有自己的state
、mutation
、action
、getter
选项。
plugins
:这个选项暴露出每次mutation
的钩子。Vuex
插件就是一个函数,它接收store
作为唯一参数,可在该方法中监听mutation
钩子的执行。
新建用户模块
store/modules/user.js
js
import { login, logout } from '@/api/user'
const user = {
state: () => ({
name: '',
avatar: '',
token: null
}),
mutations: {
setUser(state, data = {}) {
console.log('setUser', data)
const { name, avatar, token } = data
state.name = name
state.avatar = avatar
state.token = token
},
removeUser(state) {
state.name = ''
state.avatar = ''
state.token = null
console.log('removeUser')
}
},
actions: {
login({commit}, data = {}) {
const { username, password } = data
return new Promise((resolve, reject) => {
login(username, password).then(res => {
commit('setUser', res)
resolve()
}).catch(error => {
reject(error)
})
})
},
logout({state, commit}) {
return new Promise((resolve, reject) => {
logout(state.token).then(() => {
commit('removeUser')
resolve()
}).catch(error => {
reject(error)
})
})
}
}
}
export default user
以上我们单独创建一个用户模块来维护和用户相关状态,分模块管理的方式对于中大型应用可以清晰地维护相关状态信息。登录和退出登录接口设计异步操作,所有我们定义在actions
选项中。
注册模块
store/index.js
js
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
user
},
state: {},
mutations: {}
})
export default store
把user.js
模块引入到store
跟实例的modules
对象中。注册后,对于user
模块的选项定义属性值,会和合并到store
根实例中。如果需要独立隔离命名空间 ,可在user
模块中添加属性namespaced: true
。
js
// user.js
const user = {
namespaced: true,
...
}
创建插件
store/plugins/storage.js
js
import { setStorage, removeStorage, getStorage } from '@/utils/storage'
import { USER_KEY } from '@/utils/constant'
// 当 store 初始化后调用
const storage = store => {
console.log('初始化')
// 获取缓存的用户信息
const user = getStorage(USER_KEY)
// 用户存在,初始化用户信息
user && store.commit('setUser', user)
// 监听commit方法的执行
store.subscribe((mutation, state) => {
if(mutation.type === 'setUser') {
setStorage(USER_KEY, state.user)
} else if(mutation.type === 'removeUser') {
removeStorage(USER_KEY)
}
})
}
export default storage;
以上我们创建了一个storage
插件,用于对用户登录信息进行本地持久化和初始化。当store
初始化时会调用该方法,并且参数会返回初始化后的store
对象。
我们可以在该方法中对用户信息进行初始化,以及监听当执行更新用户信息的mutations
方法时,自动更新本地缓存的用户信息。
引入到store
跟实例并注册插件
js
// store.js
const store = new Vuex.Store({
// 注册插件
plugins: [storage],
modules: {
user
}
})
缓存方法封装
以下使用的时uniapp
提供的本地缓存api
:
utils/storage.js
js
export const setStorage = (key, data) => {
uni.setStorageSync(key, data)
}
export const removeStorage = (key) => {
uni.removeStorageSync(key)
}
export const getStorage = (key) => {
const data = uni.getStorageSync(key)
return data
}
以上我们对缓存方法的封装的目的是便于后续进行扩展,比如:
1.同一域名下如果存在多个项目,则当缓存的
key
属性相同时,可能会造成多个项目之间的数据污染 ,这时可在可在缓存前增加一个 项目名称前缀 等方式包装key
得唯一性。2.需要设置
key
的有效时间时,可以把字段包装成一个包含缓存时间的对象进行缓存。3.当需要对缓存数据进行加密时。
4.当你要切换缓存
api
时。5.其他扩展...
总结
以上通过一个简单的用户登录的例子来展开叙述,通过vuex
中的modules
选项对用户相关状态进行分模块维护,使用plugins
选项注册一个插件,用来保证vuex
中的用户状态信息和本地的缓存用户信息进行通过,在使用缓存相关api
时,建议统一进行封装,便于后续项目扩展。