侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

基于Proxy的小程序状态管理实现

微信(小程序)  /  管理员 发布于 3年前   296

微信小程序的市场在进一步的扩大,而背后的技术社区仍在摸索着最好的实践方案。我在帮助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/minii/blob/master/src/api/observe.js

Part2: 页面数据绑定

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

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

实现细节: https://github.com/wwayne/minii/blob/master/src/api/mapToData.js

Part3: 页面订阅更新

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

实现细节:https://github.com/wwayne/minii/blob/master/src/core.js

使用状态管理的例子

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

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

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

// stores/user.jsimport { 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.jsimport { 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{{ myName }}

最后

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

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

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

您可能感兴趣的文章:

  • 微信小程序云开发 搭建一个管理小程序
  • 小程序封装wx.request请求并创建接口管理文件的实现
  • 利用Webpack实现小程序多项目管理的方法
  • 小程序登录态管理的方法示例
  • 微信小程序使用gitee进行版本管理
  • 微信小程序 http请求的session管理


  • 上一条:
    微信小程序页面间跳转传参方式总结
    下一条:
    比较Ajax的三种实现及JSON解析
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 小程序开发之跳转微信直播示例api(0个评论)
    • 在uni_app中开发小程序之常用功能示例代码汇总(0个评论)
    • 小程序开发之多端框架:taro(0个评论)
    • 微信小程序前端使用七牛云官方SDK上传七牛云代码示例(0个评论)
    • 百度小程序审核未通过,真机审核存在点击返回键退出小程序...解决方式之一tabBar(0个评论)
    • 近期文章
    • windows系统中安装FFMpeg及在phpstudy环境php7.3 + php-ffmpeg扩展的使用流程步骤(0个评论)
    • 在go语言中对浮点的数组、切片(slice)进行正向排序和反向排序(0个评论)
    • 在go语言中对整数数组、切片(slice)进行排序和反向排序(0个评论)
    • 在go语言中对字符串数组、切片(slice)进行排序和反向排序(0个评论)
    • 最新国内免注册ChatGPT体验站_ChatGPT镜像站访问链接地址2023/3/28持续更新(0个评论)
    • 在Laravel项目中的实现无密码认证之:发送邮箱链接授权(0个评论)
    • 在go语言中使用GoRoutines实现高性能并发批量调用api示例(0个评论)
    • Docker撤回受争议的收费方案,又可以继续使用docker了(0个评论)
    • 在go语言生成唯一ID之SnowFlake算法(0个评论)
    • ChatGPT再出新功能,推出插件功能,能联网、搜索了(0个评论)
    • 近期评论
    • 博主 在

      2023年国务院办公厅春节放假通知:1月21日起休7天中评论 @ xiaoB 你只管努力,剩下的叫给天意;天若有情天亦老,..
    • xiaoB 在

      2023年国务院办公厅春节放假通知:1月21日起休7天中评论 会不会春节放假后又阳一次?..
    • BUG4 在

      你翻墙过吗?国内使用vpn翻墙可能会被网警抓,你需了解的事中评论 不是吧?..
    • 博主 在

      go语言+beego框架中获取get,post请求的所有参数中评论 @ t1  直接在router.go文件中配就ok..
    • Jade 在

      如何在MySQL查询中获得当月记录中评论 Dear zongscan.com team, We can skyroc..
    • 2017-10
    • 2018-01
    • 2020-03
    • 2021-06
    • 2021-10
    • 2022-03
    • 2023-02
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客