前言:
尽管redux存在对缓存数据的模块化拆分,但随着项目的整体业务逻辑的一步步壮大,需要管理的数据和状态也逐步增加;
于是,繁复的switch代码让部分reducer显得很复杂,给后期维护增加了工作量之余,也对开发阶段造成了一定的影响。
需求:
针对上述情况,于是想着是否能做一些代码结构的调整,让此部分代码显得清晰明了,减轻开发和维护阶段的工作量?
参考思路:
在vue里运用vuex之初,基本上是照着官方文档敲得代码,于是,尽管做了模块化拆分,但大量相似的mutation还是让页面显得很臃肿。
然后发现实际上大部分的mutation操作的逻辑是类似的,都是重新赋值操作;于是,对mutations部分的实现变成了如下所示:
const mutations = {}
Object.keys(state).forEach(prop => {
const setProp = `set${prop.charAt(0).toUpperCase()}${prop.slice(1)}`
mutations[setProp] = (state, payload) => {
state[prop] = payload
}
})
如上实现方式的好处有两点:
1,纯函数:将mutation变成了安全的纯函数的形式
2,逻辑单一:不用再去考虑在mutation里写入其他不必要的逻辑(因为这些逻辑实际上可以在commit之前就完成)
尝试实现:
根据上述对vuex里mutation部分的实现,也许我们可以将如下reducer的形式:
const initUser = {
user_info: {}
}
export default (user=initUser,action) => {
switch (action.type){
case 'update_user_info':
return Object.assign({}, user, {
user_info: action.user_info,
token: action.token || 'zixiaochen'
})
break;
case 'user_is_update':
return Object.assign({}, user, {
update_info: action.update_info
})
break;
case 'clear_user':
return user;
break;
default:
return user
}
}
修改为:
const actions = {}
Object.keys(initUser).forEach(prop => {
const setProp = `update_${prop}`
actions[setProp] = (state, payload) => {
return {
...state,payload
}
})
export default (user=initUser,action) => {
actions[action.type](user,action.updateData);
}
实现思路为:
1,将redux里数据变更的部分拆分出来,作vue中mutation的处理;
2,用...扩展符号,浅复制一个相同的数据对象,然后用新增数据部分payload对象去合并覆盖该复制对象里的已有属性的值
3,调用actions里的方法,传入state对象和需要变更的数据对象(也就是payload对应的实参)
参考文档:
动手实现 React-redux:
http://huziketang.mangojuice.top/books/react/lesson30
如何更优雅地使用 Redux:
https://cloud.tencent.com/developer/article/1005855
vue官方文档
hippus关于vuex的代码优化