Record the differences between some alipay small programs and wechat small programs encountered in the process of moving wechat small program code to Alipay small program, so as not to go to the official documents every time.

1. File name extension

The four file suffixes of wechat applets are.js,.json,.wxml and.wxss, while the four file suffixes of Alipay applets are.js,.json,.axml and.acss.

Replace all WXML files in the current directory with axML and WXSS files with ACSS:

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

Use man rename to see more usage of rename. Linux Batch rename command to rename a file name. If ZSH: command not found: rename is displayed when executing the command, run brew install rename to install the file. If brew is not installed, run brew home installation command to install the file. Brew download error handling for Mac.

2. Control attributes

Wechat applets Alipay small program
wx:if a:if
wx:for a:for
wx:key a:key

A: in the AXML file corresponds to wx: in the WXML file.

3. The label

Wechat applets Alipay small program
<i>,<icon> <icon>
<span>,<text> <text>

Wechat applet supports

tag and < I >, but Alipay applet only supports

tag. After writing HTML5 tag habit, I prefer to write < I > and < SPAN >, but if you want to write alipay applet and wechat applet at the same time, It’s better to use the applet tags

and

directly.



4. Event attributes

Wechat applets Alipay small program
bindtap onTap
catchtap catchTap

Wechat applet uses lowercase event attribute names, while Alipay applet uses small hump event attribute names. It should be noted that wechat applet is much more robust than Alipay applet. Some of the events supported by wechat applet are not supported by Alipay applet.

Wechat mini program event, Alipay mini program event.

5. Data binding

Wechat applet and Alipay applet are used to bind js data in AXML/WXML using {{}}. It should be noted that relatively complex processing is not supported in AXML of Alipay mini program.

For example, it is valid to use the following judgment in wechat small program:

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

But in the alipay directly using a: if = “{{detail. Show [‘ a_1] | | detail. Show [‘ a_2]}}” null and void, need to simplify the judgment. Define a variable in data and use it directly in AXML

<view a:if="{{showButtonA}}">A button</view>
Copy the code

The code in js is as follows:

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

Wechat WXML, Alipay AXML.

6. Life cycle

This section directly quotes descriptions and images from official documents. For more life cycle related content, see: wechat applets App, wechat applets page life cycle, wechat applets registration page, Alipay applets page operation mechanism.

First, take a look at the schematic diagram of the life cycle of the applets on the official website:

The left picture shows the life cycle of wechat applets, and the right picture shows the life cycle of Alipay applets:


APP Life cycle

Wechat small program & Alipay small program

App({
  onLaunch (options) {}, // Triggered when the applet initialization is complete
  onShow (options) {}, // Triggered when a small program starts or enters the foreground from the background
  onHide () {}, // Triggered when a small program enters the background from the foreground
  onError (msg) {}, // Triggered when a script error or API call occurs in the applet.
  globalData: 'Global data'
});
Copy the code

The foreground and background here refer to whether the user is using the small program. When the user is using the small program, it is equivalent to the foreground. When the user clicks the exit button in the upper right corner to exit the small program, it is equivalent to entering the background.

Although the attributes of life cycle callback function parameters of wechat applets and Alipay applets are slightly different, the commonly used parameters are basically the same, such as the following attributes of options parameters of onLaunch and onShow:

The options of the attribute The type of the property value The meaning of representation
path string Path to start the applet
scene number The scenario value for launching the applet
referrerInfo Object Sources of information

Page life cycle

Wechat applet and Alipay applet registration page often used several life cycle is basically the same.

Wechat small program & Alipay small program

Page({
  onLoad: function(options) {},  // execute when the page is created
  onShow: function() {}, // execute when the page appears in the foreground
  onReady: function() {}, // execute when the page is first rendered
  onHide: function() {}, // execute when the page changes from foreground to background
  onUnload: function() {},  // execute when the page is destroyed
});
Copy the code

Here the foreground and background refer to whether the current page. For example, if you jump from page A to page B, page B goes to the foreground (onLoad, onShow, onReady) and page A goes to the background (onHide). If you press the back button in the upper left corner of page A, the page A is destroyed (onUnload).

Wechat applets page routing.

Component life cycle

The life cycle of wechat applets App is basically the same as the life cycle of pages, but the way of declaring the life cycle of components is quite different.

