记录将微信小程序代码挪到支付宝小程序的过程中遇到的一些支付宝小程序和微信小程序的差异,以免每次都去官方文档查。

1.文件后缀名

微信小程序的四个文件后缀为.js、.json、.wxml、.wxss,支付宝小程序的四个文件后缀为.js、.json、.axml、.acss。

使用命令将当前目录下后缀名为wxml的文件全部替换为axml,后缀名为wxss的文件换为acss:

rename 's/\.wxml/\.axml/' * && rename 's/\.wxss/\.acss/' *

使用 man rename 查看更多rename用法。参考地址:linux 批量修改文件名后缀名命令rename。执行命令时如果提示 zsh: command not found: rename,就用 brew install rename 安装一下 rename,如果没有安装brew,使用brew 首页的安装命令安装一下即可。Mac下载brew时报错的处理。

2.控制属性

微信小程序 支付宝小程序
wx:if a:if
wx:for a:for
wx:key a:key

在axml文件中的a: 对应wxml文件中的 wx:

3.标签

微信小程序 支付宝小程序
<i><icon> <icon>
<span>、 <text>

微信小程序即支持 <icon> 标签,又支持 <i>,但是支付宝小程序只支持 <icon> 标签,写HTML5标签习惯之后比较偏向于写 <i><span>,但是如果是同时要写支付宝小程序和微信小程序,还是直接使用小程序标签 <icon><text> 比较好。

4.事件属性

微信小程序 支付宝小程序
bindtap onTap
catchtap catchTap

微信小程序使用小写的事件属性名称,支付宝小程序使用的是小驼峰的事件属性名称。需要注意的是微信小程序比支付宝小程序健壮许多,一些微信小程序支持的事件支付宝小程序是不支持的。

微信小程序事件,支付宝小程序事件。

5.数据绑定

微信小程序和支付宝小程序都是在axml/wxml中使用 {{}} 绑定js中的数据。需要注意的是,支付宝小程序的axml中不支持相对复杂处理。

比如微信小程序中使用如下判断是有效的:

<view class="common-button" wx:if="{{detail.show['a_1'] || detail.show['a_2']}}" bindtap="handleA">A按钮</view>

但是在支付宝中直接使用 a:if="{{detail.show[‘a_1’] || detail.show[‘a_2’]}}" 无效,需要将判断简化。先在data中定义一个变量,再在axml中直接使用

<view a:if="{{showButtonA}}">A按钮</view>

js中代码如下:

{data: {showButtonA: false,},methods: {init () {const { show = {} } = detail;const { a_1, a_2 } = show;this.setData({showButtonA: a_1 || a_2,});},}
}

微信wxml,支付宝axml。

6.生命周期

这部分直接引用官方文档里的描述文本以及图片。更多生命周期相关内容,查看:微信小程序App、微信小程序页面生命周期、微信小程序注册页面、支付宝小程序页面运行机制。

首先看看官网给出的小程序的生命周期示意图:

微信小程序生命周期:

支付宝小程序生命周期

APP生命周期

微信小程序&支付宝小程序

App({onLaunch (options) {}, // 小程序初始化完成时触发,全局只触发一次onShow (options) {}, // 小程序启动,或者从后台进入前台时触发onHide () {}, // 小程序从前台进入后台时触发onError (msg) {}, // 小程序发生脚本错误或 API 调用报错时触发。globalData: '全局数据'
});

这里的前台和后台指的是用户是否在使用小程序,当用户在使用小程序的时候,相当于在前台,当用户点击右上角的退出按钮退出小程序时相当于进入后台。
虽然微信小程序和支付宝小程序生命周期回调函数参数的属性略有不同,但常用的几个基本是一样的,比如onLaunch和onShow的options参数的以下属性:

options的属性 属性值的类型 代表的 意义
path string 启动小程序的路径
scene number 启动小程序的场景值
referrerInfo Object 来源信息
页面的生命周期

微信小程序和支付宝小程序注册页面时常用的几个生命周期基本相同。

微信小程序&支付宝小程序

