Home  >  Article  >  WeChat Applet  >  How to develop WeChat mini programs like a duck in water

How to develop WeChat mini programs like a duck in water

coldplay.xixi
coldplay.xixiforward
2021-03-30 10:51:371878browse

How to develop WeChat mini programs like a duck in water

 I have always wanted to write a related article to summarize and record the development of WeChat mini programs, but I have been suffering from procrastination and have not started writing. The weather has been nice recently, so I found a free time. I will output this article in the afternoon (it seems to have nothing to do with the weather), then let’s get started!

Note: This article assumes that developers have a certain grammatical foundation in WeChat applet development. Mini Program Development Document

Related free learning recommendations: WeChat Mini Program Development

WeChat Summary of Mini Programs

 During the development process of WeChat Mini Programs, it is not difficult to find that WeChat Mini Programs have well encapsulated many underlying APIs for the convenience of developers, such as for interface requestswx.request(), wx.switchTab, wx.navigateTo···, etc. for routing jumps and page navigation. Although it simplifies development to a certain extent, it is still not enough for the systematic construction of project engineering. Therefore, after comparing my previous experience in developing projects based on Vue and my own development habits, I summarized the following 3 points for reference:

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

  • 2. Encapsulation of route guard related APIs: vue-routerrouter.beforeEach() and router.afterEach() are really good;

  • 3. The interface requests public information for further extraction and encapsulation;

  • 4. The request and response interception API of the encapsulated interface: axios.interceptors.request.use() and axios of axios. interceptors.response.use()Everyone who has used it says it is 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 calling, but also in the convenience of management. At the same time, public operations are processed centrally, which greatly reduces complex and 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 reportingError codeMatching list file;
    • globalData.js:Global variablesUnified management files (equivalent to vuex);
    • keys.js: Configurable system information management files (global constant naming, etc.);
  • pages folder: small Program page file management folder (one sub-folder directory for each page);
  • router folder: routing management file;
    • router.js: WeChat applet5 A kind of routing navigationapi encapsulation;
    • routerConfig.js: page routing name and path matching configuration file;
    • routerFilter.js: route prefixinterceptionencapsulation ;
  • servers file: interface request service management folder;
    • apis folder: request request encapsulation management and interface api configuration management folder;
      • request.js: Promise encapsulation of wx.request;
      • xxx.js: The interface management file of the corresponding module;
    • requestFilter.js: InterfaceRequest and response interceptionEncapsulation file;
  • ##Others are initialization default files;

2. Route jump and route guard encapsulation

1. Route jump encapsulation

 WeChat The official documentation of the mini program provides developers with 5 routing APIs, each of which has its own special usage: Encapsulate as follows: WeChat applet route jump finally corresponds to

push, replace, pop, relaunch, switchTab

;

routes corresponds to the configuration of the routing path in routeConfig.js;

routerFilter

Corresponds to the routerFilter.js file, which processes the logic before route jump; routeConfig.js (needs to be added manually 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 processing public operations before routing jumps, and processing public operations after routing jumps 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

Global registration of the encapsulated routing api in

app.js

:

import router  from "./router/router.js"//全局注册wx.router = router
Use in page logic:

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

3. Interface request Promise encapsulation

 For the same project, many parameters in the WeChat applet api

wx.request()

are the same , if used directly, these repeated parameters need to be copied over and over again. Although copying is very simple, when a parameter changes, all interfaces need to be found and modified one by one, which is laborious to maintain and uncomfortable to watch;

  借鉴axios对请求的封装,将wx.request()封装为Promise形式岂不美哉:

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;

具体使用

以user.js为例:

import request from "./request";// 获取用户openidexport const usrInfos = data => request("POST", "/user/usrInfos", data);

index页面调用:

//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)
      })
  }})

四、接口的请求和响应拦截封装

  axiosaxios.interceptors.request.use()axios.interceptors.response.use()分别对应接口请求前的拦截处理和数据响应后的拦截处理;根据这个原理我们对微信小程序的响应也做拦截封装,对接口请求返回错误进行统一管理输出:

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

requestFilter.js中可以做很多对报错的处理,这里用一个简单的toast处理示范下:

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

对报错进行统一处理需要明确数据规:

  • 制定统一的报错码管理规范;
  • 制定前后端统一的接口请求数据返回格式;

五、全局数据管理

  对于数据的管理在小项目的开发中显得不那么重要,但是随着项目越来越大,数据越来越多,一个很好的数据管理方案能够有效地避免很多bug,这也是vuex能够在vue生态中占有一席之地的原因。秉承着合理管理数据的原则,对于该封装的数据坚决封装,对于该分模块管理的配置坚决分块管理:

globalData.js

微信小程序中全局的数据管理放在app.jsglobalData属性中,当数据太多或者app.js逻辑太复杂时,将全局数据提取出来单独管理的确是个好方案:

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

keys.js

keys.js属于个人开发中的习惯操作,将项目中可能用到的一些常量名称在此集中管理起来,十分方便调用和修改维护:

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

全局引用和注册

引入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.jsApp({
  //监听小程序初始化
  onLaunch(options) {
    //获取小程序初始进入的页面信息
    let launchInfos = wx.getLaunchOptionsSync()
    //将当前页面路由存入全局的数据管理中
    this.globalData.currentPage = launchInfos.path  },
  ···  //全局数据存储
  globalData: globalData})

使用

在页面代码逻辑中可以通过app.globalData.hostwx.$KEYS.TOKEN方式进行调用;

六、总结

  上述关于微信小程序开发的几个方面都是在实践中学习和总结的,技术层面的实现其实很容易,但是个人觉得开发规范项目工程构建才是一个项目的重要基础;完善的规范能够有效的提高开发效率和开发者之间非必要的扯皮!合理的项目工程构建能够优化开发逻辑,提高代码逻辑易读性,减少后期项目的管理时间,同时给予项目更大的扩展性。

  有需要源码的可以关注微信公众号 哇喔WEB 回复 "wxmp"获取;

  欢迎大家讨论留言、进行补充!

相关学习推荐:小程序开发教程

The above is the detailed content of How to develop WeChat mini programs like a duck in water. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:csdn.net. If there is any infringement, please contact admin@php.cn delete