To get through the game of life arena and offline businesses O2O cohesion, at the same time the response current hot WeChat applet day by day, the project team decided to also develop a targeted WeChat small procedures, in order to convenient stores in our platform into and challenge event creation and rewards to cancel after verification, further promote arena play mode and source. The following is our team as the department of the first batch of crabs, in this micro channel small program development process stepped on some pits and summary, to share with you, but also welcome correction and exchange.

Author: a LiangWu | tencent entertainment senior development engineer In this paper, byWechat platform developmentPublished inTencent Cloud + community

At present [Tencent Game life] small program has been released online, you can scan small program code to experience. Next, it mainly introduces some thinking and accumulation in the process of developing this small program.

1. Popularization of the foundation

1.1 introduction

Wechat small program is the fourth type of application in wechat launched by the wechat public platform, besides the service number, subscription number and enterprise number. It is a brand new way to connect users and services. It can be easily obtained and spread in wechat, and has excellent interactive use experience and practical functions imitating the original APP.

We can easily register small programs and submit information on the wechat public platform, which is more consistent with the registration process of the wechat public account.

1.2 configuration

User configuration: small program management platform provides user management functions, support to add one administrator, according to the account type and authentication support to configure different number of developers and experiencers account permissions, these configurations in small program development and beta stage is very useful, that is, an official whitelist configuration function.

Development configuration: Similar to the development and access configuration of other wechat public accounts, it is necessary to set the developer ID and key, server domain name configuration, development message access address and other information respectively, which can be set by referring to the small program development document one by one. For students who have experience in developing public accounts, it is also relatively quick to start. Note that all domain names must be HTTPS service domain names.

Second, development attention

2.1 Page Model

