>  기사  >  위챗 애플릿  >  적극 권장되는 몇 가지 간단하고 실용적인 WeChat 미니 프로그램 개발 팁

적극 권장되는 몇 가지 간단하고 실용적인 WeChat 미니 프로그램 개발 팁

coldplay.xixi
coldplay.xixi앞으로
2020-10-10 17:34:413193검색

WeChat Mini 프로그램 개발오늘 이 칼럼에서는 간단하고 실용적인 WeChat Mini 프로그램 개발 팁 몇 가지를 강력히 추천합니다.

적극 권장되는 몇 가지 간단하고 실용적인 WeChat 미니 프로그램 개발 팁

저는 얼마 전에 WeChat 애플릿을 개발했습니다. 개발 과정에서 제가 생각하기에 유용하다고 생각되는 몇 가지 팁을 요약해두었는데, 모두에게 도움이 되기를 바랍니다. 모두에게 정말 도움이 된다면 좋아요도 잊지 마세요

  1. WeChat 개발자 도구 버전: 1.03.2006090 (2020-06-19)
  2. 1.03.2006090(2020-06-19)
  3. 基础库版本: v2.12.1 (2020-08-04)

1. 开发中可能遇到的坑以及 Tips

本来想写个小技巧的,结果我总结了一堆坑,没上手之前完全想象不到微信小程序的开发体验是如此之差、如此之烂,从微信开发者工具到所谓的「全新语言」,都有一种浓浓的半成品的 five 即视感,实在让我 emmm.... 另外我发现网上的小程序文章大部分都是如何使用和如何避坑的实用文,而不是技巧文,这也从侧面反映了小程序的坑多。

在微信小程序原生开发过程中,我不断发出这样的疑问「为什么堂堂技术人才多如牛毛的腾讯,会推出如此 laji」,很多弱智反人类的地方,在两三年前社区就已经提出来,官方回复已经反馈正在修复中,但几年过去了,还是没有音信,官方回复仍然是一句冷冰冰的「已反馈」

  1. 微信开发者工具经常热更新不起作用甚至白屏,重新编译也不行,只能强行退出后再次打开;
  2. 跟上一条类似,有时候一点样式出错,预览整个都白屏,调试器里也不说哪里的问题,直接就给你弃疗不显示,重新编译也无法解决问题,只能强行退出后再次打开;
  3. 跟上一条类似,调试器里报的错经常没什么用,驴头不对马嘴,让人很难定位问题;
  4. Android 端自定义 Tabbar 在下拉刷新的时候,也会跟着屏幕一起往下移,而且是无法绕过的 Bug,自定义 Tabbar 样式都写好了的我又改成自带的 Tabbar 了!
  5. import 的路径不支持绝对路径,比如你希望引用 utils/fetch.js,在不管多深的组件里面你都要慢慢 ../ 点到根目录,同样 .wxss 文件 @import 导入文件时也只能使用相对路径,所以就会出现 ../../../../../../utils/fetch.js 这种东西;
  6. 静态资源路径不能有汉字,有汉字就无法加载;
  7. .wxs 文件不支持 ES6,只能使用蹩脚的 ES5 写法;
  8. .wxml 中只能引入 .wxs 文件不能引入 .js 文件???
  9. 模板 {{}} 中连方法都不能执行,只能处理简单的运算如 + - * /,如果遇到数据需要 filter 的场景,需要在 .js 文件中预先格式化好再一个个 setData,比如经常写的 [2,3,4].includes(type),居然都跑不起来!
  10. .wxs 文件中无法使用 Date 对象,所以不能 new Date(),只能使用蹩脚的 getDate 方法,正则也是一样,生成正则对象需要使用 getRegExp 函数 getRegExp(pattern[, flags])
  11. .wxs 中可以调用其它 .wxs 文件,并且只能 require 调用 .wxs 文件,引入的文件必须使用相对路径;
  12. setData 连一个对象合并都懒得做,如果 data: {a: {b: 1, c: 1}},那么 setData({a: {b: 2}}) 就会丢失 a.c 的值,真是让人火冒三丈啊,还要 setData({['a.b': 2]}) 这样才行;
  13. IOS 上 Date 对象获取任意时间参数比如 getDaygetTime 都为 NaN,是因为 IOS 的 Date 构造函数不支持 2018-04-26 这种格式的日期,必须转换为 2018/04/26 这种格式才会显示正常;
  14. 开发版小程序有时候请求莫名其妙发不出去,右上角三个点 enable debug 打开「开发调试」之后就莫名其妙能发出去请求了,在多部手机上都是这样,不明真相。

