1.全局数据共享介绍
全局数据共享也叫作状态管理,主要用于组件间数据共享问题的处理.实际开发中常用的实现方案:vuex、redux、mobx,本文主要介绍mobx.
2.准备工作
mobx需要引入两个npm包:
mobx-miniprogram:用于创建store实例对象
mobx-miniprogram-bindings:用于将store中数据或是方法绑定到组件或是页面中.
安装命令(项目所在目录下执行):
npm install --save mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1
安装完成之后,如果项目中存在miniprogram-npm文件夹则删除之后重新构建.构建完成之后重新生成的miniprogram-npm中会出现mobx-miniprogram 和mobx-miniprogram-bindings,构建方式以及构建完成新增文件夹如下:
3.使用说明
第一步创建store对象用于存储共享的数据或是方法;
第二步将store数据或是方法绑定到页面或是组件中;
第三步页面或是组件中使用全局共享数据或是方法.
下面以案例的形式分别说明如何在页面或是组件中进行全局数据共享.
3.1 page页面进行全局数据共享
示例说明:
定义num1、num2、sum12,sum12为num1和num2的和,创建两个按钮,分别实现点击之后对num1进行加2或是减2的操作.同时sum12能随着num1值的变化同时进行改变.
创建store对象:
根目录中创建store文件夹,然后创建store.js文件.store.js中内容如下:
// 导入mobx-miniprogram中的observable方法 import {observable} from 'mobx-miniprogram'; // 调用observable方法创建store对象实例并导出进行共享 export const store=observable({ // 定义数据 num1:1, num2:2, // 计算数据属性 get sum12() { console.log("sum12方法执行") return this.num1+this.num2 }, // 更新方法1用于修改num1的值 updateNum1:action(function(step){ this.num1+=step; }), // 更新方法2用于修改num2的值 updateNum2:action(function(step){ this.num2+=step; }) })
index.js中进行页面绑定store对象数据和方法:
// 导入创建store绑定方法 import {createStoreBindings} from 'mobx-miniprogram-bindings' // 导入store实例对象 import {store} from '../../store/store' Page({ // 页面加载设置store绑定成员信息 onLoad:function(){ this.storeBindings=createStoreBindings(this,{ store, fields:['num1','num2','sum12'], actions:['updateNum1'] }) }, // 页面卸载时清理处理 onUnload:function(){ this.storeBingds=this.destroyStoreBindings() }, // 按钮点击时触发的方法 addNum(e){ // 执行修改num1方法并按照指定步长step进行相加 this.updateNum1(e.target.dataset.step) } })
index.wxml页面中使用共享数据或是方法:
<view>{{num1}} + {{num2}} = {{sum12}}</view> <van-button type="primary" bindtap="addNum" data-step='{{2}}'>num1加2</van-button> <van-button type="warning" bindtap="addNum" data-step='{{-2}}'> num1减2</van-button>
3.2 component组件进行全局数据共享
示例说明:
定义num1、num2、sum12,sum12为num1和num2的和,创建两个按钮,分别实现点击之后对num2进行加3或是减3的操作.同时sum12能随着num2值的变化同时进行改变.创建test组件在index页面进行引用.
创建store对象同上示例,此处不再重述;
test.js中绑定store对象的数据或是方法:
import {storeBindingsBehavior} from 'mobx-miniprogram-bindings' import {store} from '../../store/store' Component({ behaviors:[storeBindingsBehavior], // 使用mobx-miniprogram-bindings中storeBindingsBehavior进行数据共享 storeBindings:{ store, fields:{ // 绑定数据,前者为组件中数据名,后者为store中定义的数据名,两者可不一致 num1:'num1', num2:'num2', sum12:'sum12' }, actions:{ // 绑定方法,前者为组件中方法名,后者为store中定义的方法名,两者可不一致 updateNum2:'updateNum2' } } })
test.wxml中调用store数据或是方法:
<view>{{num1}} + {{num2}} = {{sum12}}</view> <van-button type="primary" bindtap="addNum" data-step='{{3}}'>num2加3</van-button> <van-button type="warning" bindtap="addNum" data-step='{{-3}}'> num2减3</van-button>
index.wxml中引入test组件:
<view>{{num1}} + {{num2}} = {{sum12}}</view> <van-button type="primary" bindtap="addNum" data-step='{{2}}'>num1加2</van-button> <van-button type="warning" bindtap="addNum" data-step='{{-2}}'> num1减2</van-button> <view>+++++++++++++++++++++++++++++++++++++</view> <test></test>
最终实现效果如下:
3.3综合案例:点击按钮实现自定义tabbar消息数同步变化
案例说明:上篇文章uni-app入门:自定义tabbar介绍了如何自定义tabbar,此处在自定义tabbar的基础上介绍全局数据共享.pages/index页面中定义一参数num,初始化数据为2,点击按钮实现5操作,并将加5之后的num同步到tabbar的数字徽标上面.
实现思路说明:自定义tabbar上的数字徽标与pages/index页面中的num显示保持一致即可实现同步变化.可以将num作为全局数据共享的字段,分别绑定pages/index、自定义tabbar组件中。然后点击按钮实现num+5.
store/store.js中创建store对象(初始化num、定义num+5方法):
import {observable,action} from 'mobx-miniprogram' export const store=observable({ num:2, // 初始化num // 变更num值,此处按照5进行增加 updateNum:action(function(step){ this.num+=step; }) })
pages/index/index.js中绑定store中的num以及num+5方法:
// index.js import {createStoreBindings} from 'mobx-miniprogram-bindings' import {store} from '../../store/store' Page({ // 点击事件函数 addNum:function(event){ // 点击事件触发全局共享方法逻辑 this.updateNum(event.target.dataset.numinterval); // 此处实现num+5只能对当前页面num数据实现变化 // this.setData({ // num:this.data.num+event.target.dataset.numinterval // }) }, onLoad() { // 绑定共享数据 this.storeBindings=createStoreBindings(this, { store, fields:['num'], actions:['updateNum'] } ) }, onUnload(){ this.storeBindings.destoryStoreBindings(); } })
点击按钮实现num的加5的实现逻辑要放到全局数据处理中,这样才能保证全局共享数据中的num实现变化,如果在按钮的点击事件中进行num+5只能对当前页面的num值做出变化.
page/index/index.wxml:
<view>当前数字:{{num}}</view> <van-button type="primary" bindtap="addNum" data-numInterval='{{5}}'>数字加5</van-button>
自定义tabbar组件index.js中绑定store对象的num:
// custom-tab-bar/index.js import {storeBindingsBehavior} from 'mobx-miniprogram-bindings' import {store} from '../store/store' Component({ behaviors:[storeBindingsBehavior], // 映射参数绑定 storeBindings:{ store, fields:{ // 组件字段:store字段 num:()=>store.num //方式一 //num:(store)=>store.num // 方式二 // num:'num' .// 方式三 }, // 映射方法绑定 actions:{ // 组件方法:store方法 } }, data: { info:3, active: 0, icon: { normal: 'https://img.yzcdn.cn/vant/user-inactive.png', active: 'https://img.yzcdn.cn/vant/user-active.png', }, "list": [{ "pagePath": "/pages/index/index", "text": "首页" }, { "pagePath": "/pages/logs/logs", "text": "搜索" }, { "pagePath": "/pages/mine/mine", "text": "我的" }] }, /** * 组件的属性列表 */ properties: { }, /** * 组件的方法列表 */ methods: { } } })
自定义tabbar组件index.wx中数字徽标映射num:
van-tabbar active="{{ active }}" bind:change="onChange"> <van-tabbar-item info="{{num}}"> <image slot="icon" src="{{ icon.normal }}" mode="aspectFit" style="width: 30px; height: 18px;" /> <image slot="icon-active" src="{{ icon.active }}" mode="aspectFit" style="width: 30px; height: 18px;" /> 自定义 </van-tabbar-item> <van-tabbar-item icon="search">标签</van-tabbar-item> <van-tabbar-item icon="setting-o">标签</van-tabbar-item> </van-tabbar>