> 위챗 애플릿 > 미니 프로그램 개발 > 물속의 오리처럼 WeChat 미니 프로그램을 개발하는 방법

물속의 오리처럼 WeChat 미니 프로그램을 개발하는 방법

coldplay.xixi
풀어 주다: 2021-03-30 10:51:37
앞으로
2065명이 탐색했습니다.

물속의 오리처럼 WeChat 미니 프로그램을 개발하는 방법

  예전부터 위챗 미니 프로그램의 발전 과정을 정리하고 기록하기 위해 관련 글을 쓰고 싶었는데, 요즘 날씨가 좋아서 글쓰기를 시작하지 못하고 있습니다. 이 기사를 출력할 수 있는 여유로운 오후(날씨와는 관계가 없는 것 같습니다) 그럼 시작하겠습니다!

참고: 이 문서에서는 개발자가 WeChat 애플릿 개발에 있어 특정 문법적 기초를 갖추고 있다고 가정합니다. Mini 프로그램 개발 문서

관련 무료 학습 권장 사항: WeChat Mini 프로그램 개발

WeChat Mini 프로그램 요약

WeChat Mini 프로그램 개발 과정에서 WeChat Mini를 찾는 것은 어렵지 않습니다. 프로그램은 편의를 위한 것입니다. 개발자들은 인터페이스 요청을 위한 wx.request(), 라우팅 점프 및 페이지 탐색을 위한 wx.switchTab 및 wx.navigateTo와 같은 많은 기본 API를 매우 잘 캡슐화하기 시작했습니다. ···등. 어느 정도 개발을 단순화시키기는 하지만, 프로젝트 엔지니어링을 체계적으로 구축하기에는 아직 부족합니다. 따라서 이전에 Vue를 기반으로 프로젝트를 개발한 경험과 저의 개발 습관을 비교한 후 참고할 수 있도록 다음 3가지 사항을 요약했습니다. wx.request(),针对路由跳转和页面导航的wx.switchTab、wx.navigateTo···等。虽然在一定程度上简化了开发,但是对于项目工程的系统化构建还是不够的,因此本人在对比以前基于Vue开发项目的经验和自身的开发习惯,总结出如下3点可供参考:

  • 1、全局变量和配置信息统一管理;

  • 2、封装路由守卫相关api:vue-routerrouter.beforeEach()router.afterEach()真的香;

  • 3、接口请求公共信息进一步提取封装;

  • 4、封装接口的请求和响应拦截api:axiosaxios.interceptors.request.use()axios.interceptors.response.use()用过的都说好;

从上述四点出发,对微信小程序初始化工程进行规范优化,能够很大程度提高开发效率和进行项目维护管理。封装的好处不只体现在调用的方便上,也体现在管理的方便上,同时,公共操作集中处理,很大程度减少繁杂重复代码。

一、项目初始化

   新建微信小程序项目,在项目下新建如下目录和文件:

  • config文件夹:统一管理可配置的信息和变量;
    • erroList.js:接口报错错误码匹配列表文件;
    • globalData.js:全局变量统一管理文件(相当于vuex);
    • keys.js:可配置系统信息管理文件(全局常量命名等);
  • pages文件夹:小程序页面文件管理文件夹(每个页面一个子文件夹目录);
  • router文件夹:路由管理文件件;
    • router.js:对微信小程序5种路由导航api的封装;
    • routerConfig.js:页面路由名称和路径匹配配置文件;
    • routerFilter.js:路由前置拦截封装;
  • servers文件件:接口请求服务管理文件夹;
    • apis文件夹:request请求封装管理和接口api配置管理文件夹;
      • request.js:对wx.requestPromise封装;
      • xxx.js:对应模块的接口管理文件;
    • requestFilter.js:接口请求和响应拦截封装文件;
  • 其他都是初始化默认文件;

二、路由跳转和路由守卫封装

1、路由跳转封装

  微信小程序官方文档为开发者提供了5种路由跳转的api,每一种都有其特殊的用法:

  根据其用法,我们对路由api进行如下封装:微信小程序路由跳转最后对应push、replace、pop、relaunch、switchTabroutes对应routeConfig.js中路由路径的配置;routerFilter对应routerFilter.js文件,对路由跳转之前的逻辑进行处理;

routeConfig.js(每次新增页面后需要手动添加):

export const routes = 
  {
    INDEX: "/pages/index/index",
    TEST: "/pages/test/test",
  }export default {...routes};
로그인 후 복사

routerFilter.js:

