一,前言
截止到上一篇,Vue的5个核心概念就介绍完了,其中大部分介绍多来自于官网
这一篇介绍Vuex的插件功能
二,插件的创建和使用
Vuex的store接受plugins选项,这个选项暴露出每次mutation的钩子
Vuex插件是一个函数,它接收store作为唯一参数:
const myPlugin = store => {
// 当store初始化后调用
store.subscribe((mutation, state) => {
// 每次mutation之后调用
// mutation的格式为 { type, payload }
})
}
使用方式:
const store = new Vuex.Store({
// ...
plugins: [myPlugin]
})
在插件内提交 Mutation
在插件中不允许直接修改状态,类似于组件,只能通过提交mutation来触发变化
通过提交mutation,插件可以用来同步数据源到store
例如:同步websocket数据源到store:
export default function createWebSocketPlugin (socket) {
return store => {
socket.on('data', data => {
store.commit('receiveData', data)
})
store.subscribe(mutation => {
if (mutation.type === 'UPDATE_DATA') {
socket.emit('update', mutation.payload)
}
})
}
}
使用Vuex插件:
const plugin = createWebSocketPlugin(socket)
const store = new Vuex.Store({
state,
mutations,
plugins: [plugin]
})
四,生成 State 快照
有时候插件需要获得状态的“快照”,比较改变的前后状态。
想要实现这项功能,你需要对状态对象进行深拷贝:
const myPluginWithSnapshot = store => {
let prevState = _.cloneDeep(store.state)
store.subscribe((mutation, state) => {
let nextState = _.cloneDeep(state)
// 比较 prevState 和 nextState...
// 保存状态,用于下一次 mutation
prevState = nextState
})
}
每次mutation后进入subscribe获取当前state并和上一次的state对比
生成状态快照的插件应该只在开发阶段使用,使用webpack处理:
const store = new Vuex.Store({
// ...
plugins: process.env.NODE_ENV !== 'production'
? [myPluginWithSnapshot]
: []
})