Different small program development

Different small program development
Regarding the development of the WeChat applet, I have always wanted to write a summary and record of a related article. As a result, I have committed a procrastination and did not write it; this is not the weather recently, so I found a free afternoon to output this article (it seems to be related to the weather It doesn't matter)!

Note: This article assumes that the developer has a certain grammatical basis for WeChat applet development.

Mini Program Summary

  In the development process of the WeChat applet that we contacted, it is not difficult to find that the WeChat applet encapsulates many low-level apis for the convenience of developers, such as interface requests wx.request(), routing jumps and page navigation wx.switchTab、wx.navigateTo···. Although the development is simplified to a certain extent, it is not enough for the systematic construction of project engineering. Therefore, I compared my previous experience based on Vue development projects and my own development habits, and summarized the following 3 points for reference:

  • 1. Unified management of global variables and configuration information;

  • 2, package routing guard related api: vue-routerin router.beforeEach()and router.afterEach()really incense;
  • 3. The interface requests public information to be further extracted and packaged;
  • 4. The request and response interception api of the encapsulation interface: both the axiosones axios.interceptors.request.use()and the axios.interceptors.response.use()used ones are good;

Starting from the above four points, standardizing and optimizing the WeChat applet initialization project can greatly improve development efficiency and project maintenance management. The benefits of encapsulation are not only reflected in the convenience of invocation, but also in the convenience of management. At the same time, the centralized processing of common operations can greatly reduce the complexity of repetitive code.

1. Project initialization

   Create a new WeChat applet project, and create the following directories and files under the project:

  • config folder: unified management of configurable information and variables;
    • erroList.js: Interface error 错误码matching list file;
    • globalData.js: 全局变量unified management file (equivalent to vuex);
    • keys.js: Configurable system information management file (global constant naming, etc.);
  • Pages folder: Mini program page file management folder (a subfolder directory for each page);
  • router folder: routing management files;
    • router.js: 5种路由导航encapsulation of WeChat applet api;
    • routerConfig.js: page routing name and path matching configuration file;
    • routerFilter.js: routing pre- 拦截encapsulation;
  • servers file: interface request service management folder;
    • apis folder: request package management and interface api configuration management folder;
    • request.js: on wx.requestthe Promisepackage;
    • xxx.js: the interface management file of the corresponding module;
    • requestFilter.js: interface 请求和响应拦截package file;
  • Others are initialized default files;

Different small program development

Two, route jump and route guard encapsulation

1. Route jump encapsulation

  The official WeChat applet documentation provides developers with 5 types of apis for routing jumps, each of which has its own specific usage:

Different small program development

  According to its usage, we encapsulate the routing api as follows: WeChat applet routing jump is the last corresponding push、replace、pop、relaunch、switchTab; routescorresponding to the configuration of the routing path in routerFilterrouteConfig.js ; corresponding to the routerFilter.js file, processing the logic before the routing jump;

routeConfig.js (need to be manually added after each new page):

export const routes = 
  {
    INDEX: "/pages/index/index",
    TEST: "/pages/test/test",
  }
export default {...routes};

routerFilter.js:

export default () => {
  ···
  //路由跳转前逻辑处理
}

router.js (routerFilter is responsible for the processing of public operations before the route jump, and the public operations after the route jump are processed in success and fail):

import routes from "../router/routerConfig";
import routerFilter from "./routerFilter"

/**
 * 对wx.navigateTo的封装
 * @param {路由} path 
 * @param {参数} params 
 * @param {事件} events 
 */
const push = (path, params, events) => {
  routerFilter()
  wx.navigateTo({
    url: routes[path] + `?query=${JSON.stringify(params)}`,
    events: events,
    success(res) {
      console.log(res);
    },
    fail(err) {
      console.log(err);
    }
  })
}

/**
 * 对wx.redirectTo的封装
 * @param {路由} path 
 * @param {参数} params 
 */
const replace = (path, params) => {
  routerFilter()
  wx.redirectTo({
    url: routes[path] + `?query=${JSON.stringify(params)}`,
    success(res) {
      console.log(res);
    },
    fail(err) {
      console.log(err);
    }
  })

}

/**
 * 对wx.navigateBack的封装
 * @param {返回的层级} number 
 */
const pop = (number) => {
  routerFilter()
  wx.navigateBack({
    delta: number,
    success(res) {
      console.log(res);
    },
    fail(err) {
      console.log(err);
    }
  })
}

/**
 * 对wx.reLaunch的封装
 * @param {路由} path 
 * @param {参数} params 
 */
const relaunch = (path, params) => {
  routerFilter()
  wx.reLaunch({
    url: routes[path] + `?query=${JSON.stringify(params)}`,
    success(res) {
      console.log(res);
    },
    fail(err) {
      console.log(err);
    }
  })
}

/**
 * 对tabbar的封装
 * @param {路由} path 
 */
const switchTab = (path) => {
  routerFilter()
  wx.switchTab({
    url: routes[path],
    success(res) {
      console.log(res);
    },
    fail(err) {
      console.log(err);
    }
  })
}

module.exports = {
  push,
  replace,
  pop,
  relaunch,
  switchTab
}

2. Global registration and use

In app.jsrouting the encapsulated api global registration:

import router  from "./router/router.js"
//全局注册
wx.router = router

Used in page logic:

//index页面跳转test页面 
gotoTest(){
   wx.router.push("TEST")
}

Three, interface request Promise encapsulation

  For the same project, wx.request()many parameters in the WeChat applet api are the same. If you use it directly, you need to copy these repeated parameters over and over again. Although the copy is simple, you need to find all interfaces when one parameter changes. Modifying one by one, it takes a lot of effort to maintain, and it is uncomfortable to look at it;

Different small program development

  Drawing lessons from axiosthe encapsulation of requests, would n’t it be beautiful to wx.request()encapsulate in a Promiseform:

request.js:

import formatError from "../requestFilter"
const app = getApp()

/**
 * 接口请求封装
 * @param {请求方式} method 
 * @param {请求的url} url 
 * @param {请求传递的数据} data 
 */
const request = (method, url, data) => {
  //设置请求头
  const header = {
    ···
  }
  //promise封装一层,使得调用的时候直接用then和catch接收
  return new Promise((resolve, reject) => {
    wx.request({
      method: method,
      url: app.globalData.host + url, //完整的host
      data: data,
      header: header,
      success(res) {
        //对成功返回的请求进行数据管理和统一逻辑操作
        ···
        resolve(res.data)
      },
      fail(err) {
        wx.showToast({
          title: '网络异常,稍后再试!',
          mask: true,
          icon: 'none',
          duration: 3000
        })
      }
    })
  })
}
export default request;

Specific use

Take user.js as an example:

import request from "./request";

// 获取用户openid
export const usrInfos = data => request("POST", "/user/usrInfos", data);

Index page call:

//index.js
//获取应用实例
const app = getApp()
import { usrInfos } from "../../servers/apis/user"

Page({
  onLoad: function () {
    //获取用户信息
    usrInfos({
      uid: "xxxx"
    })
      .then(res => {
        console.log(res)
      })
      .catch(err => {
        console.log(err)
      })
  }
})

Fourth, the interface request and response interception package

  axiosThe axios.interceptors.request.use()and axios.interceptors.response.use()respectively correspond to the interception processing before the interface request and the interception processing after the data response; according to this principle, we also intercept and encapsulate the response of the WeChat applet, and uniformly manage the output of the error returned by the interface request:

request.js

import formatError from "../requestFilter"
const app = getApp()
···
const request = (method, url, data) => {
  ···
  return new Promise((resolve, reject) => {
    wx.request({
      ···
      success(res) {
        //对成功返回的请求进行数据管理和统一逻辑操作
        if(res.statusCode === 200){ //请求返回成功
          if(res.data && res.data.code === "SUCCESS"){ //后端对接口请求处理成功,返回数据给接口调用处
            resolve(res.data)  //then接收
          }else{        //后端对也请求判断后认为不合逻辑报错
            formatError(res)   //统一的报错处理逻辑
            reject(res.data)    //catch接收
          } 
        }else{
          reject(res.data)      //catch接收
        }
      },
      fail(err) {       //请求不通报错
        wx.showToast({
          title: '网络异常,稍后再试!',
          mask: true,
          icon: 'none',
          duration: 3000
        })
      }
    })
  })
}
export default request;

requestFilter.js

You can do a lot of error processing in requestFilter.js, here is a simple toast processing demonstration:

/**
 * 对接口返回的后端错误进行格式转化
 * @param {接口成功返回的数据} res 
 */
const formatError = (err =>{
  wx.showToast({
    title: err.message,
    mask: false,
    icon: 'none',
    duration: 3000
  })
}

export default formatError;

The unified handling of errors requires clear data regulations:

  • Formulate a unified error code management standard;
  • Develop a unified interface request data return format for the front and back ends;

Five, global data management

  The management of data is not so important in the development of small projects, but as the project gets bigger and more data, a good data management solution can effectively avoid many bugs. This is also vuex can be in vue Reasons for a place in the ecology. Adhering to the principle of reasonable data management, resolutely encapsulate the encapsulated data, and resolutely manage the configuration of the sub-module management:

globalData.js

The global data management in app.jsthe WeChat applet is placed in the globalDataattribute. When there is too much data or the app.js logic is too complicated, it is indeed a good solution to extract the global data and manage it separately:

export default {
  ···
  host: "http://www.wawow.xyz/api/test", //接口请求的域名和接口前缀 
  hasConfirm: "" //是否已经有了confirm实例
  currentPage: ""
  ···
}

keys.js

Keys.js is a customary operation in personal development. Some constant names that may be used in the project are centrally managed here, which is very convenient to call, modify and maintain:

export default {
  ···
  TOKEN: "token",
  STORAGEITEM: "test"
  ···
}

Global reference and registration

Introduce app.js:

import router  from "./router/router.js"
import keys from "./config/keys"
import globalData from "./config/globalData"
//全局注册
wx.router = router
wx.$KEYS = keys

//app.js
App({
  //监听小程序初始化
  onLaunch(options) {
    //获取小程序初始进入的页面信息
    let launchInfos = wx.getLaunchOptionsSync()
    //将当前页面路由存入全局的数据管理中
    this.globalData.currentPage = launchInfos.path
  },
  ···
  //全局数据存储
  globalData: globalData
})

use

Logic code in the page by app.globalData.host, wx.$KEYS.TOKENway call;

Six, summary

  The above aspects of WeChat applet development are all learned and summarized in practice. The technical realization is actually very easy, but I personally think that the development of standard project construction is the important foundation of a project; perfect specifications can be effective Improve development efficiency and non-essential among developers 扯皮! Reasonable project construction can optimize the development logic, improve the legibility of code logic, reduce the management time of later projects, and give the project greater scalability.

  Welcome everyone to discuss, leave a message, and make supplements!

Guess you like

Origin blog.51cto.com/15066867/2587054