關於微信小程序開發一直想寫一篇相關的文章總結和記錄下,結果拖延症犯了遲遲沒有下筆;這不最近天氣不錯,因而找一個空閒的下午將這篇文章輸出下(好像跟天氣沒啥關係)!javascript
注意:本文默認開發者對微信小程序開發有必定語法基礎。vue
在接觸的微信小程序開發過程當中,不難發現微信小程序爲了方便開發人員入手對不少底層api進行了很好的封裝,好比針對接口請求的wx.request()
,針對路由跳轉和頁面導航的wx.switchTab、wx.navigateTo···
等。雖然在必定程度上簡化了開發,可是對於項目工程的系統化構建仍是不夠的,所以本人在對比之前基於Vue開發項目的經驗和自身的開發習慣,總結出以下3點可供參考:java
一、全局變量和配置信息統一管理;ios
vue-router
的router.beforeEach()
和router.afterEach()
真的香;axios
的axios.interceptors.request.use()
和axios.interceptors.response.use()
用過的都說好;從上述四點出發,對微信小程序初始化工程進行規範優化,可以很大程度提升開發效率和進行項目維護管理。封裝的好處不僅體如今調用的方便上,也體如今管理的方便上,同時,公共操做集中處理,很大程度減小繁雜重複代碼。vue-router
新建微信小程序項目,在項目下新建以下目錄和文件:vuex
錯誤碼
匹配列表文件;全局變量
統一管理文件(至關於vuex);5種路由導航
api的封裝;攔截
封裝;wx.request
的Promise
封裝;請求和響應攔截
封裝文件;微信小程序官方文檔爲開發者提供了5種路由跳轉的api,每一種都有其特殊的用法:axios
根據其用法,咱們對路由api進行以下封裝:微信小程序路由跳轉最後對應push、replace、pop、relaunch、switchTab
;routes
對應routeConfig.js中路由路徑的配置;routerFilter
對應routerFilter.js文件,對路由跳轉以前的邏輯進行處理;小程序
export const routes = { INDEX: "/pages/index/index", TEST: "/pages/test/test", } export default {...routes};
export default () => { ··· //路由跳轉前邏輯處理 }
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 }
在app.js
中對封裝的路由api進行全局註冊:後端
import router from "./router/router.js" //全局註冊 wx.router = router
在頁面邏輯中使用:微信小程序
//index頁面跳轉test頁面 gotoTest(){ wx.router.push("TEST") }
對於同一個項目而言,微信小程序apiwx.request()
中不少參數都是相同的,若是直接使用,須要將這些重複參數一遍又一遍的copy,雖然copy很簡單,可是當有一個參數改變了須要找到全部接口一個一個修改,維護起來費勁,再者看着也難受呀;
借鑑axios
對請求的封裝,將wx.request()
封裝爲Promise
形式豈不美哉:
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({ onLoad: function () { //獲取用戶信息 usrInfos({ uid: "xxxx" }) .then(res => { console.log(res) }) .catch(err => { console.log(err) }) } })
axios
的axios.interceptors.request.use()
和axios.interceptors.response.use()
分別對應接口請求前的攔截處理和數據響應後的攔截處理;根據這個原理咱們對微信小程序的響應也作攔截封裝,對接口請求返回錯誤進行統一管理輸出:
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中能夠作不少對報錯的處理,這裏用一個簡單的toast處理示範下:
/** * 對接口返回的後端錯誤進行格式轉化 * @param {接口成功返回的數據} res */ const formatError = (err =>{ wx.showToast({ title: err.message, mask: false, icon: 'none', duration: 3000 }) } export default formatError;
對報錯進行統一處理須要明確數據規:
對於數據的管理在小項目的開發中顯得不那麼重要,可是隨着項目愈來愈大,數據愈來愈多,一個很好的數據管理方案可以有效地避免不少bug,這也是vuex可以在vue生態中佔有一席之地的緣由。秉承着合理管理數據的原則,對於該封裝的數據堅定封裝,對於該分模塊管理的配置堅定分塊管理:
微信小程序中全局的數據管理放在app.js
的globalData
屬性中,當數據太多或者app.js邏輯太複雜時,將全局數據提取出來單獨管理的確是個好方案:
export default { ··· host: "http://www.wawow.xyz/api/test", //接口請求的域名和接口前綴 hasConfirm: "" //是否已經有了confirm實例 currentPage: "" ··· }
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
方式進行調用;
上述關於微信小程序開發的幾個方面都是在實踐中學習和總結的,技術層面的實現其實很容易,可是我的以爲開發規範項目工程構建纔是一個項目的重要基礎;完善的規範可以有效的提升開發效率和開發者之間非必要的扯皮
!合理的項目工程構建可以優化開發邏輯,提升代碼邏輯易讀性,減小後期項目的管理時間,同時給予項目更大的擴展性。
歡迎你們討論留言、進行補充!