基于Proxy的小程序状态管理指南教程_小程序小白教程

微信小程序的市场在进一步的扩大,而背后的技术社区仍在摸索着最好的实践方案。我在帮助Nike,沃尔玛以及一些创业公司开发小程序后,依旧认为使用小程序原生框架是一个更高效,稳定的选择,而使用原生框架唯独缺少一个好的状态管理库,如果不引入状态管理则会让我们在模块化,项目结构以及单元测试上都有些捉襟见肘。目前相对比较稳健的做法是针对redux或者mobx做一个ada

基于Proxy的小程序状态管理指南教程

微信小程序的市场在进一步的扩大,而背后的技术社区仍在摸索着最好的实践方案。我在帮助Nike,沃尔玛以及一些创业公司开发小程序后,依旧认为使用小程序原生框架是一个更高效,稳定的选择,而使用原生框架唯独缺少一个好的状态管理库,如果不引入状态管理则会让我们在模块化,项目结构以及单元测试上都有些捉襟见肘。

基于Proxy的小程序状态管理指南教程_小程序小白教程

目前相对比较稳健的做法是针对redux或者mobx做一个adaptor应用到小程序中,但这样需要自己想办法打包引入外部库,还要想怎么去写这个adaptor,总显得有些麻烦。于是我迸发出一个想法去写一个专用于小程序的状态管理库,它使用起来足够简单并且可以通过小程序自己的npm机制安装。

目前我已经用这个开源库开发了两个电商小程序,在提高我开发效率的同时亦保证了程序的性能,所以接下来我想谈谈这背后的理念以启发更多开发者尝试新的解决方案。

基于Proxy的小程序状态管理指南教程_小程序小白教程

基于Proxy的状态管理实现

Proxy在小程序中已经得到了足够好的支持,目前并没有发现在任何iPhone或者Android上不能使用Proxy的情况。而基于Proxy的状态管理其实也就是订阅监听的模式,一方面监听数据的变化,另一方面将这些变化传达给订阅的小程序页面。

举一个比较常见的例子,当一个用户从自己的主页进入用户编辑页面,然后更改了自己的用户名点击保存后,用户主页和用户编辑页上的用户名这时候都应该被更新。这背后的程序逻辑则是:更新这个行为将触发Proxy去通知状态管理库,然后状态管理库负责检查此时还在页面栈中的所有页面,更新订阅了用户名这个数据的页面,如下图:
基于Proxy的小程序状态管理指南教程_小程序小白教程

Part1: 监听数据变化

监听数据变化其实就是监听各个Store的属性变化,实现上就是在各个Store前面加了一层Proxy,用更直观的图片来表示就是这样:
图片描述

当一个Store被观察以后,它的属性就都变成了Proxy实例,当这个属性值是Object或者Array的时候,它内部的值也会被包装成Proxy实例,这样无论多深层的数据变动都能被监听到。
而在Proxy的后面,Store的属性其实是被另一套数据(紫色部分)所维护,这套数据不负责监听,它就是纯数据,针对属性的任何变动最后都会应用到这套数据上来,它的作用是维护和返回最新的数据。

Part2: 页面数据绑定

因为小程序每个页面的js都是向Page中传递一个对象,这就让我们有机会包装这个对象,从而实现:

  1. 进入页面后,将页面保存在页面栈中
  2. 将来自状态管理库的数据映射到这个页面的data上来
  3. 页面退出时,将页面从页面栈中移除

Part3: 页面订阅更新

当数据被监听到变化后,我们需要依次做两件事,先是找到所有存储在页面栈里的页面,然后根据各个页面订阅的数据来检查变化,如果有变化就通知这些页面,从而让它们去触发setData更新页面。

使用状态管理的例子

有了状态管理库,现在我们就来实现一开始举例的更新用户信息的操作,我们的文件路径如下:

stores/
  user.js
pages/
  userEdit/
     index.js
     index.wxml

1.首先我们创建一个Store保存用户的信息,并且监听它的变化:

// stores/user.js
import { observe } from 'minii'

Class UserStore {
  constructor () {
     this.name = 'bob'
  }

  changeName (name) {
     this.name = name
  }
}

export default observe(new UserStore(), 'user')

