Skip to content

Instantly share code, notes, and snippets.

@jrainlau
Last active April 17, 2019 03:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jrainlau/36ba8bb88f6940316044d3c35f5a370e to your computer and use it in GitHub Desktop.
Save jrainlau/36ba8bb88f6940316044d3c35f5a370e to your computer and use it in GitHub Desktop.
vuex state lasting in localstorage
/**
* VuexLastingPlugin
*
* @desc Store vuex states in storage
* @author JrainLau jrainlau@gmail.com
*
* @param {Object} options options
* @param {String|Array} options.watch the state to store
* @param {Boolean} options.debug debug mode
* @param {Boolean} options.autoInit init state from storage automatically
* @param {Object} option.storage store state in localStorage (in default) or sessionStorage
* @param {String} options.storageKey item key in storage
*
* @example store = { plugins: [VuexLastingPlugin({})], state: {}, mutations: {}, actions: {} }
*/
function getObjDeepValue (obj, keysArr) {
let val = obj
keysArr.forEach(key => {
val = val[key]
})
return val
}
function setObjDeepValue (obj, keysArr, value) {
let key = keysArr.shift()
if (keysArr.length) {
setObjDeepValue(obj[key], keysArr, value)
} else {
obj[key] = value
}
}
function logger (msg) {
console.log(`%c vuex-lasting-plugin %c ${msg} %c`, 'background:#35495e ; padding: 1px; border-radius: 3px 0 0 3px; color: #fff', 'background:#41b883 ; padding: 1px; border-radius: 0 3px 3px 0; color: #fff', 'background:transparent')
}
const VuexLastingPlugin = function ({
watch = '*',
debug = true,
autoInit = true,
storage = localStorage,
storageKey = 'VuexLastingData'
}) {
return store => {
if (autoInit) {
const localState = JSON.parse(storage && storage.getItem(storageKey))
const storeState = store.state
if (localState) {
Object.keys(localState).forEach(key => {
if (key.includes('deep_')) {
let keysArr = key.replace('deep_', '').split('.')
setObjDeepValue(storeState, keysArr, localState[key])
delete localState[key]
}
})
store.replaceState({ ...storeState, ...localState })
logger('States were init from localStorage.')
}
}
store.subscribe((mutation, state) => {
let watchedDatas = {}
if (watch === '*') {
watchedDatas = state
} else {
watch.forEach(key => {
if (key.split('.').length > 1) {
watchedDatas[`deep_${key}`] = getObjDeepValue(state, key.split('.'))
} else {
watchedDatas[key] = state[key]
}
})
}
if (debug) {
logger('The states below were stored.')
console.log(watchedDatas)
}
storage && storage.setItem(storageKey, JSON.stringify(watchedDatas))
})
}
}
export default VuexLastingPlugin
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment