# Vuex 插件

Vuex 中提供了插件机制,mini-Vuex3 同样提供了插件机制,并内置了 logger 日志插件和 persists 持久化插件,下面我们来简述一下 Vuex 的插件机制

首先我们要知道,对于 Vuex 中的数据,其修改都需要经过 mutations,所以,一般来说,插件都是通过监听 mutations 的执行来实现的。Vuex 中提供了监控 mutations 执行的方法 subscribe

    /**
     * 订阅 store 的 mutation。handler 会在每个 mutation 完成后调用,接收 mutation 和经过 mutation 后的状态作为参数:
     * @param {Function} handler 每个 mutation 完成后调用的函数
     */
    subscribe(handler) {
        if (typeof handler === 'function') {
            this.subscribes.push(handler)
        }
    }

subscribe 会将所有传入的回调函数维护成一个队列挂载在 store 上,当任意一个 mutations 中的方法被执行时,都会遍历执行 subscribe 回调队列中的函数。

我们以 persists 插件举例:

export default function persists(store) {
    let state = localStorage.getItem('MINI_VUEX_STATE')
    if (state) {
        store.replaceState(JSON.parse(state))
    }
    store.subscribe(function (mutation, state) {
        localStorage.setItem('MINI_VUEX_STATE', JSON.stringify(state))
    })
}

首先,Store 在初始化实例时,最后会执行所有的插件(Vuex 的插件都是函数或高阶函数)。此时 persists 插件会向 localstorage 中寻找 key 为 MINI_VUEX_STATE 的缓存,如果有,则调用 replaceState 方法替换当前的根 state。之后有又调用了 subscribe 方法监听mutations,当mutations 执行,也就是 state 可能发生变化时,保存当前根 state 中的数据到 localstorage。

所以,我们尽量不要在 mutations 之外去修改 state 中的数据,因为各种插件可能无法监测到这种变化,包括 Vue 的调试工具 devtools 也无法追踪到这种改变。