基于Proxy的小程序状态管理

2019-06-14 admin

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

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

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

基于Proxy的状态管理实现

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

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

Part1: 监听数据变化

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

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

实现细节: https://github.com/wwayne/min…

Part2: 页面数据绑定

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

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

实现细节: https://github.com/wwayne/min…

Part3: 页面订阅更新

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

实现细节:https://github.com/wwayne/min…

使用状态管理的例子

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

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以及专栏 一个人写代码

[转载]原文链接:https://segmentfault.com/a/1190000019474324

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-67240.html

文章标题:基于Proxy的小程序状态管理

相关文章
js性能优化 如何更快速加载你的JavaScript页面
确保代码尽量简洁 不要什么都依赖JavaScript。不要编写重复性的脚本。要把JavaScript当作糖果工具,只是起到美化作用。别给你的网站添加大量的JavaScript代码。只有必要的时候用一下。只有确实能改善用户体验的时候用一下。 ...
2015-11-12
10个强大的纯CSS3动画案例分享
我们的网页外观主要由CSS控制,编写CSS代码可以任意改变我们的网页布局以及网页内容的样式。CSS3的出现,更是可以让网页增添了不少动画元素,让我们的网页变得更加生动有趣,并且更易于交互。本文分享了10个非常炫酷的CSS3动画案例,希望大家...
2015-11-16
v-charts | 饿了么团队开源的基于 Vue 和 ECharts 的图表工具
在使用echarts生成图表时,经常需要做繁琐的数据类型转化、修改复杂的配置项,v-charts的出现正是为了解决这个 痛点。基于Vue2.0和echarts封装的v-charts图表组件,只需要统一提供一种对前后端都友好的数据格式 设置简...
2018-05-24
从2014年的发展来展望JS的未来将会如何
&lt;font face=&quot;寰�杞�闆呴粦, Arial, sans-serif &quot;&gt;2014骞达紝杞�浠惰�屼笟鍙戝睍杩呴€燂紝鍚勭�嶈��瑷€灞傚嚭涓嶇┓锛屼互婊¤冻鐢ㄦ埛涓嶆柇鍙樺寲鐨勯渶姹傘€傝繖浜涜��...
2015-11-12
12个你未必知道的CSS小知识
虽然CSS并不是一种很复杂的技术,但就算你是一个使用CSS多年的高手,仍然会有很多CSS用法/属性/属性值你从来没使用过,甚至从来没听说过。 1.CSS的color属性并非只能用于文本显示 对于CSS的color属性,相信所有Web开发人员...
2015-11-12
ajax为什么令人惊异?ajax的优缺点
使用Ajax的最大优点,就是能在不更新整个页面的前提下维护数据。这使得Web应用程序更为迅捷地回应用户动作,并避免了在网络上发送那些没有改变的信息。 Ajax不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。就像DHT...
2015-11-12
HTML5的5个不错的开发工具推荐
HTML5规范终于在今年正式定稿,对于从事多年HTML5开发的人员来说绝对是一个重大新闻。数字天堂董事长,DCloud CEO王安也发表了文章,从开发者和用户两个角度分析了HTML对两个人群的优势。其实,关于HTML5的开发工具,我们以往的...
2015-11-12
JavaScript教程:JS中的原型
Keith Peters 几年前发表的一篇博文,关于学习没有“new”的世界,其中解释了使用原型继承代替构造函数。两者都是纯粹的原型编码。 标准方法(The Standard Way) 一直以来,我们学习的在 JavaScript 里创建对...
2015-11-12
零基础-5小时开发一个electron应用-[实践]
一、背景 三、技能升级 ​ 明明可以用颜值取胜,非要靠才华?不对,明明可以用代码搞定,非要搞设计?步入正题,正好最近对electron比较感兴趣,又是要做工具,那就直接怼 1.electron介绍 ​ electron最开始不叫这个名字,叫...
2017-12-26
JS中的语音合成——Speech Synthesis API
JS中的语音合成——Speech Synthesis API 简介 HTML5中和Web Speech相关的API实际上有两类,一类是“语音识别(Speech Recognition)”,另外一个就是“语音合成(Speech Synthes...
2018-05-17
回到顶部