import { basic } from '../mixins/basic'; import { observe } from '../mixins/observer/index'; function mapKeys(source, target, map) { Object.keys(map).forEach(key => { if (source[key]) { target[map[key]] = source[key]; } }); } function noop() {} function VantComponent(vantOptions = {}) { const options = {}; mapKeys(vantOptions, options, { data: 'data', props: 'properties', mixins: 'behaviors', methods: 'methods', beforeCreate: 'created', created: 'attached', mounted: 'ready', relations: 'relations', destroyed: 'detached', classes: 'externalClasses' }); options.properties = options.properties || {}; // relations 微信组件特性,暂时没法模拟到支付宝 const { relation } = vantOptions; if (relation) { options.relations = Object.assign(options.relations || {}, { [`../${relation.name}/index`]: relation }); } // add default externalClasses options.externalClasses = options.externalClasses || []; options.externalClasses.push('custom-class'); // add default behaviors options.behaviors = options.behaviors || []; options.behaviors.push(basic); // map field to form-field behavior if (vantOptions.field) { options.behaviors.push('wx://form-field'); } // add default options options.options = { multipleSlots: true, addGlobalClass: true }; observe(vantOptions, options); /** * 参照wwto => 运行时调整options */ /** * mixins */ options.mixins = options.mixins || []; options.mixins = options.mixins.concat(options.behaviors); /** * const lifeCircleNames = ['created', 'attached', 'ready', 'detached']; */ options.methods = options.methods || {}; const lifeCircleNames = ['created', 'attached', 'ready', 'detached']; lifeCircleNames.forEach(name => { let methods = options.methods[name] = options.methods[name] || options[name] || noop; // fix selectComponents api if (name == 'ready') { options.methods[name] = function() { if(this.data.id){ var app = getApp(); app.globalData.insComp = app.globalData.insComp || {}; app.globalData.insComp[this.data.id] = this; }; methods(); } } }) /** * 处理this.__observers */ let has = Object.prototype.hasOwnProperty; let propMap = {}; let observerMap = null; let walkProps = obj => { Object.keys(obj).forEach((key) => { if (!has.call(obj, key)) return let item = obj[key]; // String Number Boolean 设定默认值 if (item === String) { propMap[key] = ''; } else if (item === Boolean) { propMap[key] = false; } else if (item === Number) { propMap[key] = 0; } else if (item && typeof item == 'object') { let type = item.type; if (!('value' in item)) { if (type === String) { propMap[key] = ''; } else if (type === Boolean) { propMap[key] = false; } else if (type === Number) { propMap[key] = 0; } else { propMap[key] = ''; // 暂时默认值 } } else { propMap[key] = item.value; } if (item.observer) { // debugger observerMap = observerMap || {}; if (typeof item.observer === 'function') { observerMap[key] = item.observer; } else { // 微信小程序中observer也可以使用对象的形式 observerMap[key] = function() { this[item.observer] && this[item.observer].apply(this, arguments); }; } } } else { propMap[key] = item; } }); } // 处理properties => props let properties = options.properties; walkProps(properties); let mininsProperties = options.mixins.filter(item => item.properties); mininsProperties.forEach(item => { walkProps(item.properties); }) /** * 处理 externalClasses 同时手动拷贝class */ let externalClasses = options.externalClasses; externalClasses.forEach(clas => { propMap[clas.replace(/-(\w)/g, (match, p) => p.toUpperCase())] = ''; }) options.props = propMap; options.props.__observers = observerMap /** * my生命周期函数 */ options.didMount = function(){ this.data = Object.assign({}, this.data, this.props); this.created && this.created.apply(this, arguments); this.attached && this.attached.apply(this, arguments); this.ready && this.ready.apply(this, arguments); /** * 解决初始化observer component 组件 */ if (this.props.__observers) { Object.keys(this.props.__observers).forEach(key => { this.props.__observers[key].call(this, this.props[key]) }) } } options.didUnmount = function(){ this.detached && this.detached.apply(this, arguments); } options.didUpdate = function(prevProps, preData) { for (let key in this.props) { if (this.props.__observers && typeof(this.props.__observers[key]) === 'function') { if (JSON.stringify(prevProps[key]) !== JSON.stringify(this.props[key]) && JSON.stringify(preData[key]) !== JSON.stringify(this.props[key])) { this.setData(Object.assign({}, this.data, {[key]: this.props[key]})); this.props.__observers[key].apply(this, [this.props[key], prevProps[key]]); } } else if (this.props[key] !== prevProps[key]) { this.data[key] = this.props[key]; this.setData(this.data); } } } Component(options); } export { VantComponent };
到这里主要的问题解决了,其他一些微信小程序到支付宝小程序的差异就不都列出来了,可以灵活的修改wwto 的代码来实现转换时的差异, 如果后期有同样需求的同学尝试转换时有遇见问题,也可留言交流。
最后
最初在决定到底要不要使用wwto这个工具来转换微信小程序的时候,心里面也是没底的,毕竟刚开源,我估计是第一个在刚开源的时候来做转换的。而且本身也从未开发过支付宝小程序,也不知道支付宝小程序和微信小程序有哪些大致的差异,再加上调研技术上也没有给充裕的时间来决策到底用什么方案来实现其他平台的小程序。最后决定使用wwto来做这件事,主要是不想做重复的工作,对仅仅使用新的技术框架uni-app来重写,估计对我来说短期也不会有太多的技术积累收益,当然同时呢我也想快速的了解微信和支付宝的一些差异,重要的一点就是wwto开源的,每个部分的源代码都能debug。综合以上几点于是决定来趟一下这个浑水,总的结果来说,项目周期缩短了好多,大致花了两周的时间来完成了,也了解了支付宝小程序和微信小程序之间的一些差异,解决了好多问题,解决问题的过程中也很头疼...