A small program consists of an APP describing the overall program and a number of pages describing their respective pages, which can be seen as a series of pages combined integration, scheduled by a global APP object. Page model is an important concept in applets, which can also be seen in the applets configuration file app.json (as shown below), where the page address registered can be invoked and displayed. The display page of the applet is mainly divided into tabbar page and regular page, and only tabbar page will have the bottom tabbar display, and the corresponding jump mode API of the two kinds of pages is also different:

  • For tabbar page address (e.g. Page/XXX/XXX), call **wx.switchTab(OBJECT)** to jump;
  • NavigateTo (OBJECT) or wx.redirectto (OBJECT)** to jump to a regular page address (e.g. Page/XXX /x1)
{
  "pages": [
    "page/xxx/x1"."page/yyy/y1"]."window": {
    "navigationBarTitleText": "test"
  },
  "tabBar": {
    "list": [{
      "pagePath": "page/xxx/xxx"."iconPath": "image/xxx.png"."text": "tab1"
    }, {
      "pagePath": "page/yyy/yyy"."iconPath": "image/yyy.png"."text": "tab2"}},"networkTimeout": {
    "request": 10000."uploadFile": 10000
  },
  "debug": true
}
Copy the code

For a specific page model, there are internal independent logical and data scopes. The file consists of four components and must have the same path, directory, and file name, for example, index.js, index. WXML, index. WXSS, and index.json in the /page/index/ directory corresponding to the home page.

Page initialization, rendering, interaction and other logic can be through the page JS event monitoring and function calls for response and processing, similar to do web front-end development, just need to pay special attention to the JS development and web front-end JS development part of the difference:

  • Page logic runs in Jscore, which is not webView and has no DOM object structure such as window, body and Document.
  • Without page cookie, the refer of network request header cannot be set.
  • Object pickup plug-ins and operation modes such as jquery and Zepto are not supported. View update is implemented through data binding.
  • The page display structure is mainly displayed by the official native components, and the response control is carried out by the corresponding supported limited event functions, and the expansion is low;
  • Page data changes by calling the Page. SetData function to display the Page component display, Page component action event value; E.dail. value can be passed to the event response function to reset the page data to achieve linkage binding between the page data and the component

2.2 Life Cycle

The running of the small program and the display of each page have their specific life cycle, and through a series of declared cycle functions for scheduling control. For example, app global instance onLaunch, onShow, onHide and other listening functions to respond to the control logic of small program initialization and development. The page page has a richer monitoring and control function to achieve more control of the page life cycle.

The function definitions The functionality
onLoad Life cycle function – listens for page loads
onReady Life cycle function – Listens for the page to complete its first rendering
onShow Life cycle function – Listens for page display
onHide Life cycle function – Listens for page hiding
onUnload Life cycle function – Listens for page unload
onPullDownRefresh Page-dependent event handlers – listen for user drop-down actions
onReachBottom Page-specific event handlers – listen for user pull-up actions

The following diagram illustrates the life cycle of an applet page instance:

The display management of switching between multiple pages within the applet is managed by the applet framework routing and page stack control, and page switching is carried out by route label or navigation API function. If onHide is not displayed in the background but onUnload is not destroyed after the page is initialized for the first time, the next time the page is displayed again, the onLoad listener is not triggered, but the onShow listener is triggered. OnShow is triggered at the initialization of the page or every time it is displayed, so there is a little trick here. Some of the data that needs to be updated in real time to be displayed to the page can be retrieved and processed in onShow.

Third, data processing

3.1 Data Request

The network request in the applet is mainly realized by **wx.request(OBJECT), wx.uploadFile(OBJECT)** and other apis accessing the HTTPS domain name URL interface configured by the applet. The former is similar to Ajax requests, while the latter are often used to upload image files and so on. There are some holes in the request API to be aware of:

  • The header refer is not supported.
  • The requested URL cannot contain a custom port, only the default port 80.
  • Content-type: **’application/json’, ‘application/x-www-form-urlencoded’ or ‘multipart/form-data’** if POST is required, ‘application/x-www-form-urlencoded’ or ‘multipart/form-data’** Otherwise, the background request will not get the POST data;
  • In PHP, it is better to use Json_decode (file_get_contents(” PHP :// INPUT “)) to obtain the complete POST data. Otherwise, if the more complex multi-layer POST data structure is transmitted, the direct use of $_POST may lead to the acquisition of data format abnormalities or failure

The data request operations in the mini-program preferably require logon state security verification. Here, we copy the wechat authorization verification method of the H5 project before, encrypt the openID and other data obtained after invoking wechat login and authorization, and obtain a ticket ticket with an expiration time. Each data request of the applet needs to be verified with the openID and ticket parameters in the background PHP. If the request succeeds, subsequent requests and data are normally returned; if the request fails, the applet client is informed to log in and authorize again before requesting data. The core algorithm of the verification is also relatively simple, which is to determine whether the following equation is satisfied within the ticket validity period:

The initial ticket generation after login and authorization is also generated in the left form of the algorithm, and the local cache record of the applet is returned. The next request can be directly applied from the cache.

Finally, all the data requests in the small program are processed, which encapsulates the header Settings of GET/POST requests, the attachment and expiration processing of login parameters, the explicit and implicit control of the loading effect of requests and other logic, and is set in the app global object exposure method httpRequest, which is convenient to call processing in each sub-page.

Since our small program needs to display tabbar home pages in different states according to the user’s identity, we need to preload the request of user’s identity information. Here, we design a loading transition page, and just perform wechat login and authorization on this page, and get the initialization of login state parameters. After requesting the user’s identity, set it to the global data of app, and make corresponding judgment and display on the home page of Tabbar.

Home – Default Home page – To be reviewed Home page – Approved Home page – Rejected

3.2 Page Communication

We need the small program of business registration and create challenge function page, need to fill in the information and level is more, not a screen display and fill in, so you need to support data transfer between across pages and calls the communication ability, and the data is complete, effective and safe management, and real-time response page updates. Based on the API and characteristics provided by the small program itself, I also consulted some information, and mainly got the following ideas and methods:

category instructions advantages disadvantages
Navigate jump + URL parameter Jump with the required data as the URL parameter with the navigate tag or API jump No extra code or plug-ins, simple code The TABbar page does not support URL transmission parameters
Cache data is stored publicly The API of app’s globalData globalData or local cache Storage is used to realize data caching and common processing Global or local cache data acquisition and rewriting, convenient operation organized, easy to understand Note rewriting and destruction of global or cached data on relevant pages to ensure consistent data security and avoid arbitrary rewriting.
PubSub or Watcher mechanics Using the event publishing subscription or monitoring mechanism, the corresponding plug-in is developed, and the plug-in is introduced into each page to subscribe or monitor the required data. Based on plug-in data driven implementation, pages can be added to subscribe or monitor data processing as required, single data source, easy debugging Additional plug-ins need to be introduced, and repeated subscriptions or listening bindings caused by multiple show and hide pages need to be solved, which may lead to program crash risk
Page routing stack Use small program with getCurrentPages API to obtain the page routing stack, and according to the page number to obtain and operate the required page objects The code logic is clear, and it is more convenient to obtain and process the data of the required page object. The data is only a single copy of the original page object, and is destroyed by its internal custody, and there is no risk of data pollution. The modification of this data on the target page can be updated to the original page through the real-time response of setData You need to pay a little attention to the page stack depth variation and the acquisition of the required page objects

Considering that the form has a large amount of data, and the product requires the function of local draft of the form, we can display the data filled in last time when opening the form next time, without having to fill in it again. Therefore, we finally combine the functions of cache and page routing stack to realize the form. On the main page A of the form, localStorage is used to cache all the data of the form formData, and on the sub-page B, getCurrentPages is used to obtain and operate A sub-data of the form formData.subData of the main page A. Changes of subpage B are delivered in real time by A.setData and displayed as updates of main page A. Main page A responds to changes to LocalStoreage in onUnload for next loading and reading.

Four, code maintenance

4.1 Common Configuration

Customized information such as data, parameters, interfaces and copywriting involved in the small program code can be made into unified localized configuration and put into the global data of the app instance for public use, so as to facilitate the acquisition and processing of each sub-page. At the same time, remote update configuration can be requested in combination with the loading initialization of the small program. In this way, unified configuration management can be implemented when configuration information is updated or not. When configuration update is needed, it can be pulled from the remote replacement, without the need to modify the code file of the small program, and then go through the process of code release and waiting for review.

4.2 Diagram transmission components

In the small program registered business information and the creation of the arena are involved in the image upload processing, using the small program official picture style components and API, at the same time need to call the unified background upload picture generated URL interface. Therefore, it is necessary to optimize the code for modular packaging of components to facilitate the introduction of calls in multiple page pages.

  • picloader.wxml
<template name="picloader">
    <view class="weui-cells weui-cells_after-title">
        <view class="weui-cell">
            <view class="weui-cell__bd">
                <view class="weui-uploader">
                    <view class="weui-uploader__hd">
                        <view class="weui-uploader__title">{{title}}</view>
                    </view>
                    <view class="weui-uploader__bd">
                        <view class="weui-uploader__files">
                            <block wx:if="{{picture}}">
                                <view class="weui-uploader__file" bindtap="previewImage" data-obj="{{name}}">
                                    <image class="weui-uploader__img" src="{{picture}}" mode="aspectFill" />
                                </view>
                            </block>
                            <input id="{{name}}" name="{{name}}" hidden="{{true}}" value="{{picture}}"/>
                        </view>
                        <view class="weui-uploader__input-box">
                            <view class="weui-uploader__input" bindtap="chooseImage" data-obj="{{name}}"></view>
                        </view>
                    </view>
                </view>
            </view>
            <view class="weui-cell__ft"><icon type="{{validate}}"/></view>
        </view>
    </view>
</template>
Copy the code
  • picloader.js
const app = getApp();

function init(pageDelegate) {
  //1. Initialize the image upload seed HASH value
  app.httpRequest({
      url:app.Utils.getRequestUrl("getUploadHash"),
      success: function( res ) {
          if(res.r== "0"){
              pageDelegate.setData({
                  _hash:res._hash }); }}},false);

  //2. Bind the image selection event
  pageDelegate.chooseImage = function (e) {
    var that = this;
    var uploadUrl = app.Config.uploadBase;
    var obj = e.currentTarget.dataset.obj;// Change the object name
    if (e.currentTarget.dataset.ratio) {// The size is proportional
      uploadUrl += "? size_ratio=" + e.currentTarget.dataset.ratio;
    }

    wx.chooseImage({
        sizeType: ['original'.'compressed'].// You can specify whether the image is original or compressed. By default, both are available
        sourceType: ['album'.'camera'].// You can specify whether the source is photo album or camera, and default is both
        count:1.success: function (res0) {
            // Returns the list of local file paths for the selected photo. TempFilePath can display the image as the SRC attribute of the IMG tag
            app.uploadRequest({
                url:uploadUrl,
                filePath: res0.tempFilePaths[0].data: {_hash:that.data._hash
                },
                success:function(res){
                    var picurl = res.url || "";
                    var tmpData = {};
                    tmpData["formData." + obj] = picurl;
                    that.setData(tmpData);
                    app.Utils.checkValid(obj, picurl,that);
                    if(res.r ! ="0" && res.msg){
                      wx.showModal({
                        title: 'Image upload failed'.content: res.msg,
                        showCancel: false.success: function (res) {}}); }}})}})}//3. Bind the preview image event
  pageDelegate.previewImage = function (e) {
    var obj = e.currentTarget.dataset.obj;// Change the object name
    var pic = this.data.formData[obj] || "";
    if(pic == "") {return false;
    }
    
    wx.previewImage({
        current: e.currentTarget.id,
        urls: [pic] // HTTP link for images that need preview}); }}/ / modular
module.exports = {
  init: init
}
Copy the code
  • Using the sample WXML:
<import src="/page/common/picloader.wxml"/>
<template is="picloader" data="{{title: 'reward image upload picture: formData. Award_pic, validate: validate the award_pic, name:' award_pic '}}"/>
Copy the code
  • Using the sample JS:
const app = getApp();
var picloader = require('/utils/picloader.js');

Page({
  data:{
      ...
  },
  onLoad:function(options){
      // initialize the page. Options specifies the parameters for page hopping

      // Register the image upload component
      picloader.init(this); },... })Copy the code

4.3 Sharding Template

The requirement of the homepage of tabbar is to display the homepage of different states according to different users’ identities, including unregistered, pending review, approved review and rejected review, which all need to correspond to the same TABbar homepage URL. Therefore, it is necessary to make the page fragments of the four states into the form of sub-template WXML respectively, and display the corresponding sub-template through the conditional rendering (WX: IF) mechanism of the small program according to the user identity.

At the same time, many pages of the small program have a common header (banner) and tail (contact customer service) and other fragments to display, so it is also considered to make it into a corresponding common head and foot sub-template WXML, easy to include reference multiple pages.

<view class="page">
    <include src="/page/common/head.wxml"/>
    <view class="weui-msg">
        <include wx:if="{{status == 1}}" src="subpage/wait.wxml"/>
        <include wx:elif="{{status == 2}}" src="subpage/success.wxml"/>
        <include wx:elif="{{status == 3}}" src="subpage/fail.wxml"/>
        <include wx:else src="subpage/default.wxml"/>
    </view>
</view>
<include src="/page/common/foot.wxml"/>
Copy the code

Fifth, summarize the experience

[Tencent Game Life] the development of wechat mini program has been completed, and it is urgent to supplement the product terms and release the review online. In the whole process of exploration and development, encountered many different and Web development of the awkward place, also filled a lot of pits, including the design of small program implementation, reconstruction and front-end development is a new attempt and experience. There are also some thoughts and summaries, as follows. At present, I feel that the small program is more suitable for some small application mode aimed at promoting their lightweight functions more quickly and effectively, not suitable for the development of larger logic and functional applications. However, I believe that with the continuous increase of wechat official support for small programs, the functions and promotion of small programs will be further expanded, and the synchronization of access and development costs will be reduced. It will also be welcomed and loved by more and more developers.

advantage disadvantage
Low access threshold, easy access to refer to the public number, the current craze The official configuration and development mode is strict, and it needs to be set up within a limited range
Better use experience than H5, high fluency, small size, fast transmission benefit The functional experience is limited to component interaction, and the customization expansion is weak. Compared with the native APP experience and advanced functions, it is still less
Low learning cost, clear code organization, high development flexibility, clear development documents It does not support some common functions and features in Web development, and sometimes the development is inconvenient and limited.
Wechat has high official support, flexible embedding, small program closed-loop control, and safe and reliable data isolation H5 web page and external APP are not supported.

Has been authorized by the author tencent cloud + community release, the original link: https://cloud.tencent.com/developer/article/1145916?fromSource=waitui

Welcome to Tencent Cloud + community or follow the wechat public account (QcloudCommunity), the first time to get more mass technology practice dry goods oh ~