2. 微信请求 Promise 化

2.1 使用现成的库

安装 Promise 库 wx-promise-pro,记得一定要带 -s--production,要不然无法构建成功。

npm i -S wx-promise-pro复制代码

然后在 app.js기본 라이브러리 버전: v2.12.1 (2020-08-04)

1. 개발 중 발생할 수 있는 함정과 팁

원래는 작은 팁을 쓰고 싶었지만, 결국 많은 함정을 요약하게 되었습니다. 시작하기 전에는 WeChat 개발자 도구부터 WeChat 미니 프로그램의 개발 경험이 이렇게 나쁜 것인지 전혀 몰랐습니다. 소위 "새로운 언어"”, 모두 반제품 5개라는 시각적 감각이 강해서 정말 으음... 게다가 인터넷에 있는 대부분의 소규모 프로그램 기사는 방법에 대한 실용적인 기사라는 것을 알았습니다. 기술적인 글보다는 사용법과 함정을 피하는 방법이 중요하다는 점 역시 미니 프로그램에 함정이 많다는 측면을 반영합니다.

WeChat 미니 프로그램의 기본 개발 과정에서 "기술력이 뛰어난 Tencent가 왜 이런 라지를 출시했을까요?"라는 질문을 계속해서 받았습니다. 또는 3년 전에는 공식 답변이 복구 중이라고 보도되었지만 몇 년이 지난 후에도 여전히 공식 답변은 냉담합니다. 🎜🎜🎜WeChat 개발자 도구는 종종 핫 업데이트가 작동하지 않습니다. 또는 흰색 화면이더라도 재컴파일이 작동하지 않습니다. 🎜이전과 유사하게 때로는 약간의 스타일 오류가 발생하고 전체 미리보기가 흰색으로 표시됩니다. 문제가 무엇인지 알려주지 않고 그냥 포기하고 표시하지 않을 것입니다. 다시 컴파일해도 문제가 해결되지 않으며 강제로 종료하고 다시 열 수만 있습니다.🎜이전과 유사합니다. 디버거에서 보고된 오류는 쓸모가 없는 경우가 많아 문제를 찾기가 어렵습니다. li>🎜Android의 맞춤 탭바도 새로고침을 위해 아래로 당길 때 화면과 함께 아래로 이동하는데, 이는 불가능한 버그입니다. 사용자 정의 Tabbar 스타일을 작성한 후 내장 Tabbar로 변경했습니다! 🎜 import 경로는 절대 경로를 지원하지 않습니다. 예를 들어, 구성 요소의 깊이에 관계없이 utils/fetch.js를 참조하려는 경우. , 천천히 ../ 루트 디렉터리를 클릭해야 하며 마찬가지로 .wxss 파일 @import는 파일을 가져올 때 상대 경로만 사용할 수 있습니다. , 그래서 ../../../utils/fetch.js 이런 종류의 것입니다. 🎜정적 리소스 경로는 가질 수 없습니다. 한자, 한자가 있으면 로드할 수 없습니다. 🎜.wxs 파일은 ES6을 지원하지 않으며 형편없는 ES5 작성 방법만 사용할 수 있습니다. code>.wxml은 .wxs 파일을 가져올 수만 있습니다. .js 파일은 가져올 수 없습니다. ? ? 🎜{{}} 템플릿의 메서드도 실행할 수 없습니다. 데이터가 발견되면 + - * /와 같은 간단한 작업만 처리할 수 있습니다. , filter 시나리오는 .js 파일에서 미리 형식화된 다음 자주 작성되는 와 같이 <code>setData를 하나씩 지정해야 합니다. [2,3, 4].includes(type), 실행할 수도 없습니다! 🎜Date 개체는 .wxs 파일에서 사용할 수 없으므로 new Date()를 사용할 수 없으며 단지 crappy만 사용할 수 있습니다. getDate 메서드, 정규식 개체를 생성하려면 getRegExp 함수 getRegExp(pattern[, flags]);🎜<code>. 다른 <code>.wxs 파일은 wxs에서 호출할 수 있으며, .wxs 파일만 호출할 수 있습니다. 가져온 파일은 상대 경로를 사용해야 합니다. 🎜setData는 개체를 병합하기에는 너무 게으릅니다. /code>를 입력하면 setData({a: {b : 2}})a.c의 값을 잃게 됩니다. 이는 정말 짜증나는 일입니다. setData({['a.b': 2]}) code> 이 방법은 작동합니다.🎜IOS의 Date 개체는 getDay 및 <code>getTime은 모두 NaN입니다. 왜냐하면 IOS의 Date 생성자는 2018-04-26 형식의 날짜를 지원하지 않으며 로 변환해야 하기 때문입니다. >2018/04/26 올바르게 표시하려면; li>🎜애플릿의 개발 버전에서 오른쪽 상단 모서리에 있는 세 개의 점으로 "디버그 활성화"를 켜고 설명할 수 없는 이유로 요청을 보내지 못하는 경우가 있습니다. "개발 및 디버깅"을 열면 설명할 수 없는 요청이 전송될 수 있습니다. 이는 많은 휴대폰에서 발생하는 현상입니다.

