起步
由于之前学习vue源码,在vue源码中学到了如何针对不同的选项参数进行合并,并且为了学以致用,所以就写了一个简单的用于合并微信小程序Page构造数参数的工具函数。因为笔者最近在做微信小程序开发的,我去找了一下,发现微信小程序中好像只有组件拥有一个叫做behaviors用于组件之间的代码复用的选项,对于小程序页面来说并没有类似的mixins这种代码复用机制,便把vue这一套参数合并机制用在微信小程序的Page构造器上,它是一个简单的用于合并微信小程序Page构造器参数的工具函数,用的就是vue的参数合并这一套,不过没vue那么多选项需要合并,只有data和生命周期钩子函数这两个需要合并,不过支持多个mixins选项以及mixins嵌套合并。
github地址:https://github.com/nongcundeshifu/wxPageMixins。喜欢的就点个Star吧。
ps:目前此工具只针对小程序的Page构造器进行参数合并,小程序组件请使用其自带的behaviors进行混入,后续可能出一个通用的,可自定义合并策略函数以及可配置的工具出来吧。
使用
// 引入wxPageMixinsimport wxPageMixins from './wxPageMixins.js';// 引入mixin对象import mixin from 'mixin.js';// 在微信小程序中,使用wxPageMixins工具函数合并选项参数Page(wxPageMixins({ mixins: [mixin], // other props}));案例
testMixin.js
// 导入子mixin对象import subMixins from './subMixin.js';export default { // mixin对象也可以使用mixins字段进行合并 mixins: [subMixins], // 生命周期钩子函数 onLoad(options) { console.log('[testMixin log]: this is testMixin.js'); console.log('[testMixin log]: this page options is: ', options); // 执行子mixins对象的方法。 this.subMixin(); }, data() { return { title: 'this is testMixin.js', // 对象数据 message: { name: 'testMixin', age: 22, } } }, // 其他小程序自定义函数 onShareAppMessage() { return { title: this.data.title, } }, click(e) { console.log('[testMixin log]: this is click function', e); },}subMixin.js
// testMixin导入的子mixin对象export default { // 生命周期钩子函数 onLoad(options) { console.log('[subMixin log]: this is subMixin.js'); console.log('[subMixin log]: 我即使被重复引用了,也仅执行一次'); }, data() { return { title: 'this is subMixin.js', // 对象数据 arr: [1, 2, 3], } }, subMixin() { console.log('[subMixin log]: this is subMixin function'); }, tap(e) { console.log('[subMixin log]: this is tap function', e); },}test2Mixin.js
export default { // 生命周期钩子函数 onShow() { console.log('[test2Mixin log]: this is test2Mixin onShow log'); }, data() { return { imageSrc: 'https://temp.mixins.com', icon: { iconClass: 'icon-active', iconImageSrc: 'https://temp.icon.com', }, } },}小程序test页面:test.js
// pages/test/test.js// 导入wxPageMixins,注意使用相对路径import wxPageMixins from '../../utils/wxPageMixins/wxPageMixins.js';// 导入mixins对象import testMixin from '../../utils/mixins/testMixin.js';import test2Mixin from '../../utils/mixins/test2Mixin.js';import subMixin from '../../utils/mixins/subMixin.js';// 使用wxPageMixins合并参数Page(wxPageMixins({ // 引用mixin,顺序的不同,合并后的结果也可能不用,因为越在数组后面,其数据合并的优先级越高 mixins: [testMixin, test2Mixin], // subMixin被重复引用,因为testMixin也引入了subMixin,重复引用的生命周期钩子函数也只执行一次。 // 你可以使用此mixins选项,看和上面的有何不同。 // mixins: [testMixin, test2Mixin, subMixin], /** * 页面的初始数据 */ data: { imageSrc: 'https://temp.mixins.com', arr: [4, 5, 6], message: { age: 1, info: { vname: 'vname', vage: 100, }, }, }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { console.log('[test log]: this is test.js'); console.log('[test log]: this page options is: ', options); }, tap(e) { console.log('[test log]: this is tap function', e); },}))合并后的输出结果:


ps:以上案例可在github上的example案例中查看完整案例。
github地址:https://github.com/nongcundeshifu/wxPageMixins/tree/master/example
参数合并规则
data的合并
data为一个函数或者一个数据对象,如果是一个函数则返回一个对象数据,数据对象合并时会进行递归合并,如果是js的原始值则后者覆盖前者,如果相同字段且都是一个对象时(不是数组,数组也会直接覆盖,并不会合并),则进行对象的递归合并。
ps: 他和vue不同,这里的data可以不是一个函数,所以并且没有做此校验,因为微信小程序中的Page内部会把data转变为JSON格式,所以data可以不是函数。不过你写函数也完全ok,不过注意了,因为是JSON格式,所以,data中不能有函数数据。
合并生命周期函数
生命周期函数不会相互覆盖,而是在对应触发时机被逐个调用。如果同一个 mixin 被一个组件多次引用(重复引用,嵌套引用),它定义的生命周期函数只会被执行一次。会合并的生命周期钩子函数如下:
- onLoad
- onReady
- onShow
- onHide
- onUnload
合并其他微信小程序自定义的事件处理函数
其他微信小程序自定义的事件处理函数会直接进行事件处理函数的覆盖,并不会进行合并,产生覆盖的函数如下:
- onShareAppMessage
- onPullDownRefresh
- onReachBottom
- onPageScroll
- onResize
- onTabItemTap
合并其他字段
其他自定义字段,比如自定义的事件方法等:直接后者覆盖前者(如果是对象也不会进行递归遍历而是直接覆盖)
合并mixins
如果有多个mixin对象,或者有嵌套引用mixin时,则mixins字段将进行深度优先的递归合并。并且在数组越靠后的位置,则优先级越高。
注意
- 不要进行循环引用,估计会炸。
- 在混入对象(mixin)中,无法获取到Page构造函数执行的那一个作用域,mixin中的处理函数中只能拿到page对象,也就是this。但无法拿到调用Page构造函数之外的变量数据。
总结
以上就是我根据vue中的数据合并策略编写的微信小程序Page页面的参数合并工具,其实这种合并不只是适用于微信小程序,我们在编写自己的框架和库的时候,这种需要参数传递,并且再需要合并默认参数和用户传入参数的时候,这种合并方式就可以借鉴使用。而且我们还可以暴露出一些配置,或者暴露一些接口来让用于自定义参数的合并策略函数,这样代码的可扩展性会更强。
小程序













