GitHub:

https://github.com/WozHuang/mp-extend

相关文章:

小程序全局状态管理,在页面中获取globalData和使用globalSetData

通过页面预加载(preload)提升小程序的响应速度

主要目标

小程序本身的坑不少,开发时免不了需要引入或大或小的框架。而目前的小程序开发框架基本分为两种,一种是以Taro、wePY这种以其他技术栈开发小程序,一种是在原有的小程序开发模式上进行扩展。

对于新建立的项目,选择何种框架全凭喜好,可以优先考虑与团队技术栈相关的开发框架。但是多数时候开发者还是使用小程序官方的开发方式,并且已经开发了一段时间并投入使用了,这时再考虑引入框架代价就有点大了,于是我就在寻找一个能够在不改动现有代码前提下扩展小程序api的框架。

寻找资料

参考了westore,omix,wxpage等基于小程序自身扩展的框架后,发现他们统一都是在APP、Page、Component构造函数上做文章,对页面本身的PageOption进行操作,实现扩展api的功能。

小程序中有部分Vue和React的影子(data属性,setData方法),而Vue和React都有mixin这种扩展组件的方式,于是便考虑在Page构造函数上做文章,提供全局混入的能力来扩展api。

代码实现

我实现混入中的两个主要函数:

1. 装饰函数

使用装饰方法对PageOption(Page函数调用时传入的参数)中的生命周期函数(onLoad等)进行修改,调用混入的生命周期方法。

// 对原有函数进行修改,返回结果是原函数的返回结果
// 在调用原函数之前调用所有装饰器
function decorate(f, ...decorators) {
return function () {
for (const decorator of decorators) {
decorator && decorator.apply(this, arguments);
}
return f && f.apply(this, arguments);
};
}

2. 合并混入对象

使用mixin函数将混入中的对象与PageOption原有的对象进行合并

/**
* 实现混入的效果
* 类似 Object.assign, 但在遇见相同属性名均是对象时会递归进行合并而非直接覆盖
* 注:如果存在引用循环递归会栈溢出
*/
function mixin(o, ...mixs) {
mixs.forEach(mix => {
for (const key in mix) {
// 两个属性都是对象则递归合并
if (isObject(o[key]) && isObject(mix[key])) {
mixin(o[key], mix[key]);
} else {
o[key] = o[key] || mix[key];
}
}
// 拷贝symbol类型,(可惜小程序不支持)
for (const sym of Object.getOwnPropertySymbols(mix)) {
o[sym] = o[sym] || mix[sym];
}
});
return o;
}

3. 重写Page函数(App,Component同理)

在调用Page函数前将所有混入对象合并到PageOption中

// base.Page 页面的基类,包含所有混入对象的非生命周期属性
// lifeMixin.Page 包含所有混入对象的生命周期函数
// life.Page 一个数组包含Page所有的生命周期 ['onLoad', 'onShow', ...] const _Page = decorate(Page, function (option) {
// 合并非生命周期属性
mixin(option, base.Page);
// 合并生命周期属性
for (const lifeTime of life.Page) {
option[lifeTime] = decorate(option[lifeTime], ...lifeMixin.Page[lifeTime]);
}
// preprecess是扩展的生命周期,在Page函数调用前被调用,可以用于修改PageOption
option['preproccess'] && option['preproccess'].call(option, option);
});

通过重写Page函数在将混入对象合并到PageOption中实现全局混入的功能,最后只需要在现有代码前加入一行 Page = _Page;,即可实现全局混入的能力而无需修改其他代码。

使用示例

能够方便地以全局混入的方式扩展api,以下是一个简单示例:混入data属性 和 添加PV统计功能

Page: {
data: {
exData: '所有页面的data都会获得exData属性'
}, onLoad(){
console.log(`PV统计: 在${formatTime(new Date())} 打开了页面 ${this.__route__}`)
}
}

参考资料

wxpage

omi

Vue mixins

微信小程序之提高应用速度小技巧

