
??關于微信小程式開發一直想寫一篇相關的文章總結和記錄下,結果拖延癥犯了遲遲沒有下筆;這不最近天氣不錯,于是找一個空閑的下午將這篇文章輸出下(好像跟天氣沒啥關系😓),那我們就開始吧!
注意:本文默認開發者對微信小程式開發有一定語法基礎,小程式開發檔案
微信小程式小結
??在接觸的微信小程式開發程序中,不難發現微信小程式為了方便開發人員入手對很多底層api進行了很好的封裝,比如針對介面請求的wx.request(),針對路由跳轉和頁面導航的wx.switchTab、wx.navigateTo···等,雖然在一定程度上簡化了開發,但是對于專案工程的系統化構建還是不夠的,因此本人在對比以前基于Vue開發專案的經驗和自身的開發習慣,總結出如下3點可供參考:
-
1、全域變數和配置資訊統一管理;
-
2、封裝路由守衛相關api:
vue-router的router.beforeEach()和router.afterEach()真的香; -
3、介面請求公共資訊進一步提取封裝;
-
4、封裝介面的請求和回應攔截api:
axios的axios.interceptors.request.use()和axios.interceptors.response.use()用過的都說好;
從上述四點出發,對微信小程式初始化工程進行規范優化,能夠很大程度提高開發效率和進行專案維護管理,封裝的好處不只體現在呼叫的方便上,也體現在管理的方便上,同時,公共操作集中處理,很大程度減少繁雜重復代碼,
一、專案初始化
???新建微信小程式專案,在專案下新建如下目錄和檔案:
- config檔案夾:統一管理可配置的資訊和變數;
- erroList.js:介面報錯
錯誤碼匹配串列檔案; - globalData.js:
全域變數統一管理檔案(相當于vuex); - keys.js:可配置系統資訊管理檔案(全域常量命名等);
- erroList.js:介面報錯
- pages檔案夾:小程式頁面檔案管理檔案夾(每個頁面一個子檔案夾目錄);
- router檔案夾:路由管理檔案件;
- router.js:對微信小程式
5種路由導航api的封裝; - routerConfig.js:頁面路由名稱和路徑匹配組態檔;
- routerFilter.js:路由前置
攔截封裝;
- router.js:對微信小程式
- servers檔案件:介面請求服務管理檔案夾;
- apis檔案夾:request請求封裝管理和介面api配置管理檔案夾;
- request.js:對
wx.request的Promise封裝; - xxx.js:對應模塊的介面管理檔案;
- request.js:對
- requestFilter.js:介面
請求和回應攔截封裝檔案;
- apis檔案夾:request請求封裝管理和介面api配置管理檔案夾;
- 其他都是初始化默認檔案;

二、路由跳轉和路由守衛封裝
1、路由跳轉封裝
??微信小程式官方檔案為開發者提供了5種路由跳轉的api,每一種都有其特殊的用法:

??根據其用法,我們對路由api進行如下封裝:微信小程式路由跳轉最后對應push、replace、pop、relaunch、switchTab;routes對應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()中很多引數都是相同的,如果直接使用,需要將這些重復引數一遍又一遍的copy,雖然copy很簡單,但是當有一個引數改變了需要找到所有介面一個一個修改,維護起來費勁,再者看著也難受呀;

??借鑒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";
// 獲取用戶openid
export const usrInfos = data => request("POST", "/user/usrInfos", data);
index頁面呼叫:
//index.js
//獲取應用實體
const app = getApp()
import { usrInfos } from "../../servers/apis/user"
Page({
onl oad: function () {
//獲取用戶資訊
usrInfos({
uid: "xxxx"
})
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
}
})
四、介面的請求和回應攔截封裝
??axios的axios.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.js的globalData屬性中,當資料太多或者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.js
App({
//監聽小程式初始化
onLaunch(options) {
//獲取小程式初始進入的頁面資訊
let launchInfos = wx.getLaunchOptionsSync()
//將當前頁面路由存入全域的資料管理中
this.globalData.currentPage = launchInfos.path
},
···
//全域資料存盤
globalData: globalData
})
使用
在頁面代碼邏輯中可以通過app.globalData.host,wx.$KEYS.TOKEN方式進行呼叫;
六、總結
??上述關于微信小程式開發的幾個方面都是在實踐中學習和總結的,技術層面的實作其實很容易,但是個人覺得開發規范專案工程構建才是一個專案的重要基礎;完善的規范能夠有效的提高開發效率和開發者之間非必要的扯皮!合理的專案工程構建能夠優化開發邏輯,提高代碼邏輯易讀性,減少后期專案的管理時間,同時給予專案更大的擴展性,
??有需要原始碼的可以關注微信公眾號 哇喔WEB 回復 "wxmp"獲取;
??歡迎大家討論留言、進行補充!
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/247681.html
標籤:其他
