Vuex插件

在创建 store 的时候,可以为其配置插件,插件的主要功能是提供一种面向切面 (Aspect Oriented Programming, AOP) 的钩子函数。例如,在 Vuex 中,修改 state 的主要操作来自于 mutation,如果需要监测到 mutation 的调用,可以在每个 mutation 前添加自己的监测逻辑,这其实不难,代码如下:但是对于一个大型的项目中有很多 mutation 的调用,我们能否监测到每次 mutation 的调用又不侵入业务逻辑呢?这就需要用到插件提供的钩子函数来实现,如示例代码 6-8-1 所示。

methods: {
    clb() {
        console.log('mutation调用开始')
        this.$store.commit('increment', {
            num: 4
        })
        console.log('mutation调用结束')
    }
}
示例代码 6-8-1 rootState 和 rootGetter 参数的使用
const myPlugin = (store) => {
    // 当 store 初始化后调用
    store.subscribe((mutation, state) => {
        console.log('mutation调用开始结束')
        // 每次 mutation 之后调用
        // mutation 的格式为 { type, payload }
    })
}
const store = Vuex.createStore({
    plugins: [myPlugin],
    state: {
        count: 3
    },
    mutations: {
        increment(state,params) {
            state.count = state.count + params.num
        }
    }
})
const counter = {
    template: '<div>{{ count }}<button @click="clb">增加</button></div>',
    methods:{
        clb(){
            // 通过this.$store.commit调用mutations
            this.$store.commit('increment', {
                num: 4
            })
        }
    }
}

上面的代码中,首先定义了一个插件,在插件中采用 store.subscribe 方法就可以监测到使用该 store 下所有的 mutation 调用。每当我们调用 increment 时就会进入这个方法,其中第一个参数 mutation 是当前调用的 mutation 内容,typeincrement 的名字,payloadincrement 的参数。第二个参数是当前 state 的内容。这样,我们就在不侵入原有业务逻辑代码的情况下实现了 mutation 的监测。

利用插件,我们也可以记录 state 快照,每当 state 改变时都记录下前后的差异,这样更加有利于 Vuex 的调试,这也是 Chrome 浏览器的 Vue DevTools 工具的核心功能之一,代码如下:

const myPluginWithSnapshot = (store) => {
    let prevState = _.cloneDeep(store.state)
    store.subscribe((mutation, state) => {
        let nextState = _.cloneDeep(state)
        // 比较 prevState 和 nextState
        // 保存状态,用于下一次 mutation
        prevState = nextState
    })
}

也可以在插件中打印逻辑日志,相当于记录用户的操作,这些都是 Vuex 插件给我们提供的非常便利的功能。