关闭

基于Proxy的小程序状态管理

时间: 2019-06-14阅读: 792标签: 小程序

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

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

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



基于Proxy的状态管理实现

Proxy在小程序中已经得到了足够好的支持,目前并没有发现在任何iPhone或者Android上不能使用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 或者专栏 一个人写代码找到我


站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/3700

关闭

小程序 showLoading与showToast不能共存

loading与toast一般不能同时引用,所以一般先把hideloading了,再执行showtoast,之前把hideloading加到了complete中,所以toast就一直出问题

Mpx 小程序框架技术揭秘

与目前业内的几个小程序框架相比较而言,mpx 开发设计的出发点就是基于原生的小程序去做功能增强。所以从开发框架的角度来说,是没有任何“包袱”,围绕着原生小程序这个 core 去做不同功能的 patch 工作

了解小程序

顾名思义,「小程序」本质上与我们平常经常使用的 app 和操作系统一样,都是一段电脑程序。你可以将小程序理解为「运行在微信上的 app」。与普通的 app 不同的是,小程序的语言使用网页前端的技术栈

小程序多余文本省略号显示

如何在 wxml 页面中截取数据?取数据想必大家都会,不就是 substring 吗?但是这种方法在 wxml 页面中是无效的。那还有 css 啊,不一样可以做到吗?但是个人觉得 css 复用性太差,暂不考虑。

小程序开发注意事项_我的第一个小程序

业余时间学习了下小程序开发,整理一篇关于小程序开发需要注意的事项:后端接口域名必须使用https、不能直接进行dom节点操作、尽量使用es6的箭头函数、原生的组件层级是最高的等

小程序获取用户信息

其实获取用户信息,一种是获取权限的,一种是不用获取权限,前者获取到的信息更多,包含一些敏感信息,包括给getaccessToken接口需要传的参数,后者就是简单获取一些头像、昵称等信息

小程序自定义tabbar占位问题

针对于小程序中自定义tabbar问题,有多种自定义方式。其中之一就是需要将原先系统自带的tabbar隐藏,调用,就是在小程序底部原先放置tabbar的内容会出现空白,仍然会出现占位问题。

小程序框架_推荐多款高质量的小程序框架组件

小程序到底有多火,看看目前推出的开源框架以及组件库就知道了。由于小程序开发的火爆,大家都在致力于探索如何更好的,更加高效的开发小程序,以至于很多公司都贡献了小程序开源框架和组件库。 如: mpvue、Tina.js、Taro、wepy、weweb、touchwx

微信小程序之程序、页面注册及生命周期

微信小程序生命周期函数:onLoad: 页面加载。onShow: 页面显示每次打开页面都会调用一次。onReady: 页面初次渲染完成,onHide: 页面隐藏,onUnload: 页面卸载。在小程序中所有页面的路由全部由框架进行管理

优雅解决微信小程序授权登录需要button触发

聊一聊最近的一个项目,这个项目是一个收书、售书的小程序,有商城、专栏、信息发布论坛等功能。虽然不是面向所有用户,但要求无论用户是否授权都皆可使用,但同时也要求部分功能对不授权的用户限制开放。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!