Vuex需要遵守的规则
1.应用层级的状态应该集中到单个store对象
2.提交mutation是更改状态的唯一方法,并且这个过程是同步的。
3.异步逻辑都应该封装到action里面。
项目结构
如果你的store文件太大,只需将action、mutation、getter分割到单独的文件。
├── index.html
├── main.js
├── api
│ └── … # 抽取出API请求
├── components
│ ├── App.vue
│ └── …
└── store
├── index.js # 我们组装模块并导出 store 的地方
├── actions.js # 根级别的 action
├── mutations.js # 根级别的 mutation
└── modules
├── cart.js # 购物车模块
└── products.js # 产品模块
Vuex插件
Vuex插件就是一个函数,接受store作为唯一参数:
1.定义插件:
定义插件使用store.subscribe
const myPlugin=store => {
store.subscribe((mutation,state) => {
//mutation的格式为{ type,payload }
})
}
2.使用插件
const store=new Vuex.Store({
plugins:[myPlugin]
})
在插件内提交mutation
通过提交mutation,插件可以用来同步数据源到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)
}
})
}
}
const plugin=createWebsocketPlugin(socket){
const store=new Vuex.Store({
state,
mutation,
plugins:[plugin]
})
}
有时候插件需要获得状态的快照,用于比较前后状态。这时需要对状态进行深拷贝
const myPluginWithSnapshot=store => {
let prevState=_.cloneDeep(store.state)
store.subscribe((mutation,state) => {
let nextState=_.cloneDeep(state)
//比较preState和nextState
//保存状态,用于下次mutation
prevState=nextState
})
}
生成快照的插件应该只在开发阶段使用,使用webpack或Browserify,让构建工具帮我们处理。
const store=new Vuex.Store({
plugins:process.env.NODE_ENV !== 'production'?[myPluginWithSnapshot]:[]
})
上面的插件会默认启用。在发布阶段你要使用webpack的DefinePlugin或者Browserify的envify使process.env.NODE_ENV !== ‘production’为false
内置Logger插件
如果正在使用vue-devtools就不用这个插件
Vuex自带一个日志插件用于一般调试
import createLogger from 'vuex/dist/logger'
const store=new Vuex.Store({
plugins:[createLogger()]
})
createLogger函数的几个配置项:
const logger=createLogger({
collapsed:false, //自动展开记录的mutation
filter(mutation,stateBefore,stateAfter){
//若mutation需要被记录,就让它返回true即可
//顺便,mutation是个{ type,payload }对象
return mutation.type!=="aBlacklistedMutation"
},
transformer(state){
//在开始记录之前转换状态
//例如,只返回子树d
return state.subTree
},
mutationTransformer(mutation){
//mutation按照{ type,payload }格式记录
return mutation.type
},
logger: console //自定义console实现,默认为console
})
日志插件还可以直接通过