知識
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價值,我們在追求其視覺表現(xiàn)的同時,更側(cè)重于功能的便捷,營銷的便利,運營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序為后期升級提供便捷的支持!
您當前位置>首頁 » 新聞資訊 » 小程序相關(guān) >
強烈推介的幾個微信小程序開發(fā)小技巧,簡單又實用
發(fā)表時間:2021-1-6
發(fā)布人:葵宇科技
瀏覽次數(shù):56
前段時間在下開發(fā)了個微信小程序,開發(fā)過程中總結(jié)了一些我覺得對我有用的小技巧,提煉出來,相當于一個總結(jié)復(fù)盤,也希望可以幫助到大家。如果對大家確實有幫助,別忘了點贊哦 :star2: ~
1.03.2006090
v2.12.1
1. 開發(fā)中可能遇到的坑以及 Tips
本來想寫個小技巧的,結(jié)果我總結(jié)了一堆坑,沒上手之前完全想象不到微信小程序的開發(fā)體驗是如此之差、如此之爛,從微信開發(fā)者工具到所謂的「全新語言」,都有一種濃濃的半成品的 five 即視感,實在讓我 emmm.... 另外我發(fā)現(xiàn)網(wǎng)上的小程序文章大部分都是如何使用和如何避坑的實用文,而不是技巧文,這也從側(cè)面反映了小程序的坑多。
在微信小程序原生開發(fā)過程中,我不斷發(fā)出這樣的疑問「為什么堂堂技術(shù)人才多如牛毛的騰訊,會推出如此 laji」,很多弱智反人類的地方,在兩三年前社區(qū)就已經(jīng)提出來,官方回復(fù)已經(jīng)反饋正在修復(fù)中,但幾年過去了,還是沒有音信,官方回復(fù)仍然是一句冷冰冰的「已反饋」 :triumph:
- 微信開發(fā)者工具經(jīng)常熱更新不起作用甚至白屏,重新編譯也不行,只能強行退出后再次打開;
- 跟上一條類似,有時候一點樣式出錯,預(yù)覽整個都白屏,調(diào)試器里也不說哪里的問題,直接就給你棄療不顯示,重新編譯也無法解決問題,只能強行退出后再次打開;
- 跟上一條類似,調(diào)試器里報的錯經(jīng)常沒什么用,驢頭不對馬嘴,讓人很難定位問題;
- Android 端自定義 Tabbar 在下拉刷新的時候,也會跟著屏幕一起往下移,而且是無法繞過的 Bug,自定義 Tabbar 樣式都寫好了的我又改成自帶的 Tabbar 了!
-
import
的路徑不支持絕對路徑,比如你希望引用utils/fetch.js
,在不管多深的組件里面你都要慢慢../
點到根目錄,同樣.wxss
文件@import
導(dǎo)入文件時也只能使用相對路徑,所以就會出現(xiàn)../../../../../../utils/fetch.js
這種東西; - 靜態(tài)資源路徑不能有漢字,有漢字就無法加載;
-
.wxs
文件不支持 ES6,只能使用蹩腳的 ES5 寫法; -
.wxml
中只能引入.wxs
文件不能引入.js
文件??? - 模板
{{}}
中連方法都不能執(zhí)行,只能處理簡單的運算如+ - * /
,如果遇到數(shù)據(jù)需要filter
的場景,需要在.js
文件中預(yù)先格式化好再一個個setData
,比如經(jīng)常寫的[2,3,4].includes(type)
,居然都跑不起來! -
.wxs
文件中無法使用Date
對象,所以不能new Date()
,只能使用蹩腳的getDate
方法,正則也是一樣,生成正則對象需要使用getRegExp
函數(shù)getRegExp(pattern[, flags])
; -
.wxs
中可以調(diào)用其它.wxs
文件,并且只能 require 調(diào)用.wxs
文件,引入的文件必須使用相對路徑; -
setData
連一個對象合并都懶得做,如果data: {a: {b: 1, c: 1}}
,那么setData({a: {b: 2}})
就會丟失a.c
的值,真是讓人火冒三丈啊,還要setData({['a.b': 2]})
這樣才行; - IOS 上
Date
對象獲取任意時間參數(shù)比如getDay
、getTime
都為 NaN,是因為 IOS 的 Date 構(gòu)造函數(shù)不支持2018-04-26
這種格式的日期,必須轉(zhuǎn)換為2018/04/26
這種格式才會顯示正常; - 開發(fā)版小程序有時候請求莫名其妙發(fā)不出去,右上角三個點 enable debug 打開「開發(fā)調(diào)試」之后就莫名其妙能發(fā)出去請求了,在多部手機上都是這樣,不明真相。
2. 微信請求 Promise 化
2.1 使用現(xiàn)成的庫
安裝 Promise 庫 wx-promise-pro ,記得一定要帶 -s
或 --production
,要不然無法構(gòu)建成功。
npm i -S wx-promise-pro
然后在 app.js
中:
import { promisifyAll } from 'wx-promise-pro'
promisifyAll() // promisify all wx api
App({ ... })
之后就可以正常使用了:
wx.pro.showLoading({
title: '加載中',
mask: true
})
.then(() => console.log('in promise ~'))
2.2 自己實現(xiàn)
其實我們可以自己來實現(xiàn)一個這樣的庫,原理很簡單,以原生 API 的 wx.request 為例:
// 原生 API 使用方式
wx.request({
url: '', // 請求的 url
data: {}, // 參數(shù)
method: '', // post、get
success: res => {
// 請求成功回調(diào)函數(shù),res為回調(diào)參數(shù)
},
fail: res => {
// 請求失敗回調(diào)函數(shù),res為回調(diào)參數(shù)
}
})
如果我們將其 Promise 化,應(yīng)該的調(diào)用方式希望是:
// Promise 化后的期望使用方式
wx.pro.request({
url: '', // 請求的 url
data: {}, // 參數(shù)
method: '' // post、get
})
.then(res => {
// 請求成功回調(diào)函數(shù),res為回調(diào)參數(shù)
})
.catch(res => {
// 請求失敗回調(diào)函數(shù),res為回調(diào)參數(shù)
})
并且 then
函數(shù)返回的是一個 Promise 對象,讓這個函數(shù)可以不斷鏈式調(diào)用下去,所以首先需要 new
出來一個 Promise 對象:
function request(opt) {
return new Promise((resolve, reject) => {
wx.request({
...opt,
success: res => { resolve(res)},
fail: res => {reject(res)}
})
})
}
這里代碼我們可以進一步改進,由于 success
、 fail
這里傳入的參數(shù)只是由 resolve
、 reject
方法執(zhí)行了下,所以可以直接傳入 resolve
、 reject
方法即可。
另外,由于其他小程序原生 API 格式一致,所以我們可以使用柯里化方法,來將其他需要進行 Promise 化的 API 進行處理:
function promisify(api) {
return (opt = {}) => {
return new Promise((resolve, reject) => {
api({
...opt,
fail: reject,
success: resolve
})
})
}
}
然后,將柯里化方法執(zhí)行的結(jié)果作為新的 Promise 化的 API 掛載到 wx.pro
對象上:
// 將指定 API 進行 Promise 化
wx.pro.request = promisify(wx.request)
// 使用
wx.pro.request({...})
.then(...)
然后為了方便我們使用其他方法,可以循環(huán)將 wx
對象上可以被 Promise 化的方法比如 request
、 scanCode
、 showToast
、 getUserInfo
等一一掛載到 wx.pro
對象上,使用時可以直接 wx.pro.xx
,由于這個方法執(zhí)行返回的是一個 Promise 對象,因此可以像其它 Promise 化的對象那樣使用。
事實上,不知不覺,我們就自己實現(xiàn)了 wx-promise-pro
的源碼,這個庫的核心代碼也就是上面那這幾行
2.3 在項目中使用
有了上面的工具后,我們可以將其使用在項目中,為了不在項目中遍布 wx.request
或 wx.pro.request
這里可以簡單進行封裝,新建兩個文件如下:
// utils/api/fetch.js 封裝請求方法、請求攔截器
const app = getApp()
const BaseUrl = 'http://172.0.0.1:7300/mock'
const TokenWhiteList = [
'/app/user/get-by-code' // 不需要鑒權(quán)的api手動添加到這里
]
/**
* 設(shè)置請求攔截器
* @param params 請求參數(shù)
*/
const fetch = (params = {}) => {
// 攔截器邏輯
if (!TokenWhiteList.includes(params.url)) {
params.header = {
'content-type': 'application/json', // 默認值
'token': app.globalData.token || ''
}
}
if (params.url.startsWith('/')) { // 拼接完整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 封裝所有請求 API
import { fetch } from './fetch'
/* 根據(jù)微信code獲取用戶信息 */
const appUserGetByCode = ({ code } = {}) => fetch({
url: '/app/user/get-by-code',
data: { code }
})
/* 掃碼登錄 */
const appUserQrLogin = ({ qrCode } = {}) => fetch({
method: 'POST',
url: '/app/user/qr-login',
data: { qrCode }
})
/* 個人信息 */
const appUserInfo = () => fetch({
url: '/app/user/info'
})
/* 系統(tǒng)參數(shù)獲取,數(shù)據(jù)字典 */
const appSysParamListByParam = () => fetch({
url: '/app/sys-param/list-by-param'
})
/* 數(shù)據(jù)字典所有 */
const appSysParamListAll = () => fetch({
url: '/app/sys-param/list-all'
})
export {
appSysParamListAll, // 數(shù)據(jù)字典所有
appSysParamListByParam, // 系統(tǒng)參數(shù)獲取,數(shù)據(jù)字典
appUserGetByCode, // 根據(jù)微信code獲取用戶信息
appUserQrLogin, // 掃碼登錄
appUserInfo // 個人信息
}
在要使用 API 的地方就可以這樣引入:
import * as Api from '../../utils/api/apis.js' // 相對路徑
// 使用方式
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,就是下面我要介紹的內(nèi)容,是在下非常推介的小程序工具~
3. setState 修改 data 中想修改對象的屬性
在小程序中, data
是不能直接操作的,需要使用 setData
函數(shù)。鑒于微信小程序開發(fā)時 setData
的使用體驗十分蹩腳,我使用了個庫函數(shù) wx-updata
,這個庫函數(shù)在開發(fā)的時候?qū)ξ液苡袔椭?,這里特意推介給大家。
3.1 為什么要使用 wx-updata
你在使用 setData
的時候,是不是有時候覺得很難受,舉個簡單的例子:
// 你的 data
data: {
name: '蠟筆小新',
info: { height: 140, color: '黃色' }
}
如果要修改 info.height
為 155,使用 setData
要怎么做呢:
// 這樣會把 info 里其他屬性整不見了
this.setData({ info: { height: 155 } })
// 你需要取出 info 對象,修改后整個 setData
const { info } = this.data
info.height = 155
this.setData({ info })
似乎并不太復(fù)雜,但如果 data
是個很大的對象,要把比較深且不同的對象、數(shù)組項挨個改變:
data: {
name: '蠟筆小新',
info: {
height: 140, color: '黃色',
desc: [{ age: 8 }, '最喜歡大象之歌', '靚仔', { dog: '小白', color: '白色' }]
}
}
比如某個需求,需要把 info.height
改為 155,同時改變 info.desc
數(shù)組的第 0 項的 age
為 12,第 3 項的 color
為灰色呢?
// 先取出要改變的對象,改變數(shù)字后 setData 回去
const { info } = this.data
info.height = 155
info.desc[0].age = 12
info.desc[3].color = '灰色'
this.setData({ info })
// 或者像某些文章里介紹的,這樣可讀性差,也不太實用
this.setData({
'info.height': 155,
'info.desc[0].age': 12,
'info.desc[3].color': '灰色'
})
上面這兩種方法,是我們平常小程序里經(jīng)常用的,和其他 Web 端的框架相比,就很蹩腳,一種濃濃的半成品感撲面而來,有沒有這樣一個方法:
this.upData({
info: {
height: 155,
desc: [{ age: 12 }, , , { color: '灰色' }]
}
})
這個方法會幫我們深度改變嵌套對象里對應(yīng)的屬性值,跳過數(shù)組項里不想改變的,只設(shè)置我們提供了的屬性值、數(shù)組項,豈不是省略了一大堆蹩腳的代碼,而且可讀性也極佳呢。
這就是為什么我在上線的項目中使用 wx-updata ,而不是 setData
wx-updata 的原理其實很簡單,舉個例子:
this.upData({
info: {
height: 155,
desc: [{ age: 12 }]
}
})
// 會被自動轉(zhuǎn)化為下面這種格式,
// this.setData({
// 'info.height': 155,
// 'info.desc[0].age': 12,
// })
原來這個轉(zhuǎn)化工作是要我們自己手動來做,現(xiàn)在 wx-updata 幫我們做了,豈不美哉!
3.2 wx-updata 使用方式
在一般情況下,我們可以將方法直接掛載到 Page
構(gòu)造函數(shù)上,這樣就可以在 Page
實例中像使用 setData
一樣使用 upData
了:
// app.js 中掛載
import { updataInit } from './miniprogram_npm/wx-updata/index' // 你的庫文件路徑
App({
onLaunch() {
Page = updataInit(Page, { debug: true })
}
})
// 頁面代碼中使用方式
this.upData({
info: { height: 155 },
desc: [{ age: 13 }, '帥哥'],
family: [, , [, , , { color: '灰色' }]]
})
有的框架可能在 Page
對象上進行了進一步修改,直接替換 Page
的方式可能就不太好了, wx-updata
同樣暴露了工具方法,用戶可以在頁面代碼中直接使用工具方法進行處理:
// 頁面代碼中
import { objToPath } from './miniprogram_npm/wx-updata/index' // 你的庫文件路徑
Page({
data: { a: { b: 2}, c: [3,4,5]},
// 自己封裝一下
upData(data) {
return this.setData(objToPath(data))
},
// 你的方法中或生命周期函數(shù)
yourMethod() {
this.upData({ a: { b: 7}, c: [8,,9]})
}
})
針對修改數(shù)組指定項的時候,可能存在的跳過數(shù)組空位的情況,wx-updata 提供了 Empty 的 Symbol 類型替位符,還有數(shù)組的對象路徑方式,感興趣可以看看 wx-updata 的 文檔 。
另外,使用了 wx-updata 也還可以使用原來的 setData,特別是有時候要清空數(shù)組時,靈活使用,可以獲得更好的小程序開發(fā)體驗,祝大家小程序開發(fā)愉快
4. 使用 scss 寫樣式
4.1 Webstorm 配置方法
關(guān)于蹩腳的 .wxss
樣式,我使用 webstorm 的 file watcher 工具把 scss 文件監(jiān)聽改動并實時編譯成 .wxss
文件,感覺比較好用,這里給大家分享一下我的配置:
然后記得在 .gitignore
文件中加入要忽略的樣式:
*.scss
*.wxss.map
這樣在上傳到 git 的時候,就不會上傳 scss 文件了~ 當然如果你的團隊成員需要 scss 的話,還是建議 git 上傳的時候也加上 scss 文件。
這樣設(shè)置之后,一個組件在本地的會是下面這樣
其中我們需要關(guān)注的就是 .js
、 .json
、 .scss
、 .wxml
文件,另外的文件 .wxss
會在你改動 .scss
文件之后自動生成并更新,而 .wxss.map
是插件自動生成的映射關(guān)系,不用管。
如果不是使用 webstorm,可以直接執(zhí)行命令 sass --watch index.scss:index.wxss -s expanded
,命令行如果關(guān)閉,sass 命令就不會監(jiān)聽文件的變動然后編譯,所以最好用編輯器的插件。
同理,也可以使用 less、stylus 等預(yù)編譯語言。
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 來開發(fā)小程序的話,其他跟上面一樣,至此你就可以在小程序開發(fā)中快樂使用 scss 了~
5. 使用 iconfont 圖標字體
在 Web 開發(fā)中 iconfont 可謂是最常用的靈活圖標字體工具了,這里介紹一下如何在微信小程序中引入 iconfont 圖標。
首先找到你想使用的圖標們,點擊購物車之后下載到本地。
下載到本地是一個壓縮包,解壓縮之后將 iconfont.css
文件復(fù)制到微信小程序的 styles
文件夾中 (在下的習(xí)慣,也可以放到你想放的地方比如 fonts
),將后綴改為 .wxss
在 app.wxss
中引入樣式:
@import "styles/iconfont.wxss";
然后在 .wxml
中就可以使用剛剛你添加的圖標了,Web 使用 i
標簽,小程序中使用 text
標簽:
<text class="iconfont icon-my-edit" style="color: blue"></text>
如果后面要加新的圖標,要下載新的 iconfont.css
的文件到本地重命名并覆蓋,重新走一遍這個流程。
當然,如果你使用的樣式庫提供的一些 icon 能滿足你的要求,那更好,就不用引入外部圖標字體文件了,不過大部分情況下是不滿足的
相關(guān)案例查看更多
相關(guān)閱讀
- 搜索引擎排名
- 云南網(wǎng)站建設(shè)公司排名
- 汽車報廢軟件
- 云南小程序開發(fā)首選品牌
- 網(wǎng)站建設(shè)首選
- python開發(fā)小程序
- 汽車報廢拆解管理系統(tǒng)
- 網(wǎng)站建設(shè)公司地址
- 云南網(wǎng)站建設(shè)公司地址
- 小程序開發(fā)課程
- 迪慶小程序開發(fā)
- 云南網(wǎng)站設(shè)計
- 網(wǎng)站建設(shè)哪家強
- 模版信息
- 開發(fā)框架
- 云南花農(nóng)小程序
- 怎么做網(wǎng)站
- 保險網(wǎng)站建設(shè)公司
- 汽車報廢回收管理軟件
- 網(wǎng)站沒排名
- 微分銷
- 網(wǎng)站收錄
- 百度小程序開發(fā)
- 云南網(wǎng)站建設(shè)報價
- 網(wǎng)站上首頁
- 百度快速排名
- 網(wǎng)站建設(shè)首頁
- 網(wǎng)站建設(shè)招商
- 支付寶小程序被騙
- 報廢車回收