2. WeChat 요청 약속

2.1 기성 라이브러리 사용

🎜Promise 라이브러리 wx-promise-pro를 설치하세요. -s 또는 --production을 가져와야 합니다. 그렇지 않으면 빌드가 성공하지 못합니다. 🎜
import { promisifyAll } from &#39;wx-promise-pro&#39;promisifyAll()  // promisify all wx apiApp({ ... })复制代码
🎜그런 다음 app.js에서: 🎜
wx.pro.showLoading({    title: &#39;加载中&#39;,    mask: true})
  .then(() => console.log(&#39;in promise ~&#39;))复制代码
🎜 그러면 정상적으로 사용할 수 있습니다: 🎜
wx.pro.showLoading({    title: &#39;加载中&#39;,    mask: true})
  .then(() => console.log(&#39;in promise ~&#39;))复制代码

2.2 自己实现

其实我们可以自己来实现一个这样的库,原理很简单,以原生 API 的 wx.request 为例:

// 原生 API 使用方式wx.request({    url: &#39;&#39;,     // 请求的 url
    data: {},    // 参数
    method: &#39;&#39;,  // post、get
    success: res => {        // 请求成功回调函数,res为回调参数
    },    fail: res => {        // 请求失败回调函数,res为回调参数
    }
})复制代码

如果我们将其 Promise 化,应该的调用方式希望是:

// Promise 化后的期望使用方式wx.pro.request({    url: &#39;&#39;,     // 请求的 url
    data: {},    // 参数
    method: &#39;&#39;   // post、get})
  .then(res => {      // 请求成功回调函数,res为回调参数
  })
  .catch(res => {      // 请求失败回调函数,res为回调参数
  })复制代码

并且 then 函数返回的是一个 Promise 对象,让这个函数可以不断链式调用下去,所以首先需要 new 出来一个 Promise 对象:

function request(opt) {    return new Promise((resolve, reject) => {
        wx.request({
            ...opt,            success: res => { resolve(res)},            fail: res => {reject(res)}
        })
    })
}复制代码

这里代码我们可以进一步改进,由于 successfail 这里传入的参数只是由 resolvereject 方法执行了下,所以可以直接传入 resolvereject 方法即可。

另外,由于其他小程序原生 API 格式一致,所以我们可以使用柯里化方法,来将其他需要进行 Promise 化的 API 进行处理:

function promisify(api) {    return (opt = {}) => {        return new Promise((resolve, reject) => {
            api({
                ...opt,                fail: reject,                success: resolve
            })
        })
    }
}复制代码

然后,将柯里化方法执行的结果作为新的 Promise 化的 API 挂载到 wx.pro 对象上:

// 将指定 API 进行 Promise 化wx.pro.request = promisify(wx.request)// 使用wx.pro.request({...})
    .then(...)复制代码

然后为了方便我们使用其他方法,可以循环将 wx 对象上可以被 Promise 化的方法比如 requestscanCodeshowToastgetUserInfo 等一一挂载到 wx.pro 对象上,使用时可以直接 wx.pro.xx,由于这个方法执行返回的是一个 Promise 对象,因此可以像其它 Promise 化的对象那样使用。

事实上,不知不觉,我们就自己实现了 wx-promise-pro 的源码,这个库的核心代码也就是上面那这几行 

2.3 在项目中使用

有了上面的工具后,我们可以将其使用在项目中,为了不在项目中遍布 wx.requestwx.pro.request 这里可以简单进行封装,新建两个文件如下:

// utils/api/fetch.js 封装请求方法、请求拦截器const app = getApp()const BaseUrl = &#39;http://172.0.0.1:7300/mock&#39;const TokenWhiteList = [    &#39;/app/user/get-by-code&#39;     // 不需要鉴权的api手动添加到这里]/**
 * 设置请求拦截器
 * @param params 请求参数
 */const fetch = (params = {}) => {    // 拦截器逻辑
    if (!TokenWhiteList.includes(params.url)) {
        params.header = {            &#39;content-type&#39;: &#39;application/json&#39;,             // 默认值
            &#39;token&#39;: app.globalData.token || &#39;&#39;
        }
    }    if (params.url.startsWith(&#39;/&#39;)) {    // 拼接完整URL
        params.url = BaseUrl + params.url
    }    // 返回promise
    return wx.pro.request({ ...params })
      .then(({ data: { code, message, data } }) => {          // ... 各种异常情况的逻辑处理
          // 与后端约定 code 20000 时正常返回
          if (code === 20000) return Promise.resolve(data)          return Promise.reject(message)
      })
}export { fetch }复制代码

然后再将所有 API 封装到单独的文件中集中管理:

// utils/api/apis.js 封装所有请求 APIimport { fetch } from &#39;./fetch&#39;/* 根据微信code获取用户信息 */const appUserGetByCode = ({ code } = {}) => fetch({    url: &#39;/app/user/get-by-code&#39;,    data: { code }
})/* 扫码登录 */const appUserQrLogin = ({ qrCode } = {}) => fetch({    method: &#39;POST&#39;,    url: &#39;/app/user/qr-login&#39;,    data: { qrCode }
})/* 个人信息 */const appUserInfo = () => fetch({    url: &#39;/app/user/info&#39;})/* 系统参数获取,数据字典 */const appSysParamListByParam = () => fetch({    url: &#39;/app/sys-param/list-by-param&#39;})/* 数据字典所有 */const appSysParamListAll = () => fetch({    url: &#39;/app/sys-param/list-all&#39;})export {
    appSysParamListAll,   // 数据字典所有
    appSysParamListByParam,   // 系统参数获取,数据字典
    appUserGetByCode,   // 根据微信code获取用户信息
    appUserQrLogin,   // 扫码登录
    appUserInfo   // 个人信息}复制代码

在要使用 API 的地方就可以这样引入:

import * as Api from &#39;../../utils/api/apis.js&#39;   // 相对路径// 使用方式Api.appSysParamListAll()
  .then(({ dataList }) => this.upData({ sysParamList: dataList }))
  .then(() => {      const keyList = this.data.sysParamList.map(T => T.key)      this.upData({
          keyList,          formData: { keys: keyList }
      })
  })复制代码

使用方式就很舒服,这里使用到了 upData,就是下面我要介绍的内容,是在下非常推介的小程序工具~ 

3. setState 修改 data 中想修改对象的属性

在小程序中,data 是不能直接操作的,需要使用 setData 函数。鉴于微信小程序开发时 setData 的使用体验十分蹩脚,我使用了个库函数 wx-updata,这个库函数在开发的时候对我很有帮助,这里特意推介给大家。

3.1 为什么要使用 wx-updata

你在使用 setData 的时候,是不是有时候觉得很难受,举个简单的例子:

// 你的 datadata: {    name: &#39;蜡笔小新&#39;,    info: { height: 140, color: &#39;黄色&#39; }
}复制代码

如果要修改 info.height 为 155,使用 setData 要怎么做呢:

// 这样会把 info 里其他属性整不见了this.setData({ info: { height: 155 } })// 你需要取出 info 对象,修改后整个 setDataconst { info } = this.data
info.height = 155this.setData({ info })复制代码

似乎并不太复杂,但如果 data 是个很大的对象,要把比较深且不同的对象、数组项挨个改变:

data: {    name: &#39;蜡笔小新&#39;,    info: {        height: 140, color: &#39;黄色&#39;,        desc: [{ age: 8 }, &#39;最喜欢大象之歌&#39;, &#39;靓仔&#39;, { dog: &#39;小白&#39;, color: &#39;白色&#39; }]
    }
}复制代码

比如某个需求,需要把 info.height 改为 155,同时改变 info.desc 数组的第 0 项的 age 为 12,第 3 项的 color 为灰色呢?

// 先取出要改变的对象,改变数字后 setData 回去const { info } = this.data
info.height = 155info.desc[0].age = 12info.desc[3].color = &#39;灰色&#39;this.setData({ info })// 或者像某些文章里介绍的,这样可读性差,也不太实用this.setData({    &#39;info.height&#39;: 155,    &#39;info.desc[0].age&#39;: 12,    &#39;info.desc[3].color&#39;: &#39;灰色&#39;})复制代码

上面这两种方法,是我们平常小程序里经常用的,和其他 Web 端的框架相比,就很蹩脚,一种浓浓的半成品感扑面而来,有没有这样一个方法:

this.upData({    info: {        height: 155,        desc: [{ age: 12 }, , , { color: &#39;灰色&#39; }]
    }
})复制代码

这个方法会帮我们深度改变嵌套对象里对应的属性值,跳过数组项里不想改变的,只设置我们提供了的属性值、数组项,岂不是省略了一大堆蹩脚的代码,而且可读性也极佳呢。

这就是为什么我在上线的项目中使用 wx-updata,而不是 setData

wx-updata 的原理其实很简单,举个例子:

this.upData({    info: {        height: 155,        desc: [{ age: 12 }]
    }
})// 会被自动转化为下面这种格式,// this.setData({//    &#39;info.height&#39;: 155,//    &#39;info.desc[0].age&#39;: 12,// })复制代码

原来这个转化工作是要我们自己手动来做,现在 wx-updata 帮我们做了,岂不美哉!

3.2 wx-updata 使用方式

在一般情况下,我们可以将方法直接挂载到 Page 构造函数上,这样就可以在 Page 实例中像使用 setData 一样使用 upData 了:

// app.js 中挂载import { updataInit } from &#39;./miniprogram_npm/wx-updata/index&#39;  // 你的库文件路径App({
    onLaunch() {
        Page = updataInit(Page, { debug: true })
    }
})// 页面代码中使用方式this.upData({    info: { height: 155 },    desc: [{ age: 13 }, &#39;帅哥&#39;],    family: [, , [, , , { color: &#39;灰色&#39; }]]
})复制代码

有的框架可能在 Page 对象上进行了进一步修改,直接替换 Page 的方式可能就不太好了,wx-updata 同样暴露了工具方法,用户可以在页面代码中直接使用工具方法进行处理:

// 页面代码中import { objToPath } from &#39;./miniprogram_npm/wx-updata/index&#39;  // 你的库文件路径Page({    data: { a: { b: 2}, c: [3,4,5]},    // 自己封装一下
    upData(data) {        return this.setData(objToPath(data))
    },    // 你的方法中或生命周期函数
    yourMethod() {        this.upData({ a: { b: 7}, c: [8,,9]})
    }
})复制代码

针对修改数组指定项的时候,可能存在的跳过数组空位的情况,wx-updata 提供了 Empty 的 Symbol 类型替位符,还有数组的对象路径方式,感兴趣可以看看 wx-updata 的文档,也可以参考 这篇介绍文章。

另外,使用了 wx-updata 也还可以使用原来的 setData,特别是有时候要清空数组时,灵活使用,可以获得更好的小程序开发体验,祝大家小程序开发愉快 

4. 使用 scss 写样式

4.1 Webstorm 配置方法

关于蹩脚的 .wxss 样式,我使用 webstorm 的 file watcher 工具把 scss 文件监听改动并实时编译成 .wxss 文件,感觉比较好用,这里给大家分享一下我的配置:

然后记得在 .gitignore 文件中加入要忽略的样式:

*.scss
*.wxss.map复制代码

这样在上传到 git 的时候,就不会上传 scss 文件了~ 当然如果你的团队成员需要 scss 的话,还是建议 git 上传的时候也加上 scss 文件。

这样设置之后,一个组件在本地的会是下面这样

적극 권장되는 몇 가지 간단하고 실용적인 WeChat 미니 프로그램 개발 팁

其中我们需要关注的就是 .js.json.scss.wxml 文件,另外的文件 .wxss 会在你改动 .scss 文件之后自动生成并更新,而 .wxss.map 是插件自动生成的映射关系,不用管。

如果不是使用 webstorm,可以直接执行命令 sass --watch index.scss:index.wxss -s expanded,命令行如果关闭,sass 命令就不会监听文件的变动然后编译,所以最好用编辑器的插件。

同理,也可以使用 less、stylus 等预编译语言。

4.2 Visual Studio Code 配置方法

万能的 VSC 当然也可以做到这个功能,搜索并下载插件 easy sass,然后在 setting.json 中修改/增加配置:

"easysass.formats": [
  {    "format": "expanded",    "extension": ".wxss"
  },
  {    "format": "compressed",    "extension": ".min.wxss"
  }
]复制代码

上面 expanded 是编译生成的 .wxss 文件,下面 compressed 是压缩之后的 .wxss 样式文件,下面这个用不到可以把下面这个配置去掉,然后在 .gitignore 文件中加入要忽略的中间样式:

*.scss复制代码

当然也可以不添加,如果你的同事也是实用 scss 来开发小程序的话,其他跟上面一样,至此你就可以在小程序开发中快乐使用 scss 了~

5. 使用 iconfont 图标字体

在 Web 开发中 iconfont 可谓是最常用的灵活图标字体工具了,这里介绍一下如何在微信小程序中引入 iconfont 图标。

首先找到你想使用的图标们,点击购物车之后下载到本地。

적극 권장되는 몇 가지 간단하고 실용적인 WeChat 미니 프로그램 개발 팁

下载到本地是一个压缩包,解压缩之后将 iconfont.css 文件复制到微信小程序的 styles 文件夹中 (在下的习惯,也可以放到你想放的地方比如 fonts),将后缀改为 .wxss

적극 권장되는 몇 가지 간단하고 실용적인 WeChat 미니 프로그램 개발 팁

app.wxss 中引入样式:

@import "styles/iconfont.wxss";复制代码

然后在 .wxml 中就可以使用刚刚你添加的图标了,Web 使用 i 标签,小程序中使用 text 标签:

<text class="iconfont icon-my-edit" style="color: blue"></text>复制代码

如果后面要加新的图标,要下载新的 iconfont.css 的文件到本地重命名并覆盖,重新走一遍这个流程。

相关免费学习推荐:微信小程序开发

위 내용은 적극 권장되는 몇 가지 간단하고 실용적인 WeChat 미니 프로그램 개발 팁의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.im에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제