您现在的位置: 微信小程序 > 微信小程序开发 > 教程 >

各种小程序的组件机制差异

来源:微信小程序 编辑:Yiyongtong.com 发布时间:2018-10-19 10:53热度:

在蚂蚁金服的开放平台上看到一些贴子,说提供一个工具,一键转换微信小程序为支付宝小程序。我与百度的人交流时,也听到相似的东西。其实都没有这么简单,它们最多是将一些循环条件分支指令改一下名,将一些文件的后缀名改一下,更多的差异点在API与各式的配置对象上,细节是魔鬼,我在娜娜奇的官网也列举了许多相关的东西,但也不能打票说已经很齐全。。。。

 

各种小程序的差异点-文档

 

补充一句,娜娜奇是我们公司的小程序开发框架,以React方式转译成各种小程序与快应用的框架。类似于京东的taro。

最近忙于支付宝小程序的开发,我得到许多有关小程序的一手资料,包括自己测试得到的,及从百度,小米快应用与支付宝内部人士提供的。

本文将重点说一下小程序的组件机制,之前娜娜奇的组件机制是基于template标签实现的,但百度的template有点BUG,给他们提了,不知现在修了没有。与template机制在快应用又出入太大,于是转向用自定义组件机制开发娜娜奇的组件机制。下面链接有一些相关的测试与说明

转换小程序 · Issue #133 · RubyLouvre/anu

经测试,使用了自定义组件机制的确是比template实现的简洁一些。但自定义组件机制是一个比较高级的特性,因此兼容性上比template差多了。只能内部推到各方改进了。

微信在Component的配置对象提供了一些对象如methods, lifetimes,pageLifetimes,来减少其直辖的配置项。
比如说lifetimes收纳了created、attached、ready、moved、detached这些生命周期钩子,pageLifetimes收纳了onShow, onHide这些与页面切换的钩子,methods收纳剩下的方法,另外还有许多配置项。的确,微信小程序独自发布这么久,肯定是最完善的

支付宝的自定义组件机制没有properties,只有props,并且作用也不一样,props只是指定默认值,不是规定参数类型。支付宝也没有lifetimes与pageLifetimes对象,生命周期函数的名字也不一样 didMount 、didUpdate 、didUnmount,数量也少了,但从名称来看,支付宝在内部应该运行一个自己的迷你React。


其他方面,支付宝没有 dataset, selectComponent,selectAllComponents,getRelationNodes这些东西,但支持了早被React废弃的mixin机制。


支付宝没有created这样的钩子是相当麻烦的事,因此积级推动他们加上这个钩子!

百度的自定义组件机制与微信的较为相近,但也没有lifetimes与pageLifetimes对象,只有4种生命周期钩子:created,attached,ready,detached。有selectComponent,selectAllComponents。

快应用的页面与组件的配置对象都是一样,但它没有构造函数,只是要求我们export一个对象
有props对象,用来定义类型与默认值,也有与state相似的data对象,也有三个做了访问限制的private, protected, public对象。生命周期钩子上有onInit、onReady、onDestroy这三个。

从组件的设计来看, 微信 > 百度 > 支付宝 > 快应用

 

因此想兼容这么多种小程序,我们必须自己写一个工厂方法,根据不同的平台生成不同的配置项,并且放弃掉一些微信的强大功能了。

var hooksName = {
	wx: ['created', 'attached', 'detached'],
	bu: ['created', 'attached', 'detached'],
	ali: ['didMount', 'didMount', 'didUnmount'],
	quick: ['onInit', 'onReady', 'onDestroy'],
};

export function registerComponent(type, name) {
	registerComponents[name] = type;
	var reactInstances = (type.reactInstances = []);
	var wxInstances = (type.wxInstances = []);
	var hooks = [
		function created() {
			var instance = reactInstances.shift();
			if (instance) {
				console.log('created时为', name, '添加wx');
				instance.wx = this;
				this.reactInstance = instance;
			} else {
				console.log('created时为', name, '没有对应react实例');
				wxInstances.push(this);
			}
		},
		function attached() {
                        if(appType == "ali"){
                            created.call(this)
                        }
			if (this.reactInstance) {
				updateMiniApp(this.reactInstance);
				console.log('attached时更新', name);
			} else {
				console.log('attached时无法更新', name);
			}
		},
		function detached() {
			this.reactInstance = null;
		},
	];
	var data = {
		props: {},
		state: {},
		context: {},
	};
	var config = {
		data: data,
		public: data,
		dispatchEvent: eventSystem.dispatchEvent,
		methods: {
			dispatchEvent: eventSystem.dispatchEvent,
		},
	};
	hooksName[appType].forEach(function(name, index) {
		config[name] = hooks[index];
	});

	return config;
}