2.接着在我们的小程序页面订阅Store的信息

// pages/userEdit/index.js
import { mapToData } from 'minii'
import userStore from '../../stores/user'

const connect = mapToData(state => (({
  myName: state.user.name
}))
Page(connect({
  updateNameToJames () {
    userStore. changeName('james')
  }
}))

3.完成,现在可以在页面中使用和更新数据了

// pages/userEdit/index.wxml
<text>{{ myName }}</text>
<button bindtap="updateNameToJames">update name to James</button>

最后

小程序因为有体积的限制,所以我希望在代码量上也尽量做到轻量和便捷,所以目前这个状态管理库并没有太多很复杂的功能,在小程序打包后所占用的体积也不到1kb,颇有点够用就好的意思。

我也已经用它开发了两款小程序,在经历了一段时间的用户使用后,我也更有信心说这个方案在小程序中是可行的。如果你有任何想法和建议,都欢迎告诉我。

项目Github: https://github.com/wwayne/minii


关于作者

Hi, 我是wwayne,是一名居住在上海的独立软件工程师,我正在开发我的新产品 https://talk-to.kim, 你可以在Github 或者专栏 一个人写代码找到我

海计划公众号
(0)
上一篇 2020/03/29 01:47
下一篇 2020/03/29 01:47

您可能感兴趣的内容

  • Chameleon基础知识教程_一套代码运行多端,一端所见即多端所见

    Chameleon基础知识教程 官方网址:https://CML.JS.org GitHub:https://github.com/didi/chameleon 简介描述:一套代码…

    2020/03/07
  • github-profile-summary小白基础_可视化GitHub概况的工具

    github-profile-summary小白基础 官方网址:https://profile-summary-for-github.com/ GitHub:https://git…

    2020/03/10
  • 为什么你应该使用 Object.is() 进行相等性比较小白教程_object菜鸟攻略

    我们都知道JavaScript是弱类型语言,在某些情况下,当与“ ==”进行相等性比较时,它特别落后。使用“ ==”进行比较可能会“将2个操作数中的一个强制转换为另一种类型然后进行比较”而产生意外结果。0 == ‘ ‘ //true
    null == undefined //true
    [1] == true //true因此Javascript提供了三等运算符

    2020/03/20
  • 蚂蚁微客零基础入门_众包,赚钱,做任务,发任务,兼职

    蚂蚁微客零基础入门 官方网址:https://wk.alipay.com 简介描述:众包,赚钱,做任务,发任务,兼职 支付宝推出蚂蚁微客这项目,给许多自由职业创造一条新的创业路子。…

    2020/03/06
  • web Socket和Socket.IO框架指南攻略_Socket入门基础知识

    HTTP无法轻松实现实时应用:● HTTP协议是无状态的,服务器只会响应来自客户端的请求,但是它与客户端之间不具备持续连接。● 我们可以非常轻松的捕获浏览器上发生的事件(比如用户点击了盒子),这个事件可以轻松产生与服务器的数据交互(比如Ajax)。但是,反过来却是不可能的:服务器端发生了一个事件,服务器无法将这个事件的信息实时主动通知它的客户端。只有在客户端

    2020/03/30
  • Js对象的增删改查基础知识入门_对象攻略教程

    Object:对象以后看到的,除了5种基本数据类型就是对象 ,JS中表示一个人的信息(name,gender,age)var name = “huangchen”;
    var gender = “男”;
    var age = 18;如果使用基本数据类型,我们所创建的变量都是独立的,不能成为一个整体, 对象属于一种复合的数据类型,在对象可以保存多个不同

    2020/03/29
  • 一致性hash算法和实现小白入门_Hash使用说明

    一致性hash算法是什么?一致性hash算法,是麻省理工学院1997年提出的一种算法,目前主要应用于分布式缓存当中。一致性hash算法可以有效地解决分布式存储结构下动态增加和删除节点所带来的问题。在Memcached、Key-Value Store、Bittorrent DHT、LVS中都采用了一致性hash算法,可以说一致性hash算法是分布式系统负载均衡

    2020/03/26
  • HTTPie入门基础教程_一个 HTTP 的命令行客户端工具

    HTTPie入门基础教程 官方网址:https://httpie.org GitHub:https://github.com/jakubroztocil/httpie 简介描述:一…

    2020/03/06
  • MobX在React Native 中的使用心得基础知识教程_跨平台指南攻略

    MobX 是一款十分优秀的状态管理库,不但书写简洁还非常高效。当然这是我在使用之后才体会到的,当初试水上车的主要原因是响应式,考虑到可能会更符合 Vue 过来的思考方式。然而其实两者除了响应式以外并没有什么相似之处。在使用过程中走了不少弯路,一部分是因为当时扫两眼文档就动手,对 MobX 机制理解得不够;其它原因是 MobX 终究只是一个库,会受限于 Rea

    2020/04/05
  • Js错误处理入门攻略_错误小白常识

    当 JavaScript 引擎执行 JavaScript 代码时,会发生各种错误:可能是语法错误,通常是程序员造成的编码错误或错别字;可能是拼写错误或语言中缺少的功能(可能由于浏览器差异);可能是由于来自服务器或用户的错误输出而导致的错误;也可能是由于许多其他不可预知的因素。那么js有没有好的可以检测错误的呢?有的,那就是:throw、try 和 catch

    2020/03/26
  • 程序员经典面试题:高并发系统,一般需要怎么做基础知识教程_面试使用帮助

    高并发系统总是那么令人着迷,比如说双十一的抢购,比如说12306的抢票,都是非常经典的高并发的例子,也是非常大的挑战。对于开发这样系统的人来说,最怕的就是突发的流量,就好比河流突发大水而引发洪涝灾害一样,突发的流量也会引起服务器奔溃。为了应对这些突发的流量,我们总需要做点什么?今天我们来介绍一下高并发的几个套路。分布式提升并发的好的办法,便是提升硬件。举个大

    2020/03/26
  • VLC菜鸟教程_视频监控直播的插件

    VLC菜鸟教程 官方网址:https://www.videolan.org/ 简介描述:视频监控直播的插件 VLC 是一款自由、开源的跨平台多媒体播放器及框架,可播放大多数多媒体文…

    2020/03/12
  • 基于Vue的验证码插件vue2-verify小白攻略_插件使用指南

    在我们Web项目开发中,验证码是一种比较常见的区分用户是计算机还是人的手段。主要是为了保证项目的安全。现在Vue开发的项目很多,基本都是前后端分离的。给大家推荐一个基于Vue比较好用的验证码插件vue2-verify。但是大家要注意一点,单纯前端的验证是不安全的,因为可以直接通过接口请求。下面雷雪松就详细的给大家介绍一下基于Vue的验证码插件vue2-ver

    2020/03/24
  • 小程序底层实现原理及一些思考小白攻略_原理新手入门

    小程序底层实现原理及一些思考两月以后,看着电脑,我回想起接到通知说要开发小程序引擎的那个下午。当时的我以为,这个小程序和其他小程序都不一样,因为它是个假的,其实是个网页。两月之后,我才发现,“噢~原来大家都是这么做的啊”。最近一直在做小程序的底层实现,过程中磕磕绊绊也多次进行架构方向上的转型,趁着周末抽空写一篇文章记录一下开发过程中遇到的问题和一些思考与决策

    2020/03/24
  • Js常用的动态效果库有那些?基础知识教程_库小白攻略

    当我想要在网上找一个简洁的 Javascript 动效库时,总是发现很多“推荐”的库都是缺乏持续维护的。经过一番研究,我收集了 11 个最好的库,你可以用在自己的项目中。另外我还添加了一些有用但是缺少持续维护的库。提示:可以用 Bit 来共享你的组件,用它们构建多个项目并与你的团队同步更改。不要重复造轮子。使用纯CSS在深入研究这些库之前,不要忘记还有纯 C

    2020/03/26
  • javascript有什么特点?基础指南_特点菜鸟知识

    JavaScript是一种属于网络的脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果。通常JavaScript脚本是通过嵌入在HTML中来实现自身的功能的。JavaScript脚本语言具有以下特点:(1)脚本语言。JavaScript是一种解释型的脚本语言,C、C++等语言先编译后执行,而JavaSc

    2020/03/22