Wechat applets component
Component({
  behaviors: [].// Behaviors introduce properties, data, methods, and lifecycle functions that are shared between components
  properties: { // Pass in component properties from the parent component
    contactInfo: {
      type: Object.value: null.observer(newVal, oldVal) { // Listen for changes to properties passed in from the parent component
        if (newVal) {
          this.doSomthing(); }}},},data: {}, // Component data
  lifetimes: { // Lifecycle functions
    created: function () {}, // execute when the component instance has just been created
    attached: function () {}, // executed when the component instance enters the page node tree
    ready: function () {}, // Components are laid out in the view layer
    moved: function () {},// execute when the component instance is moved to another location in the node tree
    detached: function () {}, // executed when the component instance is removed from the page node tree
    error: function (err) {}, // executes when a component method throws an error
  },
  // Life cycle functions prior to the Applets Foundation library 2.2.3 are declared here
  attached: function () {},ready: function() {},pageLifetimes: { // The lifecycle function of the page on which the component is located
    show: function () {},// execute when the page of the component is displayed
    hide: function () {},// execute when the page where the component is located is hidden
    resize: function () {},// execute when the page size of the component changes
  },
  methods: {
    doSomething () {
      console.log('doSomething'); }}})Copy the code
Alipay small program components
Component({
  mixins: [// Mixins are used to introduce properties, data, methods, and lifecycle functions shared between components].props: {// External attributes passed in

  },
  data: {  // Data within the component

  },
  onInit(){ // Triggered when the component is created

  },
  didMount(){ // The component is created

  },
  didUpdate(prevProps,prevData){ // Component update completed

  },
  didUnmount(){ // Triggered when a component is deleted

  },
  methods: {doSomething(){
      console.log('doSomething'); ,}}});Copy the code

The life cycle of wechat applets and Alipay applets.

7. Listen for changes in property values passed from the parent component to the child component

Wechat applets

The wechat applet directly uses the observer attribute. When the attribute of the passed subcomponent changes, the function corresponding to the observer will be triggered. NewVal is the latest value of the attribute.

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

Using components in the PARENT component’s WXML:

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

When the passed property currentStatus changes, the observer corresponding function is fired.

Alipay small program

According to the q&A in the Alipay applet document, there is currently no direct way like observer to listen for changes in attribute values from parent components to child components. DidUpdate can be used instead in Alipay.

DidUpdate is a callback after a custom component data update. It is called every time the component data changes.

DidUpdate is triggered by changes in props and data, so be careful when using didUpdate to handle changes in property values.

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

If you only need to initialize it once, you can set the flag bit to indicate whether it has been initialized:

Component({
  props: {// External attributes passed in
    selectSkuData: {},},initialized: false.didUpdate(prevProps,prevData){ // Component update completed
    const { selectSkuData } = this.props;
    if (this.initialized) return;
    if (selectSkuData && Object.keys(selectSkuData).length > 0) {
      this.init(); }},methods: {init(){...this.initialized = true; }});Copy the code

8. Events in child components alter data in parent components

Wechat applets

The WXML part of the child component:

<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>
Copy the code

Js part of child component:

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

The WXML part of the parent component:

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

In the parent component, for convenience, I used the same event name for the binding as for the call, but I could have used other event names, such as bind:changeStatus=”handleA”.

The js part of the parent component:

changeStatus(event) {
  const { status } = event.detail;
  this.setData({
    currentStatus: status, }); . },Copy the code

Alipay small program

Axml part of child component:

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

Js part of child component:

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

Axml part of parent component:

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

The js part of the parent component:

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

Note:

  1. Calls methods in child componentsthis.props.onChangeStatus({ status: value });It is equivalent to indirectly calling the method defined in the parent component. The parameters obtained by the function are directly passed by the child component when it is called. However, the parameters obtained by the event bound by the parent component in the wechat applet are the event object of the wechat appletevent.detailTo get access to the transmitted data.

2. The event attribute bound to the child component must start with ON, such as onChangeStatus above. I tried to change it to start with Handle, and the data in the child component is a string instead of a function.

Whether alipay applet or wechat applet, if the components are nested, the following situation occurs: Page A contains component A, and component A contains component B. When clicking component B, an event in page A needs to be triggered, and A method needs to be defined in component A. Take Alipay mini program as an example:

A page

changeData () {
  console.log('doSomething');
}
Copy the code

Use component A on page A:

<component-a 
  onChangeData="changeData"
/>
Copy the code

Component a

Component({props: {onChangeData: () => {}}, methods: {onChangeData () {console.log(' events defined in Component A '); this.props.onChangeData(); }}})Copy the code

Component B is used in component A

<component-b
 onChangeData="onChangeData"
Copy the code

The property onChangeData passed from component A to its child component B is the method defined in component A’s methods.

Define methods in component B

Props: {onChangeData: () => {}}, methods: {onChangeData () {console.log(' events defined in component B '); this.props.onChangeData(); }}Copy the code

When the onChangeData method in component B is triggered, the changeData method in page A is triggered.

Use only

(1) Use component A in page A:

<component-a 
  onChangeData="changeData"
/>
Copy the code

(2) Use component B in component A:

<component-b
 onChangeData="onChangeData"
Copy the code

If a method is not defined in component A, the value passed to onChangeData in (2) is null, not changeData.

9. Obtain the component instance

Wechat applets

The WXML portion of the parent component:

<component-a id="componentA" />
Copy the code

Js part of the parent component:

this.componentA = this.selectComponent('#componentA');
Copy the code

Alipay small program

Axml part of parent component:

<component-a ref="saveComponentA" />
Copy the code

Js part of the parent component:

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

10.API

The API of wechat is placed under WX, such as wx.canIUse, and the API of Alipay is placed under My, such as my.caniuse. Here are the API differences used in this project:

1. The request

Wechat applets
wx.request({
  url: 'https://www.test.com/test/'.data: {
    a: 'valueA'.b: 'valueB',},header: {
    'content-type': 'application/json',},success: (res) = > {},
  fail: (err) = > {},
  complete: () = >{},})Copy the code

Method in Wx. request can be GET, HEAD, POST, PUT, DELETE, TRACE and CONNECT. There is no PATCH method, because PATCH request is not used in the current project. Therefore, we simply put a solution that does not support PATCH request in wechat open community: wx.request() does not support PATCH request.

Alipay small program

My.request currently supports GET/POST/PUT (where PUT requests are supported on Alipay client 10.1.92 or later).

As shown above, alipay applet supports fewer requests, but PUT and DELETE requests are used in the project, which cannot be avoided. This problem is solved by the back end. When the front end passes a my.request headers parameter, it adds a nonexistent attribute to the headers. When the back end receives the attribute, it uses the value of the attribute as the actual request.

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) = >{}});Copy the code

When the back end receives the useMethod attribute, the value of useMethod is used as the actual request.

Note also that wx.request() will trigger success regardless of the request’s status code (200 or 401) as long as the request itself is successful, but my.request() will only trigger success if the status code is between 200 and 300. Fail is triggered when a request returns a status code representing a failure, such as 401.

Wechat applets Request, wechat applets Network, Alipay applets Request.

2. Make phone calls

Wechat applets:

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

Alipay mini program:

my.makePhoneCall({
  number: '12345' 
});
Copy the code

3. Copy the text to the clipboard

Wechat applets

Set the contents of the system clipboard:

wx.setClipboardData({
  data: 'Replicated data'.success: () = > {},
  fail: () = > {},
  complete: () = >{}})Copy the code

Get the contents of the system clipboard:

wx.getClipboardData({
  success ({ data }) {
    console.log(data); // Data is the contents of the system clipboard}})Copy the code
Alipay small program

Set the contents of the system clipboard:

my.setClipboard({
  text: 'Copied content'.success: () = > {},
  fail: () = > {},
  complete: () = >{}});Copy the code

Get the contents of the system clipboard:

my.getClipboard({
  success: ({ text }) = > {
    console.log(text); // Text is the contents of the system clipboard}});Copy the code

4. The interaction

Interactive apis are often used in projects, which are not listed here. If you don’t remember, go to the following two paths.

Wechat mini program interface interaction, Alipay mini program interaction feedback.

5. Other

The import and export of files in alipay mini program and wechat mini program are different. The code in the project is simplified as follows:

There are files a.js:

let a = 111;

export function getA() {
  if (a === 111) {
    a = 222;
  }
  if (a === 222) {
    a = 111; 
  }
  return a;
}
Copy the code

Both page 1 and Page 2 refer to the a.js file as follows:

Import {getA} from 'relative path /a.js'; Page({ onLoad() { const a = getA(); console.log(a); }})Copy the code

The user first goes to page 1, then to page 2. In wechat mini program, the printed content on page 1 is 222, and the printed content on page 2 is 111. Because the code in A.js is executed only once on the first import. However, in the Alipay applet (which has the same effect as the wechat applet on the developer tool, but is different on the real phone), when the real phone enters page 1 and page 2, it will execute the code in A. js and initialize A as 111, so the content printed out twice is 222.