在小程序中实现全局混入,以混入的形式扩展小程序的api的更多相关文章

  1. 中小研发团队架构实践之生产环境诊断工具WinDbg 三分钟学会.NET微服务之Polly 使用.Net Core+IView+Vue集成上传图片功能 Fiddler原理~知多少? ABP框架(asp.net core 2.X+Vue)模板项目学习之路(一) C#程序中设置全局代理(Global Proxy) WCF 4.0 使用说明 如何在IIS上发布,并能正常访问

    中小研发团队架构实践之生产环境诊断工具WinDbg 生产环境偶尔会出现一些异常问题,WinDbg或GDB是解决此类问题的利器.调试工具WinDbg如同医生的听诊器,是系统生病时做问题诊断的逆向分析工具 ...

  2. C#程序中设置全局代理(Global Proxy)

    1. HttpWebRequest类的Proxy属性,只要设置了该属性就能够使用代理了,如下: 1             //设置代理 2         WebProxy WP = new Web ...

  3. [Z] C#程序中设置全局代理(Global Proxy)

    https://www.cnblogs.com/Javi/p/7274268.html 1. HttpWebRequest类的Proxy属性,只要设置了该属性就能够使用代理了,如下: 1        ...

  4. [FMX]在 FMX 程序中绘制单像素宽度的直线 [FMX]在 FMX 程序中绘制单像素宽度的直线

    [FMX]在 FMX 程序中绘制单像素宽度的直线 2017-10-09 • Android.Delphi.教程 • 暂无评论 • swish •浏览 353 次 在前面的一篇文章中,我介绍了一种绘制低 ...

  5. 在.NET Core程序中设置全局异常处理

    以前我们想设置全局异常处理只需要这样的代码: AppDomain currentDomain = AppDomain.CurrentDomain; currentDomain.UnhandledExc ...

  6. 关于在程序中 文件新生成 在用os.system()程序对新生成的文件处理 举个栗子 如下:

    print 'save to ',savedir+os.sep+d["FILE_NAME"]                ff = open(savedir+os.sep+d[& ...

  7. 王爽《汇编》检测9.1(1) | 若要使程序中的jmp指令执行后,CS:IP指向程序的第一条指令,在data段中应该定义哪些数据?

    ;监测点9.1(1) assume cs:code data segment db dup() data ends code segment start: mov ax,data :这一段一定要补上 ...

  8. 如何在微信小程序中使用字体图标

    微信小程序中,在image标签里,可以在src中引用本地文件,但是background设置背景图或者使用字体图标的时候,却不能引用本地文件,只能用url地址的图片或字体,或者使用base64编码后的格 ...

  9. 微信小程序中换行,空格(多个空格)写法

    在小程序中HTML的网页实体无法正常使用,小程序中的写法为: 一.空格,换行 <text>你好!\t七月流火啊!\n我在下一行</text> \t 空格( 多个只会显示一个空格 ...

随机推荐

  1. 【JS】垃圾回收和块级作用域

    垃圾回收: JavaScript中,开发者不必关心内存分配和回收的问题.这和Java语言相似.有一个垃圾自己主动回收机制.那么JavaScript内部到底是如何回收垃圾的呢? 使用标记回收法:就是说. ...

  2. Empower Developers

     Empower Developers Timothy High THingS ARE uSuAlly EASiER SAid THAn donE, and software architects ...

  3. 问题2-:Syntax error on tokens, delete these tokens

    出现原因:拷贝下来的代码缺少{左大括号 然后运行时run as 没有选到java application 是因为没有main方法 加个public static void main(String() ...

  4. Oracle 数据块损坏与恢复具体解释

    1.什么是块损坏: 所谓损坏的数据块,是指块没有採用可识别的 Oracle 格式,或者其内容在内部不一致. 通常情况下,损坏是由硬件故障或操作系统问题引起的.Oracle 数据库将损坏的块标识为&qu ...

  5. Hadoop-2.2.0中文文档——Apache Hadoop 下一代 MapReduce (YARN)

    MapReduce在hadoop-0.23中已经经历了一次全然彻底地大修.就是如今我们叫的MapReduce 2.0 (MRv2) or YARN. MRv2的基本思想是把JobTracker分成两个 ...

  6. luogu1896 [SCOI2005]互不侵犯 状压DP

    题目大意 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子.( 1 <=N <=9, 0 ...

  7. C# 同步更新系统时间

    前言 在定位用户问题时,发现有些电脑,会出现系统时间不是最新的问题. 可能原因: 取消了勾选服务器时间同步 当前安装的系统,是一个未知来源系统,导致系统时间更新失败 而系统时间不正确,会导致IE选项- ...

  8. springboot整合ActiveMQ 2(主备模式,负载均衡)

    基本使用,https://www.tapme.top/blog/detail/2018-09-05-10-38 主备模式,https://www.tapme.top/blog/detail/2018- ...

  9. POJ 1386 判断欧拉回路

    题意:要开启一扇门,n个单词是密码,n个单词中,如果一个单词的首字母和前一个单词的尾字母相同,并且每个单词都能这么连起来且只用一次,则门可以开启,否则不能开启,现给出单词,判断门是否可以开. 有向图欧 ...

  10. C++批量加载动态库函数方法

    1.枚举定义enum  {    // 0 - GigE DLL (implicitly called)    Func_isVersionCompliantDLL,    Func_isDriver ...