立诚勿怠,格物致知
It's all about connecting the dots

Vuex Data Persistence数据持久化

In one of my frontend project using VueJS, there is a need to maintain run-time data in javascript to local hardware so that these data will not be lost in case of a page refreshing. This requirement can be saying in another way – data persistence is required. Since the diversity of frontend environment, there are many stuff can be employed to save your run-time data. For example, if you use react-native, you can use one of React Native’s API called AsyncStorage; if you are written html webpage, the Html api sessionStorage, localStorage and cookie can all be employed. And today we are going to employ localStorage, we’re going to talk about data persistence in webpage developed using VueJS.

First, let’s talk about the premise: my project used vue 2.2.1, vuex 2.2.1, and vuex-persist 0.1.8. To use vuex-persist 0.1.8, the official npm page says that Vue of version equal to or higher than 2.0 ,  vuex of version equal to or higher than 2.1 are required.

Vuex-persist is used as a plugin of vuex. In my program, I create the store using code like below (simplified and many code is removed):

// import Vue from 'vue'
import Vuex from 'vuex'
import { merge } from './utils'
import { config } from './mode'
import mock from '../mock'
import VuexPersistence from 'vuex-persist'

// 用于使用script标签加载window.Vuex,Vuex会被自动安装,无需手动安装
// Vue.use(Vuex)

const state = {
  config,
  mock,
  states: {
    // other code here
    alertingOkCallback () {},
    alertingCancelCallback () {},
    // other code here
  },
  wechat: {},
  user: {},
  car: {},
  order: {},
  options: {
    orderStatus: [
      { value: '0', text: '核保中', belong: '核保中' },
      { value: '1', text: '已取消', belong: '已取消' },
      { value: '2', text: '质检失败', belong: '核保中' },
      { value: '3', text: '核保失败', belong: '核保失败' },
      { value: '4', text: '待核保', belong: '核保中' },
      // { value: '5', text: '待质检', belong: '核保中' },
      { value: '5', text: '待缴费', belong: '核保中' },
      { value: '6', text: '已质检', belong: '核保中' },
      { value: '7', text: '待解付', belong: '核保成功' },
      { value: '8', text: '待出单', belong: '核保成功' },
      { value: '9', text: '已出单', belong: '已完成' },
      { value: '10', text: '已分配快递员', belong: '已完成' },
      { value: '11', text: '已取单', belong: '已完成' },
      { value: '12', text: '配送成功', belong: '已完成' },
      { value: '13', text: '配送失败', belong: '已完成' },
      { value: '14', text: '已退单', belong: '已取消' },
      { value: '15', text: '代垫付', belong: '核保成功' },
      { value: '16', text: '转人工', belong: '核保中' }
    ],
    certificateType: [
      { value: '1', text: '身份证' },
      { value: '2', text: '组织机构代码证' },
      { value: '3', text: '护照' },
      { value: '4', text: '军官证' },
      { value: '5', text: '港澳回乡证或台胞证' },
      { value: '6', text: '其他' },
      { value: '7', text: '港澳通行证' }
    ]
  }
}

const initialStateString = JSON.stringify(state)

const getters = {
  config: state => state.config,
  mock: state => state.mock,
  states: state => state.states,
  user: state => state.user,
  wechat: state => state.wechat,
  car: state => state.car,
  order: state => state.order,
  options: state => state.options
}

const mutations = {
  setStates (state, options) { merge(state.states, options) },
  setUser (state, options) { merge(state.user, options) },
  setWechat (state, options) { merge(state.wechat, options) },
  setCar (state, options) { merge(state.car, options) },
  setOrder (state, options) { merge(state.order, options) },
  resetAllStoreInfo (state, options) {
    merge(state, (() => {
      const originalState = JSON.parse(initialStateString)
      return {
        states: originalState.states,
        // user: originalState.user,
        wechat: originalState.wechat,
        car: {
          ...originalState.car,
          ownerName: state.car.ownerName,
          plateHeader: state.car.plateHeader,
          plateBody: state.car.plateBody
        },
        order: originalState.order
      }
    })())
  }
}

const actions = {
  load: ({ commit }, bool) => commit('setStates', {
    isLoading: bool
  }),
  roar: ({ commit }, { text, callback }) => commit('setStates', {
    isRoaring: true,
    roaringText: text,
    roaringCallback: callback || null
  }),
  alert: ({ commit }, { text, callback }) => commit('setStates', {
    isAlerting: true,
    alertingText: text,
    alertingOkCallback () {
      callback && callback()
      commit('setStates', { isAlerting: false })
    },
    alertingCancelCallback: null
  }),
  confirm: ({ commit }, { text, okCallback, cancelCallback }) => commit('setStates', {
    isAlerting: true,
    alertingText: text,
    alertingOkCallback () {
      okCallback && okCallback()
      commit('setStates', { isAlerting: false })
    },
    alertingCancelCallback () {
      cancelCallback && cancelCallback()
      commit('setStates', { isAlerting: false })
    }
  }),
  wait: ({ commit }, bool) => commit('setStates', {
    isWaiting: bool
  }),
  present: ({ commit }, val) => commit('setStates', {
    presenting: val
  })
}

const vuexLocal = new VuexPersistence({
  storage: window.localStorage,
  reducer: state => ({
    user: state.user,
    wechat: state.wechat,
    car: state.car,
    order: state.order
  }),
  filter: (mutation) => (
    mutation.type === 'setUser' ||
    mutation.type === 'setWechat' ||
    mutation.type === 'setCar' ||
    mutation.type === 'setOrder' ||
    mutation.type === 'resetAllStoreInfo'
  )
})

export default new Vuex.Store({
  state,
  getters,
  actions,
  mutations,
  plugins: [vuexLocal.plugin]
})

Attention

Please be aware of that some of the code above is not written in the best or at least better practice, for example, state.options is just static data, and these data can be separated to a new file and not included in the state variable, because it’s not necessary to monitoring these data through vuex. They are listed here just for intention purpose.)

Analyse

First, let’s analyze that which data in variable state should be keep persist – that’s to say – which data should be saved to local hardware through Html5 api  localStorage.

You can see there are eight children under variable state: ‘config’, ‘mock’, ‘states’, ‘wechat’, ‘user’, ‘car’, ‘order’, and ‘options’. Now I tell you that children like ‘config’, ‘mock’ and ‘options’ are all static data that won’t be changed through entire run-time. So it’s obviously that only children ‘states’, ‘wechat’, ‘user’, ‘car’, ‘order’. Absolutely, it’s not. The children ‘states’ is used to store data for common layout components like alert dialog popup, and you can see that there is method properties stored in children ‘state’, so it’s not appropriate to save it in localStorage. So finally, we only need to keep data in ‘wechat’, ‘user’, ‘car’ and ‘order’ persistent. So now you know why the configuration object passed to new VuexPersistence is as below:

const vuexLocal = new VuexPersistence({
  storage: window.localStorage,
  reducer: state => ({
    user: state.user,
    wechat: state.wechat,
    car: state.car,
    order: state.order
  }),
  filter: (mutation) => (
    mutation.type === 'setUser' ||
    mutation.type === 'setWechat' ||
    mutation.type === 'setCar' ||
    mutation.type === 'setOrder' ||
    mutation.type === 'resetAllStoreInfo'
  )
})

I won’t cover configuration detail for vuex-persist, because you can simply open the official link here: https://www.npmjs.com/package/vuex-persist and read it online.

Conclusion

Actually, vuex-persist is just a nom package used to generate a vuex plugin which can save and restore data to and from api like localStorage. You can revise plugin alike yourself, if you read the source code of vuex-persist, you will know it’s just not a hard work. If you doesn’t know how to write a plugin for vuex, you can read this webpage: https://vuex.vuejs.org/en/plugins.html.

————-stylish cutting line————–

Written by Yakima Teng,

August 27, 2017

in Shanghai, China

赞(1) 打赏
文章名称:《Vuex Data Persistence数据持久化》
文章链接:https://www.orzzone.com/vuex-data-persistence.html
商业联系:yakima.public@gmail.com

本站大部分文章为原创或编译而来,对于本站版权文章,未经许可不得用于商业目的,非商业性转载请以链接形式标注原文出处。
本站内容仅供个人学习交流,不做为任何投资、建议的参考依据,因此产生的问题需自行承担。

评论 2

  1. #1

    帮助很大,多谢分享。

    xhy7年前 (2017-10-20)回复

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力提供更多优质内容!

支付宝扫一扫打赏

微信扫一扫打赏

登录

找回密码

注册