You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
actions:{
updateA(){}, // A 可能在其他地方被单独使用
updateB(){}, // B 可能在其他地方被单独使用
updateAandB({dispatch}){
dispatch("updateA");
dispatch("updateB");
}, // 同时触发 A B 的复杂action
}
复制代码
如果在简历上写“XX电商系统”的实现,其实第一直觉是这个人一定是从培训班出来的。而我们“项目管理”课程正好就是做一个小型电商网站。开发时长一个月左右,包含买家端、卖家端、管理员端,虽然业务逻辑比较常见,但是这次开发仍有收获,最重要的一点收获就是 对Vuex有了真正的实践和认识。 所以,本文大部分介绍Vuex在该项目上的实践以及所踩的坑,另外的部分则是项目中一些其他要点的总结。
过去那臃肿的Vue组件
前面的几次项目开发,拿到后端接口和需求之后,会按照以下的方式去实现功能:
Promise
的then
方法里进行数据更新或者做更多的业务处理。好像没什么问题哈?
第1、2、3步基本上是没太大问题的,问题就出在第4步,其结果是导致一个Vue文件越来越大,到后面一个复杂的页面vue文件将会包含如下内容:
data
里大量的数据字段,有控制是否展示元素的
,渲染用数据
,用于"上锁"的变量
等。created
或mounted
里包含了大量的请求
和回调处理
。template
里使用的组件的属性内,绑定了大量的props
。最后的结果就是vue文件变得臃肿。
文件越长,可读难度会提高,可维护性会降低。
谁也不喜欢看一个包含了逻辑处理、界面处理、数据处理的冗杂代码文件。
所以,为了解决上述问题,引入
Vuex
是非常必要的。干净、解耦合、职责分明
笔者所做的,是将关于数据请求和更新,基本都放到了
Vuex
里,让Vuex
成为了整个项目的“数据集散中心”
,而vue
组件里,仅仅是进行事件调度(dispatch)
和绑定来自Vuex的数据
。简单的例子
我们以商品详情页面举例,其包含如下的功能:
如图所示:
如果我们不使用Vuex,代码的结构可能如下:
如果按照上述的方式来写,虽然可以保证关于这个页面的逻辑处理都保留在这个vue文件内,但是却显得十分臃肿,如果后续要加更多的功能抑或是修改,其需要读的代码可能更多。
所以,以上代码示例中的被
【MARK】
标记的部分,将是Vuex
可以优化的。 最后的代码如下图所示:代码的可读性提高了不少:
data
里不含任何业务数据字段,仅保留控制页面的字段【触发事件】-【回调】
这样简单的逻辑。关于数据处理的代码,全部封装到了
Vuex
上了:我们在Vuex层,不仅请求了数据,同时对返回的数据做了判断以及不同的逻辑处理,同时设置
Getters
使的页面能够基于Getters
提供的数据做各类二元判断
。Vuex层带来了如下的好处:
Actions
,就这个例子,我只要写了一次加入购物车
的函数,在各个页面都可以使用了。添加商品进购物车的同时更新商品数据并更新购物车数据
,这样需要写三次HTTP
请求的业务逻辑,此时只需要将三个Actions进行组合即可,而这几个Actions还可以在其他地方单独使用。数据仓库
带来的好处就是减少了数据层层传递的操作,按照以前的编码习惯,我会大量使用$emit
和props
来实现父子或兄弟组件通信,而现在,只需要在组件中触发相应的事件绑定相应的数据即可。全新的业务编写体验
直观体验来说,彻底使用
Vuex
后,编码思路清晰不少,因为写完整体的一个功能需要2~3天,而Vuex对于“间断性编程”
非常有帮助,能够迅速捡起上一次开发的进度。使用Vuex之后就是按照如下的步骤进行开发了:
(第1、2、3步不变,如前文) 4.构建Vuex的Store模型,定义所需的方法。 5.编写组件并绑定在Vuex上的相关数据和方法。 6.编写触发
dispatch
后的回调。笔者认为使用Vuex几个重要的原则
使用
Vuex
存在一定的规范,在官网上已经陈列了诸如表单处理
,测试
,项目结构
的规范,而下面的一些原则仅仅是笔者的一些经验之谈,不一定正确,有所帮助便是最好的。【不处理页面跳转】:页面跳转在
dispatch
的回调里进行处理。最初我的设计是在
Action
请求数据之后同时也负责所有的跳转逻辑
和弹窗逻辑
,不过,这样做又让视图层
和数据层
耦合了,使得我抽象出来的Action
的复用性变得极差,同时,在vue
文件看到关于视图层的处理才算是比较正常的编写逻辑。【单一职责原则】:
mutation
和action
尽量保持只做一件事原则。正如上一条原则中提到的要提高
action
的复用性,那么就要保证需要复用的action
只做一个功能,如更新A数据
和更新B数据
不要直接融合成一个action
,而是分别定义两个action
,并通过组合的方式来实现一个更复杂的功能,有点类似精简指令集的思想。如:
【使用Promise和AA】(Async & Await)
为了让
dispatch
函数拥有Promise风格
的处理回调的能力,可以让action
的返回值作为一个Promise
对象,如:在组件内就可以使用
.then
:而
Vuex
一般建议在actions
进行异步操作,所以为了让代码更加优雅,可以用AA
如下编写:所以,在实践中的代码如图:
【使用namespace】,为了你自己好。
一般使用vuex,会根据实体或者页面来拆分state形成module,一个module里包含其所需的所有
actions,states,mutation
等。如电商里,一般有商品
,订单
,用户
这几个实体可以拆成module,拆分出来之后如图:拆分的好处是更加独立直观了,坏处是如果不使用命名空间,可能造成
actions
,mutations
冲突,正好Vuex
也提供namespace
的配置,参考官方文档即可。这次使用的不足
未使用namespace
虽然总结到了原则里,不过这次并没有使用
namespace
,算是这次比较大的不足了,解决的办法是”手动namespace“,如图:将
actions
的方法名前缀加上该实体名用于区分不同的方法,实在是比较拙劣的手段了。部分代码仍然有重复书写的情况
情况发生在获取到异步数据之后的代码,一般如下这段代码会大量重复:
虽然不算多,但是这逻辑仍然有可抽象出来的可能性,下次打算在
RootState
里添加一个action
,用于处理这样的后端返回数据,期望结果如下:其他收获
拥抱 Vue CLI 3
3.0 基本在配置上做到
极简化
了。很久没开发Vue
的项目了,记得上一个Vue
项目里,仍然有一大堆xxx.congfig.js
,而现在,基本集成到了CLI内部了,通过一个vue.config.js
可满足大部分开发需求。本项目配置如下图:比以前的配置更加直观了,更多请参考:cli.vuejs.org/zh/,至于插件机制,本次开发未用上,只是在安装第三方包的时候可以用
vue add
了,有GUI可以查看安装了哪些插件。将
Vue.use 和 Vue.install
使用的地方汇总到plugins
目录下本项目是一个多页面应用,总共有3个Vue实例,所以希望能够按需注入想要的第三方依赖如
axios
,qrcode
,lazyload
等一些工具库或第三方组件。于是都将其汇总到plugins
目录下了,如下图:这样封装的好处是,我可以对每个Vue实例按需导入第三方依赖,一行import就可以,如下图:
开始考虑优化了
一个大型的web app 打包压缩后都不超过500kb,所以就以此作为
Benchmark
来优化该项目打包后的大小,按需引入
第三方依赖(特别是Element
和lodash
)减少了不少项目体积。不过最主要的还是得学会用webpack analyse tool
来分析。结论
总之,本次项目主要是刷新了对
Vuex
的认知,其能够让我们编写的vue
组件可读性和可维护性更高。同时,也能够让数据更新这块的代码复用性更高。通过Vuex
来构建一个中心化的数据集散中心
还能让开发的思路更顺畅,值得学习。参考:
Vuex 是什么?
The text was updated successfully, but these errors were encountered: