微信原生小程序转其他平台的小程序实践(下)

简介: 如何将现有的微信原生小程序转其他平台的小程序?我想如果打算做这么一件事,或许大多数同学和我一样可能没什么思路。我第一次听说是在一次小程序生态技术大会上,一公司的一位前端技术人员谈到他们公司主要是将自己的微信小程序通过团队开发的工具转成其他平台的小程序,所以当时我也很想了解这个工具是怎么做的,实现过程是什么?
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。综合以上几点于是决定来趟一下这个浑水,总的结果来说,项目周期缩短了好多,大致花了两周的时间来完成了,也了解了支付宝小程序和微信小程序之间的一些差异,解决了好多问题,解决问题的过程中也很头疼...


相关文章
预约按摩小程序开发,为什么很多上门按摩平台根本招聘不到优秀技师?
上门按摩平台面临招不到优秀技师的问题,主要原因是平台众多,技师选择多样。为解决此问题,平台可引入技师等级制度,根据订单数量和好评率划分高、低等级技师。高等级技师可享受70%-90%的高提成及首页推荐,这不仅能激励技师的积极性,还能帮助平台筛选出优质技师,提升服务质量和口碑,形成良性循环。
|
1月前
|
JSON 小程序 JavaScript
uni-app开发微信小程序的报错[渲染层错误]排查及解决
uni-app开发微信小程序的报错[渲染层错误]排查及解决
511 7
|
1月前
|
小程序 JavaScript 前端开发
uni-app开发微信小程序:四大解决方案,轻松应对主包与vendor.js过大打包难题
uni-app开发微信小程序:四大解决方案,轻松应对主包与vendor.js过大打包难题
613 1
|
1月前
|
存储 JSON 小程序
微信小程序入门之新建并认识小程序结构
微信小程序入门之新建并认识小程序结构
50 1
|
1月前
|
监控 小程序 前端开发
小程序全栈开发中的WebSocket实时通信实践
【10月更文挑战第3天】随着移动互联网的发展,小程序因便捷的用户体验和社交传播能力,成为企业拓展业务的新渠道。本文探讨了小程序全栈开发中的WebSocket实时通信实践,包括其实时通信、长连接及双向通信的特点,并通过实时聊天、推送、游戏和监控等功能的实现,展示了WebSocket在小程序中的应用。开发者需注意安全性、性能及兼容性等问题,以保障小程序的稳定运行和用户体验。
46 7
|
1月前
|
缓存 小程序 索引
uni-app开发微信小程序时vant组件van-tabs的使用陷阱及解决方案
uni-app开发微信小程序时vant组件van-tabs的使用陷阱及解决方案
199 1
|
1月前
|
机器学习/深度学习 人工智能 JSON
微信小程序原生AI运动(动作)检测识别解决方案
近年来,疫情限制了人们的出行,却推动了“AI运动”概念的兴起。AI运动已在运动锻炼、体育教学、线上主题活动等多个场景中广泛应用,受到互联网用户的欢迎。通过AI技术,用户可以在家中进行有效锻炼,学校也能远程监督学生的体育活动,同时,云上健身活动形式多样,适合单位组织。该方案成本低、易于集成和扩展,已成功应用于微信小程序。
|
1月前
|
小程序 JavaScript API
微信小程序开发之:保存图片到手机,使用uni-app 开发小程序;还有微信原生保存图片到手机
这篇文章介绍了如何在uni-app和微信小程序中实现将图片保存到用户手机相册的功能。
598 0
微信小程序开发之:保存图片到手机,使用uni-app 开发小程序;还有微信原生保存图片到手机
|
1月前
|
JavaScript 小程序 开发者
uni-app开发实战:利用Vue混入(mixin)实现微信小程序全局分享功能,一键发送给朋友、分享到朋友圈、复制链接
uni-app开发实战:利用Vue混入(mixin)实现微信小程序全局分享功能,一键发送给朋友、分享到朋友圈、复制链接
340 0
|
1月前
|
小程序
uni-app开发微信小程序使用onPullDownRefresh(下拉刷新)总结
uni-app开发微信小程序使用onPullDownRefresh(下拉刷新)总结
523 0

热门文章

最新文章