使用watch在微信小程序中实现全局状态共享

问题

在之前开发微信小程序的时候,获取用户信息、openid还有地理位置这些信息的时候,都是采用Promise的方式异步获取,但是这样的话在页面和App.js中都获取就可能造成请求重复的问题。

比如为了在每个页面都能获取到这些共享信息,都会选择在App.js中进行获取,然后在页面级进行获取,这两次获取的时间间隔较小时就可能导致前一个请求还未获取到数据,后一个请求就会再次进行获取,这样就产生了两次请求。

还有一个问题就是书写麻烦(虽然也能通过async await简化),比如

onLoad() {
 app.getUserInfo()
 .then(userInfo => {

 }).catch(err => { /* 错误处理 */ });

 // 如果同时需要userInfo和openid,可能就是如下形式:
 Promise.all([app.getUserInfo(), app.getOpenid()])
 .then(res => {

 }).catch(err => { /* 错误处理 */ });
}

正好周末的时候突然想到了vue的watch语法,利用一些相关的知识,就可以解决这个麻烦的问题了。

解决思路

双向绑定

vue的双向绑定原理,3.0将会采用Proxy监听数据变化,不过考虑到小程序这边的Proxy兼容性我不知道,所以采用了2.0的Object.defineProperty来监听数据的变化。

主要还是拦截设置的操作,在进行赋值时,将新旧值通知至监听者。

观察者模式

在页面级的onLoad监听app.globalData各个键名的事件,而在app.js的onLoad中则使用Object.defineProperty重新定义app.globalData,这样一旦app.globalData相应的键值发生了变化,就会通知监听的页面该值发生了变化。

模块化的引用

观察者模式导出的是一个对象(类实例),而不是一个类,所以在导入的时候这个对象是共享的,就可以通过这个对象将app.js和其他页面联系起来。

至于模块加载的实质,ES6模块加载的机制,与CommonJS模块完全不同。感兴趣的可以去看看这个

封装Page

小程序的Page函数本身是不支持watch,但是我们可以自定义一个函数,进行参数合并就可以了。

在页面onLoad时先遍历watch属性,对app.globalData进行监听,可以参考vue的watch用法。

页面onUnload时就会进行销毁,此时也应该取消监听,这些我都封装过了,不用手动处理了。

有了这些思路,用不了多久,一个雏形就出来了,经过手动测试,感觉没什么问题,我就发布到npm了,大家感兴趣的可以安装体验一下。

安装

npm i wx-watch -S --production

使用

// app.js
var { watchData, } = require('/miniprogram_npm/wx-watch/index.js');

App({
 onLaunch() {
 this.watchData(); /* 监听this.globalData的变化,并触发事件,其他页面监听的值必须在globalData中预先定义,否则无法监听 */
 },
 watchData,
 globalData: {
 userInfo: null,
 }
});

// 其他需要监听globalData的页面.js
var { getPage } = require('../../miniprogram_npm/wx-watch/index.js');
const app = getApp();

/**
 * getPage(页面参数,app) app必传,因为封装的时候访问不到,就只能传参了
*/
getPage({
 watch: {
 userInfo(userInfo, oldUserInfo) {
 console.log(`来自app.glodalData的userInfo`);
 }
 },
 // 其他参数
}, app)

github:  github.com/ma125120/wx

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。

(0)