export default () => {
  ···  //路由跳转前逻辑处理}
로그인 후 복사

router.js(routerFilter负责路由跳转前公共操作处理,在success和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、全局注册和使用

app.js中对封装的路由api进行全局注册:

import router  from "./router/router.js"//全局注册wx.router = router
로그인 후 복사

在页面逻辑中使用:

//index页面跳转test页面 gotoTest(){
   wx.router.push("TEST")}
로그인 후 복사

三、接口请求Promise封装

  对于同一个项目而言,微信小程序apiwx.request()

  • 1. 전역 변수 및 구성 정보 통합 관리 🎜
  • 🎜2. 경로 가드 관련 API 캡슐화: vue-router code>router.beforeEach( ) 및 router.afterEach()는 정말 좋습니다. 🎜
  • 🎜3 인터페이스는 추가 추출 및 캡슐화를 위해 공개 정보를 요청합니다. 🎜
  • 🎜 4. 캡슐화된 인터페이스의 요청 및 응답 차단 API: axiosaxios.interceptors.request.use() 및 axios.interceptors.response.use() 사용해본 사람은 다 좋다고 합니다 🎜
🎜위의 4가지 점에서 시작하여 WeChat 애플릿 초기화 프로젝트를 표준화하고 최적화합니다. 개발 효율성과 프로젝트 유지관리 관리를 크게 향상시킬 수 있습니다. 캡슐화의 이점은 호출의 편리성뿐만 아니라 관리의 편의성에도 반영됩니다. 동시에 공용 작업이 중앙에서 처리되므로 복잡하고 반복적인 코드가 크게 줄어듭니다. 🎜🎜🎜 1. 프로젝트 초기화 🎜🎜🎜     새로운 WeChat 애플릿 프로젝트를 생성하고 프로젝트 아래에 다음 디렉터리와 파일을 생성합니다. 🎜
  • config 폴더: 구성 가능한 정보 및 변수의 통합 관리
      erroList.js: 인터페이스 오류 오류 코드가 목록 파일과 일치합니다.
  • globalData.js: 전역 변수 통합 관리 파일(vuex와 동일);
  • keys.js: 구성 가능한 시스템 정보 관리 파일(전역 상수 이름 지정 등)
  • pages 폴더: 미니 프로그램 페이지 파일 관리 폴더( 각 페이지에는 하위 폴더 디렉터리가 있습니다);
  • 라우터 폴더: 라우팅 관리 파일;
    • router.js: WeChat 미니 프로그램을 위한 5가지 유형의 경로 탐색API 캡슐화;
    • routerConfig.js: 페이지 라우팅 이름 및 경로 일치 구성 파일;
    • routerFilter.js: 가로채기 이전 캡슐화 라우팅
  • 서버 파일: 인터페이스 요청 서비스 관리 폴더;
    • apis 폴더: 요청 요청 캡슐화 관리 및 인터페이스 API 구성 관리 폴더
      • request.js: wx.requestPromise 캡슐화;
      • xxx.js: 해당 모듈의 인터페이스 관리 파일;
    • requestFilter.js: 인터페이스 요청 및 응답 차단 캡슐화 파일
  • 기타는 초기화 기본 파일입니다. 🎜🎜 🎜🎜 2. 경로 점프 및 Route Guard Encapsulation 🎜🎜🎜🎜 1. Route Jump Encapsulation 🎜🎜🎜 WeChat Mini 프로그램 공식 문서는 개발자에게 5가지 유형의 루트 점프 API를 제공하며 각 API에는 고유한 특수 기능이 있습니다. 사용법: 🎜🎜🎜🎜  사용법에 따라 API는 다음과 같이 캡슐화됩니다. WeChat 애플릿 경로 점프 마지막으로 push, replacement, pop, relaunch, switchTab에 해당합니다. routes는 RouteConfig.js의 라우팅 경로 구성에 해당합니다. 경로 점프 전에 논리를 처리하는 routerFilter.js 파일에 🎜

    routeConfig.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;
    로그인 후 복사
    로그인 후 복사

    routerFilter .js:

    import request from "./request";// 获取用户openidexport const usrInfos = data => request("POST", "/user/usrInfos", data);
    로그인 후 복사
    로그인 후 복사

    router.js(routerFilter는 경로 점프 전 공용 작업 처리를 담당하고 경로 점프 성공 및 실패 후 공용 작업 처리를 담당합니다.):

    //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)
          })
      }})
    로그인 후 복사
    로그인 후 복사
    🎜🎜2 , 글로벌 등록 및 사용 🎜🎜🎜 글로벌 등록 app.js의 캡슐화된 라우팅 API: 🎜
    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;
    로그인 후 복사
    로그인 후 복사
    🎜 페이지 로직에서 사용: 🎜
    /**
     * 对接口返回的后端错误进行格式转化
     * @param {接口成功返回的数据} res 
     */const formatError = (err =>{
      wx.showToast({
        title: err.message,
        mask: false,
        icon: 'none',
        duration: 3000
      })}export default formatError;
    로그인 후 복사
    로그인 후 복사
    🎜🎜 3. 인터페이스 요청 약속 캡슐화 🎜🎜 🎜 동일한 프로젝트의 경우 WeChat 애플릿 API의 많은 매개변수 wx.request()는 동일합니다. 직접 사용할 경우 이러한 반복되는 매개변수를 계속해서 복사해야 합니다. 복사는 매우 간단하지만 매개변수가 변경되면 모든 것을 찾아야 합니다. 인터페이스를 만들고 하나씩 수정하면 유지 관리가 힘들고 보기에도 불편합니다 🎜

      借鉴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"获取;

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

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

  • 위 내용은 물속의 오리처럼 WeChat 미니 프로그램을 개발하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    관련 라벨:
    원천:csdn.net
    본 웹사이트의 성명
    본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
    최신 이슈
    인기 튜토리얼
    더>
    최신 다운로드
    더>
    웹 효과
    웹사이트 소스 코드
    웹사이트 자료
    프론트엔드 템플릿