【微信小程序】——Mobx全局数据共享和分包
微信小程序开发
- 全局数据共享
- 1. 全局数据共享介绍
- 2. 小程序中的全局数据共享方案
- 3. 安装Mobx相关的包
- 4. 创建Mobx中Store实例
- 5. 页面中使用Store成员
- 6. 组件中使用Store成员
- 分包
- 1. 基础概念
- 2. 使用分包
- 3. 独立分包
- 4. 分包预下载
- 案例:自定义tabBar
- 1.案例效果
- 2. 实现步骤
全局数据共享
1. 全局数据共享介绍
全局数据共享即状态管理
,是为了解决组件之间数据共享的问题,将数据统一存到Store
仓库里,各组件都能直接访问仓库内的数据,避免了各组件间频繁的数据传递等问题。
类似的有Vue
中的Vuex
,Redux
,Mobx
等。
不使用Store
:
使用Store
:
2. 小程序中的全局数据共享方案
在小程序中,可使用mobx-miniprogram
配合mobx-miniprogram-bindings
实现全局数据共享。
mobx-miniprogram
:用来创建Store
实例对象mobx-miniprogram-bindings
:用来把Store
中的共享数据或方法,绑定到组件或页面中使用
3. 安装Mobx相关的包
npm install --save mobx-miniprogram mobx-miniprogram-bindings
注意:安装完成后记得重新构建npm
4. 创建Mobx中Store实例
项目根目录下创建store文件夹用于存放Mobx相关的JS文件
创建store.js用来创建store实例
store.js:
//在这个JS文件里,专门来创建Store的实例对象import { action, observable } from 'mobx-miniprogram'
export const store = observable({//数据字段numA: 1,numB: 2,//计算属性:当numA或numB变化时,自动更新sum的值get sum() {return this.numA + this.numB},// actions 方法,用来修改store中的数据updateNum1: action(function (step) {this.numA += step}),updateNum2: action(function (step) {this.numB += step})
})
注意:
- 计算属性的值是只读的,不能也不需要对其进行手动修改
- 直接修改store里的数据可能会带来危险,所以一般在actions方法里修改store里的数据
5. 页面中使用Store成员
5.1 在页面的JS中写入以下代码:
// 页面的.js文件
import { createStoreBindings } from "mobx-miniprogram-bindings";
import { store } from "../../store/store";
Page({/*** 页面的初始数据*/data: {},/*** 生命周期函数--监听页面加载*/onLoad: function (options) {this.storeBindings = createStoreBindings(this,{store,fields:['numA','numB','sum'],actions:['updateNum1']})},/*** 生命周期函数--监听页面卸载*/onUnload: function () {this.storeBindings.destroyStoreBindings()},
})
代码分析:
- 引入
mobx
的createStoreBindings
方法和我们创建的store
实例:
import { createStoreBindings } from "mobx-miniprogram-bindings";
import { store } from "../../store/store";
createStoreBindings
方法可以将Store
中的数据或方法绑定到我们的页面中
- 在页面加载时,绑定
Store
:
onLoad: function (options) {this.storeBindings = createStoreBindings(this,{store,fields:['numA','numB','sum'],actions:['updateNum1']})},
createStoreBindings
方法接收两个参数,一个是this
代表当前页面的实例,第二参数是配置对象,包含三个属性:
store
代表数据源fields
代表我们需要将哪些字段绑定到我们的页面中actions
代表我们需要将哪些方法绑定到我们的页面中
createStoreBindings
的调用有一个返回值,我们将这个返回值挂载到了当前页面上作为一个自定义属性storeBindings
而存在,这样我们就可以在页面卸载时利用storeBindings
来清理挂载的Store实例
- 在页面卸载时接触绑定的
Store
:
onUnload: function () {this.storeBindings.destroyStoreBindings()},
调用
destroyStoreBindings
方法即可进行清理Store
5.2 在页面上使用Store
数据
页面的.wxm
结构:
<view>
{{numA}} +{{numB}} = {{sum}}
<button type="primary" bindtap="btn1" data-step="{{1}}">numA+1</button>
<button type="primary" bindtap="btn1" data-step="{{-1}}">numA-1</button>
</view>
在页面的JS中添加按钮tap事件的处理函数:
btn1(e){this.updateNum1(e.target.dataset.step)
}
6. 组件中使用Store成员
6.1 在组件的JS中写入以下代码:
// components/numbers/numbers.js
import {storeBindingsBehavior} from "mobx-miniprogram-bindings"
import {store} from '../../store/store'
Component({//通过storeBindingsBehavior来实现自动绑定behaviors:[storeBindingsBehavior],storeBindings:{//指定要绑定的Storestore,fields:{// 绑定字段的第1种方式numA:()=>store.numA,// 绑定字段的第2种方式numB:(store)=>store.numB,// 绑定字段的第3种方式sum:'sum'},actions:{updateNum2:'updateNum2'}},/*** 组件的属性列表*/properties: {},/*** 组件的初始数据*/data: {},/*** 组件的方法列表*/methods: {}
})
6.2 在组件上使用Store
数据
组件的.wxm
结构:
{{numA}}+{{numB}}={{sum}}
<button type="primary" bindtap="Cbtn1" data-step="{{1}}">CnumA+1</button>
<button type="primary" bindtap="Cbtn1" data-step="{{-1}}">CnumA-1</button>
在组件JS中的methods
方法列表中加入添加按钮tap事件的处理函数:
Cbtn1(e){this.updateNum2(e.target.dataset.step)
},
分包
1. 基础概念
什么是分包?
分包指的是把一个完整的小程序项目,按照需求划分为不同的之包,在构建时打包成不同的分包,用户在使用时按需进行加载。分包的好处?
- 可以优化小程序首次启动的下载时间
- 在多团队共同开发时可以更好的解耦协作
分包前项目的构成
分包前,小程序项目中所有的页面和资源都被打包到了一起,导致整个项目体积过大,影响小程序首次启动的下载时间。
分包后项目的构成
分包后,小程序项目由1个主包+多个分包组成:- 主包:一般只包含项目的启动页面或TabBar页面、以及所有分包都需要用到的一些公共资源
- 分包:只包含和当前页面有关的页面和私有资源
分包的加载规则
- 在小程序启动时,默认会下载主包并启动主包内页面
- tabBar页面需要放到主包中
- 当用户进入分包内某个页面时,客户端会把对应的分包下载下来,下载完成后再进行展示
- 非tabBar页面可以按照功能的不同, 划分为不同的分包之后,进行按需下载
- 在小程序启动时,默认会下载主包并启动主包内页面
分包的体积限制
目前,小程序分包的大小有以下两个限制:- 整个小程序所有分包大小不超过16M(主包+所有分包)
- 单个分包/主包大小不能超过2M
2. 使用分包
- 配置方法
app.json中添加以下分包的配置,保存后会自动生成相应的文件:
//app.json"subpackages": [{"root":"pkgA","pages": ["pages/cat/cat","pages/dog/dog"]},{"root":"pkgB","pages": ["pages/apple/apple"]}],
- 查看分包的体积大小
- 打包原则
小程序会按
subpackages
的配置进行分包,subpackages
之外的目录将被打包到主包中主包也可以有自己的
pages
(即最外层的pages
字段)"pages":["pages/home/home","pages/message/message","pages/contact/contact"],
tabBar
页面必须在主包内
如上代码即是tabBar
页面的配置,配置到了主包的pages
里分包之间不能互相嵌套
- 引用原则
- 主包 无法引用分包内的私有资源
- 分包之间不能相互引用私有资源
- 分包可以引用主包内的公共资源
3. 独立分包
什么是独立分包
独立分包本质上也是分包,只不过它比较特殊,可以独立于主包和其它分包而单独运行。
独立分包和普通分包的区别
最主要的区别:是否依赖于主包才能运行- 普通分包必须依赖于主包才能运行
必须先进入主包才能跳到普通分包
- 独立分包可以在不下载主包的情况下,独立运行
- 普通分包必须依赖于主包才能运行
独立分包的应用场景
开发者可以按需,将某些具有一定功能独立性的页面配置到独立分包中,原因如下:- 当小程序从普通的分包页面启动时,需要首先下载主包
- 而独立分包不依赖主包即可运行,可以很大程度上提升分包页面的启动速度
注意:一个小程序中可以有多个独立分包
独立分包的配置方法
独立分包的目录结构于普通分包一样,独立分包只需在JSON
配置中通过independent
进行声明://app.json //pkgB设置为独立分包 "subpackages": [{"root":"pkgA","name": "p1","pages": ["pages/cat/cat","pages/dog/dog"]},{"root":"pkgB","name": "p2","pages": ["pages/apple/apple"],"independent": true}],
独立分包的引用原则
独立分包和普通分包以及主包之间,是相互隔绝的,不能相互引用批次的资源!例如:- 主包无法引用独立分包内的私有资源
- 独立分包之间,不能相互引用私有资源
- 独立分包和普通分包之间,不能相互引用私有资源
- 特别注意:独立分包中不能引用主包内的公共资源
4. 分包预下载
分包预下载指的是:在进入小程序的某个页面时,由框架自动预下载可能需要的分包
,从而提升进入后续分包页面时的启动速度。
配置分包的预下载
预下载分包的行为,会在进入指定的页面时触发。在app.json
中,使用preloadRule
节点定义分包的预下载规则,示例代码如下:
"preloadRule": {"pages/contact/contact":{"packages": ["p1"],"network": "all"}},"subpackages": [{"root":"pkgA","name": "p1","pages": ["pages/cat/cat","pages/dog/dog"]},{"root":"pkgB","name": "p2","pages": ["pages/apple/apple"],"independent": true}],
上述代码配置的是打开
pages/contact/contact
页面时,在任意网络环境下都会预下载p1
分包。打开
pages/contact/contact
页面时查看调试器控制台会有正在预下载p1
和预下载成功的提示:
分包预下载的限制
同一个分包的页面享有共同的预下载大小限额2M,例如:
案例:自定义tabBar
1.案例效果
在此案例中,用到的主要知识点如下:
- 自定义组件
- Vant组件库
- MobX数据共享
- 组件样式隔离
- 组件数据监听器
- 组件的behaviors
- Vant 样式覆盖
2. 实现步骤
配置信息
在app.json
文件的tabBar
中添加"custom": true
同时保留list里的配置项:"tabBar": {"custom": true,"list": [{"pagePath": "pages/home/home","text": "首页","iconPath": "/images/tabs/home.png","selectedIconPath": "/images/tabs/home-active.png"},{"pagePath": "pages/message/message","text": "消息","iconPath": "/images/tabs/message.png","selectedIconPath": "/images/tabs/message-active.png"},{"pagePath": "pages/contact/contact","text": "联系我们","iconPath": "/images/tabs/contact.png","selectedIconPath": "/images/tabs/contact-active.png"}]},
添加tabBar代码文件
项目根目录创建custom-tab-bar
文件夹,然后右键此文件夹新建Component
,起名为index
此时页面底部显示:
表示添加tabBar代码文件和配置成功编写tabBar代码
custom-tab-bar/index.wxml
:<!--使用vant的van-tabbar 组件--> <van-tabbar active="{{ active }}" bind:change="onChange" active-color="#13A7A0"><van-tabbar-item wx:for="{{list}}" wx:key="index" info="{{item.info?item.info:''}}"><imageslot="icon"src="{{ item.iconPath }}"mode="aspectFit"style="width: 25px; height: 25px;"/><imageslot="icon-active"src="{{ item.selectedIconPath }}"mode="aspectFit"style="width: 25px; height: 25px;"/>{{item.text}}</van-tabbar-item> </van-tabbar>
custom-tab-bar/index.wxss
:/* 修改van-tabbar样式进行样式覆盖 */.van-tabbar-item {--tabbar-item-margin-bottom:0; }
custom-tab-bar/index.js
:// custom-tab-bar/index.js import { storeBindingsBehavior } from "mobx-miniprogram-bindings" import { store } from '../store/store' Component({//在自定义组件中使用 Vant Weapp 组件时,需开启styleIsolation: 'shared'才能进行样式覆盖options: {styleIsolation: 'shared'},//通过storeBindingsBehavior来实现自动绑定behaviors: [storeBindingsBehavior],storeBindings: {//指定要绑定的Storestore,fields: {sum: 'sum',active:'active'},actions:{changeActive:'changeActive'},},/*** 数据监听器*/observers:{"sum":function (val) {// 赋值操作this.setData({'list[1].info':val})}},/*** 组件的属性列表*/properties: {},/*** 组件的初始数据*/data: {list: [{pagePath: "/pages/home/home",text: "首页",iconPath: "/images/tabs/home.png",selectedIconPath: "/images/tabs/home-active.png"}, {pagePath: "/pages/message/message",text: "消息",// 消息数量info: 0,iconPath: "/images/tabs/message.png",selectedIconPath: "/images/tabs/message-active.png"}, {pagePath: "/pages/contact/contact",text: "联系我们",iconPath: "/images/tabs/contact.png",selectedIconPath: "/images/tabs/contact-active.png"}]},/*** 组件的方法列表*/methods: {onChange(event) {// event.detail为选中项索引// 调用store里的修改tabBar选中项索引的函数this.changeActive(event.detail)// 手动实现页面跳转wx.switchTab({url: this.data.list[event.detail].pagePath,})},} })
store/store.js
://在这个JS文件里,专门来创建Store的实例对象import { action, observable } from 'mobx-miniprogram' export const store = observable({//数据字段numA: 1,numB: 2,// tabBar选中项索引active: 0,//计算属性:当numA或numB变化时,自动更新sum的值get sum() {return this.numA + this.numB},// actions 方法,用来修改store中的数据updateNum1: action(function (step) {this.numA += step}),updateNum2: action(function (step) {this.numB += step}),changeActive: action(function (index) {this.active = index}) })
详细步骤,可以参考小程序官方文档:
https://developers.weixin.qq.com/miniprogram/dev/framework/ability/custom-tabbar.html
【微信小程序】——Mobx全局数据共享和分包相关推荐
- 【微信小程序】全局数据共享
1.1.什么是全局数据共享 全局数据共享(又叫做:状态管理)是为了解决组件之间数据共享的问题.开发中常用的全局数据共享方案有:Vuex.Redux.MobX等. 1.2.小程序中的全局数据共享方案 在 ...
- uni开发微信小程序解决全局分享分销问题
uni开发微信小程序解决全局分享分销问题 1. 需求 1.小程序内每个页面都要打开胶囊分享按钮并实现分销 2.分享功能应该是在用户登录之后才予以打开 3.不想做在每个页面都写分享钩子的傻逼操作 2.实 ...
- uniapp 微信小程序配置全局主题色、实现动态修改主题色
前言: 本文的实现目标是全局配置小程序的整体主题色,包括本地图标的色调.第一步实现在本地可以统一修改整体的主题色以及本地图标的颜色:第二步实现通过后台接口动态调整小程序前端的整体主题色以及本地图标颜色 ...
- 微信小程序 蓝牙 长数据包 分包拆包
https://www.jianshu.com/p/de7bd0093c43 关于 微信小程序蓝牙 分包发送 及 多包发送 不返回问题 关于分包发送 20字节分包,微信小程序支持多于20字节发送.但是 ...
- 微信小程序:全局路由登录拦截和分享参数过长的问题
文档 微信小程序开发文档-获取不限制的小程序码 微信小程序没有提供路由拦截系统,我们可以自己通过应用首页作为入口,拦截所有页面 大致思路如下: 登录拦截 用户进入首页后,判断是否登录,或者执行其他全局 ...
- AOP方式捕获和处理微信小程序前端全局异常
原因 这几天,公司开发的小程序有部分用户用户打开咨询列表页显示空白,我们查后台日志没有错误.最让人头疼的是,这种前端显示不正确,只是在某些机型上才出现,我们的测试人员无法复现该问题.无法复现,又没有错 ...
- 微信小程序API全局域名配置设置
目前来说,大部分的微信小程序都是跟后台进行交互,通过API请求数据,所以API请求地址的管理就显得比较重要了,如果是在wx.request的时候采取写url地址,后面要是地址修改,就要到每个请求的地方 ...
- 微信小程序——使用npm包、分包
使用npm包 支持与限制 不支持依赖于 Node.js 内置库的包 不支持依赖于浏览器内置对象的包 不支持依赖于 C++ 插件的包 vant weapp 安装 初始化文件 npm init -y np ...
- 微信小程序:全局状态管理mobx-miniprogram(类似store)
一.背景 需求是,每个播放视频的地方都有控制是否静音的按钮,点某一个静音则全局静音. 问题:由于我的每个小卡片都是一个组件,本质是每个页面引几次同一个组件,刚开始用的setData,但是这样每个卡片中 ...
最新文章
- TVM vs TensorRT比较
- 京东方剑指物联网领域
- 5.29 相约杭州!云原生 Meetup 第二期杭州站报名开启!
- linux rm(remove) 命令详解
- c语言中指针中 - 和 。的区别?
- 什么是二维数组?二维遍历?Java二维数组制作图片迷宫 使用如鹏游戏引擎制作窗口界面 附带压缩包下载,解压后双击start.bat启动...
- 如何有效的在 LINQ 查询中处理异常?
- java 减少内存_java-减少应用程序内存占用
- 【Vue2.0】—props 配置(十三)
- CodeReview技巧和规范
- 查计算机主板,怎么查看自己电脑的主板型号是什么?主板型号查询检查方法
- 2.1、ROS+PX4仿真---定点飞行控制
- Codevs 侦探推理
- Apache的Order Allow,Deny 详解
- C语言入门最基础教学(编译器下载)
- 【视点】说好的光伏政策严肃性呢?
- Flink Record has Long.MIN_VALUE timestamp (= no timestamp marker). Is the time characteristic
- 无线局域网技术(二)无线传输技术基础
- 漫谈MCMC与Gibbs采样(三)—— 有趣的马尔科夫链
- Python 实现中国地图可视化