相关推荐

  • 微信小程序设置全局请求URL及封装wx.request请求操作示例

    本文实例讲述了微信小程序设置全局请求URL及封装wx.request请求操作.分享给大家供大家参考,具体如下: app.js: App({ //设置全局请求URL globalData:{ URL: 'https://www.oyhdo.com', }, /** * 封装wx.request请求 * method: 请求方式 * url: 请求地址 * data: 要传递的参数 * callback: 请求成功回调函数 * errFun: 请求失败回调函数 **/ wxRequest(metho

  • 微信小程序 定义全局数据、函数复用、模版等详细介绍

    微信小程序 定义全局数据.函数复用.模版等问题总结: 1.如何定义全局数据 在app.js的App({})中定义的数据或函数都是全局的,在页面中可以通过var app = getApp();  app.function/key的方式调用,不过我们没有必要再app.js中定义全局函数. 2.如何实现代码的复用 函数的复用: test.js test: function(){ } module.exports={ test:test } other.js var common = require('

  • 微信小程序实现全局搜索代码高亮的示例

    需求 最近在做微信小程序的时候,需要实现在搜索框的输入内容的时候实现全局匹配实现高亮效果,目前的思路是,递归后台来返回的数据,并将对象的value值替换为需要的dom节点,并且通过rich-text来实现,高亮效果. 代码 wxml: <view class='homePage'> <input bindinput="bindKeyInput"></input> <view wx:for="{{newJson}}" wx:f

  • 在微信小程序里使用watch和computed的方法

    在开发 vue 的时候,我们可以使用 watch 和 computed 很方便的检测数据的变化,从而做出相应的改变,但是在小程序里,只能在数据改变时手动触发 this.setData() ,那么如何给小程序也加上这两个功能呢? 我们知道在 vue 里是通过 Object.defineProperty 来实现数据变化检测的,给该变量的 setter 里注入所有的绑定操作,就可以在该变量变化时带动其它数据的变化.那么是不是可以把这种方法运用在小程序上呢? 实际上,在小程序里实现要比 vue 里简单,

  • 微信小程序本作用域下调用全局JS详解及实例

    微信小程序本作用域下调用全局JS详解 本地wxml文件 <view> app版本:{{version}} </view> 本地js文件 var app; Page({ data:{ }, onLoad:function() { app = getApp(); this.setData({version:app.globalData.appName}); } }) 全局js文件 //app.js App({ globalData:{ appName:"hcoder"

  • 小程序自定义单页面、全局导航栏的实现代码

    需求 产品说小程序返回到首页不太方便,想添加返回首页按钮,UI说导航栏能不能设置背景图片,因为那样设计挺好看的. 需求分析并制定方案 这产品和UI都提需求了,咱也不能反驳哈,所以开始调研,分析可行性方案:1.可以添加悬浮按钮.2.自定义导航栏. 添加悬浮按钮,是看起来是比较简单哈,但是感觉不太优雅,会占据页面的空间,体验也不太好.所以想了下第二种方案,自定义导航栏既可以实现产品的需求还可以满足UI的设计美感,在顶部空白处加上返回首页的按钮,这样和返回按钮还对称(最终如图所示,顶部导航栏是个背景图

  • 微信小程序全局变量功能与用法详解

    本文实例讲述了微信小程序全局变量功能与用法.分享给大家供大家参考,具体如下: 全局变量的作用 在微信小程序开发中,会遇到一个很实际的应用场景,就是一个变量会在多个页面进行使用. 例如: 1. 在微信小程序开发中使用高德地图的微信小程序开发,其中key值就需要在多个页面使用: 2. 在微信小程序开发电商平台时同样,比如客服电话,就需要在多个页面使用. 在以上两种类似的场景中,开发者就需要使用全局变量,当然也有开发者说不能每个page页面都定义一个?如果客服电话改变,如果客服要求采用他的高德key,

  • 微信小程序 开发之全局配置

    一.app.json 使用app.json文件来对微信小程序进行全局配置,决定页面文件的路径.窗口表现.设置网络超时时间.设置多 tab 等. 注意在.json不能注释,否则会出错. 二.工具栏tabBar 如果我们的小程序是一个多 tab 应用(客户端窗口的底部或顶部有 tab 栏可以切换页面),那么我们可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面. tabBar 是一个数组,只能配置最少2个.最多5个 tab,tab 按数组的顺序排序 app.js

  • 使用watch在微信小程序中实现全局状态共享

    问题 在之前开发微信小程序的时候,获取用户信息.openid还有地理位置这些信息的时候,都是采用Promise的方式异步获取,但是这样的话在页面和App.js中都获取就可能造成请求重复的问题. 比如为了在每个页面都能获取到这些共享信息,都会选择在App.js中进行获取,然后在页面级进行获取,这两次获取的时间间隔较小时就可能导致前一个请求还未获取到数据,后一个请求就会再次进行获取,这样就产生了两次请求. 还有一个问题就是书写麻烦(虽然也能通过async await简化),比如 onLoad() {

  • 微信小程序MoxB实现全局状态管理流程详解

    目录 安装 MobX 创建 MobX Store 使用 MobX Store 在 Component 构造器中使用 在 Page 页面中使用 github 地址:https://github.com/wechat-miniprogram/mobx-miniprogram-bindings. 安装 MobX 在小程序根目录下执行 npm install --save mobx-miniprogram mobx-miniprogram-bindings 安装 mobx-miniprogram 和 m

  • 微信小程序中的swiper组件详解

    微信小程序中的swiper组件 微信小程序中的swiper组件真的是简单方便 提供了页面中图片文字等滑动的效果 <swiper> <swiper-item></swiper-item> <swiper-item></swiper-item> <swiper-item></swiper-item> </swiper> 这里的就是一个滑块视图容器:而就是你希望滑动的东西,可以是文字也可以是image 其中swipe

  • 微信小程序中顶部导航栏的实现代码

    微信小程序中顶部导航栏的实现 实例代码: <view class="swiper-tab"> <view class="swiper-tab-list {{currentTab==0 ? 'on' : ''}}" data-current="0" bindtap="swichNav">11</view> <view class="swiper-tab-list {{curre

  • 微信小程序中input标签详解及简单实例

    微信小程序中input标签详解及简单实例 使用input标签,我们都会,在微信小程序中使用,必定也是可以一下子就会的,但是却有些常用的属性无法按照习惯去使用: 我就用我最常用的来做例子: 一个一个来解读: 首先,我是定义了他的id,这是我们最常用的,所以就配了一个id,毕竟不操作他,又为什么设成输入框呢, 第二,设置他的样式, 第三,设置他的输入类别,以上都是很简单的 第四.使用正则l:哎限定输入为纯数字.这点可能有点不理解,这是对他的keyup事件监听,将不是纯数字的list无视掉.注意,是对

  • 微信小程序中使用Promise进行异步流程处理的实例详解

    微信小程序中使用Promise进行异步流程处理的实例详解 我们知道,JavaScript是单进程执行的,同步操作会对程序的执行进行阻塞处理.比如在浏览器页面程序中,如果一段同步的代码需要执行很长时间(比如一个很大的循环操作),则页面会产生卡死的现象. 所以,在JavaScript中,提供了一些异步特性,为程序提供了性能和体验上的益处,比如可以将代码放到setTimeout()中执行:或者在网页中,我们使用Ajax的方式向服务器端做异步数据请求.这些异步的代码不会阻塞当前的界面主进程,界面还是可以

  • 微信小程序中使用javascript 回调函数

     微信小程序中使用javascript 回调函数 回调函数原理: 我现在出发,到了通知你" 这是一个异步的流程,"我出发"这个过程中(函数执行),"你"可以去做任何事,"到了"(函数执行完毕)"通知你"(回调)进行之后的流程 点击此处转载参考文献 感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

  • 微信小程序中button组件的边框设置的实例详解

    微信小程序中button组件的边框设置的实例详解 button的边框是用:after方式实现的,用户如果在button上定义边框会出现两条线,需用:after的方式去覆盖默认值. 如果设置了Button的背景色,没有用:after设置边框的颜色,则button的四个角会出现模糊的尖角.如下图所示: 如上图四个角会模糊..wxss代码如下: .clickEncryptBtn{ width:130px; border-radius: 3px; margin:20px auto; padding-to

  • 微信小程序中显示html格式内容的方法

    前言 最近项目上遇到在微信小程序里需要显示新闻内容,新闻内容是通过接口读取的服务器中的富文本内容,是html格式的,小程序默认是不支持html格式的内容显示的,那我们需要显示html内容的时候,就可以通过wxParse来实现. 准备工作: 首先我们下载wxParse github地址:https://github.com/icindy/wxParse 本地下载:http://xiazai.jb51.net/201704/yuanma/wxParse-master(jb51.net).rar wx

  • 微信小程序中页面FOR循环和嵌套循环

    微信小程序中页面FOR循环和嵌套循环 单个循环 <view wx:for="{{pinpaiTishi}}" wx:key="{{xxx}}"> <view wx:if="{{item.name!=null}}" wx:key="{{xxxx}}"> //判断name是否为null <view class="tr"> <view class="td-lef

随机推荐