微信号:DianrongMafia

介绍:点融黑帮——一个充满激情和梦想的技术团队,吸引了来自金融及信息科技领域的顶尖人才.我们正在用技术创新改变传统金融.

Vue世界中的Redux——Vuex

2017-09-26 19:00 徐毅俊


目标读者

Vue.js开发者,对Redux有经验

了解State Management



ReduxReact的使用已经几乎是事实标准了,但随着Vue的崛起,一些Web应用已经开始使用Vue来搭建或者正在迁移至Vue如果原先不是用Mobx来管理应用状态的,那么你一定在寻找一个可以比拟Redux的工具或框架,Vuex就是这么一个选择。


✎试验代码


先从一个不使用Vuex的应用来开始。模拟场景为展示一个图书馆注册用户已借的书目以及自身会员信息,并假使用户可以点击扫码按钮来借新一本新的书,直接使用数据对象作为数据源。



大致效果(Unstyled)



✎改造开始


首先需要:

import Vuex from 'vuex'

Vue.use(Vuex);

(本文使用的vuex版本为2.3.1)


试着定义第一个Store

这里Store的概念和redux比较接近。


 

这里的data是一个数据常量,data.books是一个普通的Array。表示初始状态。


如果需要修改状态,那么必须要提供mutations

这个与redux中的reducer类似。Vuex允许在state后定义一连串的修改方法(mutations),这种方式非常直观。但与redux不同的是,由于实现机制的区别,Vuex中的state可看作是 能够 直接被修改的。强调一下,与Reduxreducer方法类似,mutations中的每个方法必须是同步的。



使用mutations很简单,使用store.commit即可,例如store.commit('addNewBook', { title: ..., due: ... } )就可以了。 


✎如何处理异步操作


异步操作将会用到ActionsAction方法可以通过调用context(第一参数)中的commit方法来使用mutations,从而达到最终修改状态的目的,且Action自身的实现可以不必是同步的。actions 本身使用store.dispatch()来调用。在redux上使用过redux-thunkredux-promisemiddlewares的读者,很容易理解这个Actions的这个作用。(这里用setTimeout来摸拟通过bookId取得book数据。)



✎创建第二个Store


类似的,假设我们的data.membership是一个对象类型。并以此为数据创建一个 membershipStore。也就是说state的最外层既可以是数组,也可以是普通对象。


✎Modules


关键时刻到了,如果我们要合并两个状态,那么我们的combineReducers大招在哪里?



Vuex中,相似的概念叫做modules combination。附上最简单的使用方法。


注意,在合并为一个store, modules中的booksStore参数就不再需要是Vuex.Store创建的对象了,只需要那个对Store的定义对象就足够了。换言之,这里的bookStores = { state: ... }


✎连接两个世界


将最终Vuex Store作为参数在创建Vue instance时传入就可以了(key'store')。但还需要把store中的数据映射到你的Vue instance中去,而Vuex提供了许多种方法。这里推荐Vuex.mapState,相当简洁的方案,已能满足绝大多数情况。是不是让你想起了 react-redux中的@connect?

一但注入了storethis.$store就有对应的值了。还记得store.dispatch()吗?



✎运行起来


最后,我们把所有代码整合起来。

点一下"Scan Barcode..."button,这时我们梳理一下流程。

此时Event handler调用到borrowBook 然后通过dispatch,最终再到commit,将一条新的book记录放入state中,Vue 检测到这一改动,重绘了books列表。成功!



✎其他观点


以下的几个特性,由于篇幅有限,没有在文中提及。相信在实际开发中一定会遇到:

1. mutation或者actions的命名,可以常量化。充分利用es6的语法(Computed Property Name)

2. 利用Vuexgetters特性可以做出类似reselect(on redux)的效果。

3. modules合并时可以自定义namespace,例如可以实现dispatch('/books/borrowBook')

4. 如果需要在state对象中动态增加新的属性(没有预先定义),需要额外操作。


成文仓促,定有不足之处,请读者不吝指正。

欢迎与作者交流,共同学习。






点击回顾往期精彩内容

点融荣登“中国网贷先锋榜”

Affordance杂谈

浅谈金融类APP测试

今天我们来谈谈信息收集这件小事

用Django编写后端任务流程

Webpack优化 | 快一点,再快一点

活动回顾 | CTDC2017首席技术官领袖峰会成功举办

今天我们来聊一聊运动这件事。

CSP与并发编程

使用 Mesos 管理 Docker 实践

来共享密钥吧

浅谈交易手续费设计#1

多Header or Footer的RecyclerViewAdapter

浅谈 golang channel



想了解更多请关注我们



 
点融黑帮 更多文章 点融荣登“中国网贷先锋榜” Affordance杂谈 浅谈金融类APP测试 ​今天我们来谈谈信息收集这件小事 用Django编写后端任务流程
猜您喜欢 Google 官方应用架构的最佳实践指南 最好的安卓网络请求库: Fast Android Networking(上) 备份策略 - 单表备份的隐患与应对方案 一个学法的码农看快播案 春田花花同学会 - 腾讯ISUX