利用vuex的plugins选项写一个简单的本地持久化插件

499 阅读1分钟

在vuex中,很多时候我们不希望保存在vuex中的状态因为刷新页面而丢失。这时候我们可以结合浏览器的 sessionStorage 或者 localStorage 来选择性的进行数据管理。多的不说直接贴出代码:

const myPlugin = (options = {}) => {
  const KEY = 'vuex' // 本地储存 键
  const storage = window.sessionStorage // 本地储存方式

  // 储存状态
  function setState(state) {
    return storage.setItem(KEY, JSON.stringify(state))
  }

  // 获取状态
  function getState() {
    const data = storage.getItem(KEY)
    if (data) {
      return JSON.parse(data)
    }
    return {}
  }
  
  return function (store) {
    // 当 store 初始化后调用
    let currentState = JSON.parse(JSON.stringify(store.state)) // 当前state
    let storageState = getState() // 储存在本地的状态

    for (let item in currentState) {
      if (storageState[item]) {
        currentState[item] = storageState[item]
      }
    }
    // 直接重置 store.state
    // 因为插件中只能通过 mutation 修改状态,不允许通过state直接修改状态。
    // 所以这里利用 replaceState 方法替换全部 state
    store.replaceState(currentState)


    store.subscribe((mutation, state) => {
      // 每次 mutation 之后调用
      let storageData = {} // 需要储存的数据 
      const reducer = options.reducer
      if (reducer && typeof reducer === 'function') {
        storageData = options.reducer(state)
      }
      setState(storageData)
    })
  }
}

使用插件

const store = new Vuex.Store({
  // ...
  plugins: [
    myPlugin({
       reducer(state) {
           return {
              // 只储存state中的demoData
              demoData: state.demoData
           }
       }
    })
  ]
})

以上就是全部代码。由于本文主要是想要大家了解vuex插件,所以更为细致的封装,发布到npm上,这些就留给爱学习的你们了。
想更详细的了解vuex的插件,可去查看官方文档

注意事项:

  • Vuex 插件就是一个函数,它接收 store 作为唯一参数, 当每次mutation之后都会调用 subscribe 方法。
  • 在插件中不允许直接修改状态——类似于组件,只能通过提交 mutation 来触发变化。