Page({onLoad: function(options) {},  // 页面创建时执行onShow: function() {}, // 页面出现在前台时执行onReady: function() {}, // 页面首次渲染完毕时执行onHide: function() {}, // 页面从前台变为后台时执行onUnload: function() {},  // 页面销毁时执行
});

这里的前台和后台指的是否是当前页面。比如从页面A跳转到页面B,那么B页面进入前台(onLoad、onShow、onReady),A页面进入后台(onHide)。如果按A页面的左上角的返回按钮,那么A页面被销毁(onUnload)

微信小程序页面路由。

组件的生命周期

微信小程序App的生命周期和页面的生命周期基本相同,但是组件的生命周期的声明方式有很大不同。

微信小程序组件
Component({behaviors: [], // behaviors用于引入组件间共享的属性、数据、方法、生命周期函数properties: { // 从父组件中传入组件的属性contactInfo: {type: Object,value: null,observer(newVal, oldVal) { // 监听从父组件中传入的属性的变化if (newVal) {this.doSomthing();}},},},data: {}, // 组件的数据lifetimes: { // 生命周期函数created: function () {}, // 组件实例刚刚被创建时执行attached: function () {}, // 组件实例进入页面节点树时执行ready: function () {}, // 组件在视图层布局完毕执行moved: function () { }, // 组件实例被移动到节点树的另一个位置时执行detached: function () {}, // 组件实例从页面节点树移除时执行error: function (err) {}, // 组件方法抛出错误时执行},// 小程序基础版本库2.2.3之前的生命周期函数在这里声明attached: function () { }, ready: function() { },pageLifetimes: { // 组件所在页面的生命周期函数show: function () { }, // 组件所在的页面被展示时执行hide: function () { }, // 组件所在的页面被隐藏时执行resize: function () { }, // 组件所在的页面尺寸变化时执行},methods: {doSomething () {console.log('doSomething');},}
})
支付宝小程序组件
Component({mixins:[ // mixins用于引入组件间共享的属性、数据、方法、生命周期函数],props:{ // 外部传入的属性},data: {  // 组件内的数据},onInit(){ // 组件创建时触发},didMount(){ // 组件创建完毕触发},didUpdate(prevProps,prevData){ // 组件更新完毕触发},didUnmount(){ // 组件删除时触发},methods:{doSomething(){console.log('doSomething');},},
});

微信小程序组件的生命周期、支付宝小程序组件的生命周期。

7.监听父组件传递给子组件的属性值的变化

微信小程序

微信小程序直接使用observer属性,在传入子组件的属性变化的时候会触发observer对应的函数,newVal是属性的最新值。

Component({properties: {currentStatus: { type: String,value: 'all',observer: function (newVal, oldVal) {this.doSomething();},},},...

父组件的wxml中使用组件:

<component-a currentStatus="{{currentStatus}}" bind:changeStatus="changeStatus"/>

当传入的属性currentStatus变化的时候,就会触发observer对应的函数。

支付宝小程序

根据支付宝小程序文档中的问答,目前还没有像observer那样直接的监听父组件传入子组件的属性值变化的方法。支付宝中可以使用didUpdate代替。

didUpdate 为自定义组件数据更新后的回调,每次组件数据变更的时候都会调用。

要注意的是不论是props改变还是data改变 ,都会触发didUpdate,所以在使用didUpdate根据属性值的变化做一些处理的时候一定要小心,及时返回。

didUpdate (prevProps) {const { currentStatus } = this.props;const prevCurrentStatus = prevProps.currentStatus;if (currentStatus === prevCurrentStatus) return;this.doSomething();
},

如果只需要初始化一次的话,可以设置标志位表明是否初始化过:

Component({props:{ // 外部传入的属性selectSkuData: {},},initialized: false,didUpdate(prevProps,prevData){ // 组件更新完毕触发const { selectSkuData } = this.props;if (this.initialized) return;if (selectSkuData && Object.keys(selectSkuData).length > 0) {this.init();}},methods:{init() {...this.initialized = true; }
});

8.子组件中的事件改变父组件中的数据

微信小程序

子组件中的wxml部分:

<view wx:for="{{statusOptions}}" wx:key="index" data-value="{{item.value}}" data-index="{{index}}"class="list-item {{currentStatus === item.value ? 'selected' : ''}}"bindtap="changeStatus">{{item.label}}</view>

子组件中的js部分:

methods: {changeStatus(event) {const { value } = event.target.dataset;...this.triggerEvent('changeStatus', { status: value });},
},

父组件中的wxml部分:

<component-a currentStatus="{{currentStatus}}" bind:changeStatus="changeStatus"/>

父组件中的事件,为了方便,绑定的事件名称和调用的事件名称我使用了一样的,这里的事件名称也可以用别的,比如 bind:changeStatus=“handleA”

父组件中的js部分:

changeStatus(event) {const { status } = event.detail;this.setData({currentStatus: status,});...
},
支付宝小程序

子组件中的axml部分:

<view a:for="{{statusOptions}}" a:key="index" data-value="{{item.value}}"class="list-item {{currentStatus === item.value ? 'selected' : ''}}"onTap="changeStatus">{{item.label}}</view>

子组件中的js部分:

changeStatus(event) {const { value } = event.target.dataset;...this.props.onChangeStatus({ status: value });
},

父组件中的axml部分:

<component-a currentStatus="{{currentStatus}}" onChangeStatus="changeStatus"/>

父组件中的js部分:

changeStatus(data) {const { status } = data;this.setData({currentStatus: status,});...
},

注意:

子组件中调用方法this.props.onChangeStatus({ status: value });相当于间接调用父组件中定义的方法,函数拿到的参数直接是子组件调用时传的参数,但是微信小程序中父组件绑定的事件拿到的参数是微信小程序的event对象,要通过event.detail才能拿到传递的数据。
2.给子组件绑定的事件属性一定要以on开头,比如上文的onChangeStatus,我试了下换成以handle开头的话,子组件件中拿到的数据是一个字符串而不是一个函数。

不论支付宝小程序还是微信小程序,如果组件是嵌套的,遇到如下这种情况:
页面A包含组件a, 组件a中包含组件b,当点击组件b的时候,需要触发页面A中的某个事件,那在组件a中也要定义方法。以支付宝小程序为例:

页面A

changeData () {console.log('doSomething');
}

在页面A中使用组件a:

<component-a onChangeData="changeData"
/>

组件a

Component({props: {onChangeData: () => {}},methods: {onChangeData () {console.log('组件a中定义的事件');this.props.onChangeData();}}
})

组件a中使用组件b

<component-b onChangeData="onChangeData">

这里从组件a传递到它的子组件b中的属性onChangeData是在组件a的methods中定义的方法。

在组件b中定义方法

  props: {onChangeData: () => {}},methods: {onChangeData () {console.log('组件b中定义的事件');this.props.onChangeData();}}

当触发组件b中的onChangeData方法时,就会触发页面A中的changeData方法。

只使用

(1)在页面A中使用入组件a:

<component-a onChangeData="changeData"
/>

(2)在组件a中使用组件b:

<component-bonChangeData="onChangeData">

不在组件a中定义方法的话,(2)中传递给onChangeData的值是null,而不是changeData。

9.获取组件实例

微信小程序

父组件的wxml部分:

<component-a id="componentA" />

父组件的js部分:

this.componentA = this.selectComponent('#componentA');
支付宝小程序

父组件的axml部分:

<component-a ref="saveComponentA" />

父组件的js部分:

saveComponentA(ref) {this.componentA= ref;
},

10.API

微信的API都放在wx下,比如wx.canIUse,支付宝的API都放在my下,比如my.canIUse。以下是这次项目用到的API的差异:

1.请求

微信小程序
wx.request({url: 'https://www.test.com/test/',data: {a: 'valueA',b: 'valueB',},header: {'content-type': 'application/json',},success: (res) => {},fail: (err) => {},complete: () => {},
})

wx.request中的method可以是GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT,里面没有PATCH方法,因为目前项目中没有使用到PATCH请求,所以只简单放一个在微信开放社区中的不支持PATCH请求的解决方案:wx.request()不支持PATCH请求。

支付宝小程序

my.request 目前支持 GET/POST/PUT(其中 PUT 请求在支付宝客户端 10.1.92 或更高版本支持)。

如上所示支付宝小程序支持的请求方式比较少,但是项目中用到了PUT、DELETE请求,无法避免。由后端解决了这个问题。前端传递参数的时候传递一个my.request的headers中加一个原本不存在的属性,当后端收到这个属性的时候,以这个属性值作为真正的请求方式。

my.request({url: 'https://www.test.com/test/',method: 'POST',data: {a: 'valueA',b: 'valueB',},headers:{'content-type':'application/json','useMethod': 'DELETE',},dataType: 'json',success: (res) => {},fail: (res) => {},complete: (res) => {},
});

当后端接收到useMethod属性时,会以useMethod的值作为真正的请求方式。

还要注意的是wx.request()无论请求的状态码是什么(200也好401也好),只要请求本身是成功了的,就会触发success函数,但是my.request()在状态码为200-300之间才会触发success,请求返回代表失败的状态码(比如401)时,会触发fail。

2.拨打电话

微信小程序:

wx.makePhoneCall({phoneNumber: '12345',success: (res) => {},fail: (err) => {},complete: () => {},
});

支付宝小程序:

my.makePhoneCall({number: '12345'
});
3.复制文本到剪切板
微信小程序

设置系统剪切板的内容:

wx.setClipboardData({data: '被复制的数据',success: () => {},fail: () => {},complete: () => {}
})

获取系统剪切板的内容:

wx.getClipboardData({success ({ data }) {console.log(data); // data是拿到的系统剪切板的内容},
})
支付宝小程序

设置系统剪切板的内容:

my.setClipboard({text: '被复制的内容',success: () => {},fail: () => {},complete: () => {},
});

获取系统剪切板的内容:

my.getClipboard({success: ({ text }) => {console.log(text); // text是拿到的系统剪切板的内容},
});
4.交互

项目中经常会用到交互API,这里不一一列举出来了,不记得的时候去下面两个路径中查找。

微信小程序界面交互、支付宝小程序交互反馈。

5.其他

微信小程序和支付宝小程序中文件的导入导出有不同。按照项目中的代码简化如下:

有文件a.js:

let a = 111;export function getA() {if (a === 111) {a = 222;}if (a === 222) {a = 111; }return a;
}

在页面1和页面2中都引用了a.js文件,使用方式如下:

import { getA } from '相对路径/a.js';Page({onLoad() {const a = getA(); console.log(a);}
})

用户首先进入页面1,然后进入页面2。
在微信小程序中,页面1打印出的内容是222,页面2打印出的内容是111。因为a.js中的代码只在第一次import的时候执行了一次。
但是在支付宝小程序中(在开发者工具上是和微信小程序一样的效果,但是在真机上不同),真机上进入页面1和页面2的时候,都会执行a.js中的代码,都会初始化a为111,所以两次打印出的内容都是222。

微信小程序和支付宝小程序对应的差异相关推荐

  1. 实现微信小程序和支付宝小程序二维码合并

    实现微信小程序和支付宝小程序二维码合并,这样用户就可以通过同一个二维码进入微信或者支付宝啦 1.需要准备可以通过公网访问的服务器 2.微信小程序 打开微信小程序后台->开发(左边)->开发 ...

  2. 跳转微信小程序和支付宝小程序

    跳转微信小程序和支付宝小程序 微信小程序 参考链接 获取微信小程序 URL Scheme 如何获取 需要联系小程序开发者或者其他渠道获取长期有效的 Scheme 示例 小程序 Scheme (测试小程 ...

  3. uni-app实现微信小程序,支付宝小程序,微信、支付宝、银联多商户收款

    uni-app实现微信小程序,支付宝小程序,微信.支付宝.银联多商户收款 前言 前言 哈哈哈,这个标题起得有点啰嗦.不过内容还是很真实有效的. 先说下需求吧.就是用户通过扫小程序码.实现微信app扫进 ...

  4. 微信小程序转支付宝小程序工具

    现在市面上各大厂商都推出了小程序.那么我们每一次都得从新进行开发,做开发的很多朋友都遇到过这类的问题,今天像素科技就分享一款工具可以快速让微信小程序转支付宝小程序. Antmove - 小程序转换器, ...

  5. 小程序开发过程中常见问题[微信小程序、支付宝小程序]

    小程序开发过程中常见问题[微信小程序.支付宝小程序] 正文 一.样式中如何使用background-image呢? background-image支持网络的图片链接或者base64 二.使用自适应单 ...

  6. dedecms小程序插件升级到1.4.4(支持百度小程序,微信小程序,头条小程序,QQ小程序,支付宝小程序...)

    从2019年6月份开发到现在 dede织梦小程序插件已经升级到1.4.4版本,现在已经支持:微信小程序,百度小程序,头条/抖音小程序,QQ小程序,支付宝小程序. dedecms小程序插件目前主要的功能 ...

  7. CML更新 | 新增百度小程序、支付宝小程序

    祝所有工程师小伙伴开工大吉,Beatles 团队已经开始忙碌起来了. 几个事情要向诸位汇报一下: 一.新增百度小程序.支付宝小程序 发布alpha版本支持百度小程序.支付宝小程序,已有项目可以无缝直接 ...

  8. uni-app跨端开发H5、微信小程序、支付宝小程序遇到的坑

    文章目录 微信支付宝小程序通用功能 1.checkbox样式 2.分享功能 支付宝小程序参数 微信小程序参数 其他兼容问题 H5 微信小程序 支付宝小程序 持续更新中... 微信支付宝小程序通用功能 ...

  9. Picker——uniapp[uview]微信小程序兼容支付宝小程序

    博主uview-ui版本1.8.3 PICKER-时间选择组件-生日范围选择 my.datePicker 支付宝小程序api提供地址:在这里~ 地址:https://opendocs.alipay.c ...

最新文章

  1. 趣谈Linux操作系统学习笔记:用户态内存映射:如何找到正确的会议室?(第25讲)...
  2. spring mvc 中文乱码 post与get的方法解决
  3. DRUID连接池的实用 配置详解
  4. jdbc事务和事务的隔离级别
  5. linux 域账户密码忘记,linux基础命令-用户域用户组管理
  6. JAVA安装报1620错误_java安装错误1620
  7. Spring定时任务@scheduled多线程的使用(@Async注解)
  8. c# json转换实例
  9. 【R语言】如何直接调取Wind、iFinD数据接口教程
  10. java根据word模板导出word文件
  11. 为谷歌浏览器Chrome创建多个用户
  12. 苹果马桶iPoo,果粉还hold住吗
  13. 为什么百度蜘蛛不对网站进行抓取?
  14. 谷歌发布语义分割新数据集!
  15. java动物声音模拟器_动物声音模拟器app|动物声音模拟器下载_v9.2.3_9ht安卓下载...
  16. pytorch Fashion MNIST 数据集下载慢怎么办
  17. Vue 将毫秒转换为天 小时 分钟 秒 / 毫秒转 小时 分钟
  18. 【综合评价分析】topsis评价 原理+完整MATLAB代码+详细注释+操作实列
  19. 每日技术新闻汇_2019-8-26
  20. unity survival shooter ZSpace

热门文章

  1. 【测试】对淘宝购物车的测试用例设计
  2. 无盘服务器玩游戏卡屏,电脑玩游戏卡屏怎么办 电脑玩游戏卡屏的解决方法
  3. bootstrap支付宝充值html,jQuery+Bootstrap手机端支付宝金额充值表单页面代码
  4. 乡村版《小时代3》 转自豆瓣
  5. UVA - 11624  Fire! 两次BFS
  6. java程序员的浪漫代码_专属于程序员的浪漫-Java输出动态闪图iloveyou
  7. 如何使用时间序列数据去酿酒
  8. 双乳囊性结节2级严重吗 吃什么能消除乳房结节
  9. 使用随机数实现扑克牌洗牌的算法(弱智版)
  10. 网站设为首页,加入收藏夹