ez-wxlite
ez-wxlite是一套小程序開(kāi)發(fā)模板,旨在設(shè)計(jì)一套簡(jiǎn)潔、高效、可維護(hù)的開(kāi)發(fā)框架。
本套模板總體上分為兩部分:
- client:小程序源碼部分;
- server:為本地服務(wù),不是后端服務(wù),主要作用是mock接口以及靜態(tài)文件服務(wù)。
點(diǎn)擊這里下載模板:https://github.com/wxlite-plus/ez-wxlite/releases
client
client部分是框架的核心,設(shè)計(jì)上分為:
- req:網(wǎng)絡(luò)請(qǐng)求;
- router:路由;
- config:配置信息;
- utils:工具集,用于存放一些通用的公共方法。
- wxs:工具集,wxml相關(guān)的一些公共變量及方法。
使用
框架核心代碼都包含在client/framework文件夾內(nèi),在app.js中一次性引入:
// app.jsrequire('./framework/index.js').patch();App({});
調(diào)用patch方法會(huì)直接完成App、Page、Component這三個(gè)全局方法的代理,并完成相應(yīng)的注入,所以上面的App({})其實(shí)已經(jīng)是被代理之后的App,在這一實(shí)例中我們可以獲取到注入的options數(shù)據(jù),通過(guò)this.$opts獲取到:
App({ onLaunch() { console.log(this.$opts); }, onShow() { console.log(this.$opts); },});
原小程序的App方法只能在onLaunch中獲取到options,代理過(guò)后的App,通過(guò)將options掛載在實(shí)例上,我們可以在所有生命周期里訪(fǎng)問(wèn)到,方便使用,Page同理。
req
req是wx.request的高級(jí)封裝,用于發(fā)起ajax請(qǐng)求以及文件上傳。
wx.request是一個(gè)底層api,使用的不便之處在于:
- 返回結(jié)果比較底層,需要處理statusCode,而開(kāi)發(fā)者往往更關(guān)注業(yè)務(wù)相關(guān)的data部分;
- 登錄機(jī)制繁瑣,設(shè)計(jì)上甚至有些反人類(lèi);
- 不具備良好的接口管理功能,可維護(hù)性差;
……
綜上所述,wx.request需要一層高級(jí)的封裝來(lái)簡(jiǎn)化操作,因此有了req,req代理了wx.request,并在這基礎(chǔ)上做了一些設(shè)計(jì)工作,以提供良好的維護(hù)性:
- promisify:支持promise,替代callback的方式;
- 簡(jiǎn)化respone:簡(jiǎn)化返回的數(shù)據(jù)信息,只保留業(yè)務(wù)數(shù)據(jù);
- method替代url:使用js api的書(shū)寫(xiě)方式來(lái)替代直接書(shū)寫(xiě)url的方式;
- 接口緩存:支持便捷的接口前端緩存;
- 自動(dòng)登錄:登錄態(tài)過(guò)期自動(dòng)重新登錄,過(guò)程對(duì)開(kāi)發(fā)者透明。
詳細(xì)內(nèi)容請(qǐng)瀏覽:https://github.com/wxlite-plus/mp-req
router
頁(yè)面的跳轉(zhuǎn)存在哪些問(wèn)題呢?
- 與接口的調(diào)用一樣面臨url的管理問(wèn)題;
- 參數(shù)類(lèi)型單一,只支持string。
當(dāng)我們傳遞的參數(shù)argument不是string,而是number或者boolean時(shí),也只能在下個(gè)頁(yè)面得到一個(gè)argument.toString()值:
// pages/index/index.jswx.navigateTo({ url: '/pages/a/index?a=true',});// pages/a/index.jsPage({ onLoad(options) { console.log(options.a); // => "true" console.log(typeof options.a); // => "string" console.log(options.a === true); // => false },});
上面這種情況想必很多人都遇到過(guò),而且感到很抓狂,本來(lái)就想傳遞一個(gè)boolean,結(jié)果不管傳什么都會(huì)變成string。
我們的解決方案是:利用json.stringify encodeURIComponent和decodeURIComponent JSON.parse的方式讓參數(shù)保真。
順手也替換掉那不好記的navigate api,于是就出現(xiàn)了如下方式:
// pages/pageA/index.jsconst { router } = require('../../framework/index.js');Page({ onReady() { router.push({ name: 'home', }); },});// pages/index/index.jsPage({ onLoad() { console.log(this.$opts); // { id: '123', type: 1 } },});
詳細(xì)內(nèi)容請(qǐng)瀏覽:https://github.com/wxlite-plus/mp-router
server
server為本地服務(wù),不是后端服務(wù),主要作用是:
- mock服務(wù):當(dāng)后端接口未就緒時(shí),使用自定義的數(shù)據(jù)模擬接口調(diào)用;
- 靜態(tài)文件服務(wù):開(kāi)發(fā)階段使用本地靜態(tài)資源替代線(xiàn)上的cdn資源;
運(yùn)行
- 命令行進(jìn)入server目錄,執(zhí)行npm包安裝:npm install(或者使用yarn);
- 執(zhí)行npm run dev。
done!
mock服務(wù)
mock的配置文件為server/mock/init.js,假設(shè)我需要一個(gè)獲取我的用戶(hù)信息的接口:
function init(server) { server.get('/user/myInfo', (req, res) => { res.json({ code: 0, data: { id: '123456', name: 'Jack' }, msg: 'succ', }); });}
接著我就可以通過(guò)訪(fǎng)問(wèn)http://localhost:8080/user/myInfo得到我預(yù)設(shè)的json。
靜態(tài)文件服務(wù)
如果我們想要隨意地切換靜態(tài)資源服務(wù)環(huán)境,那么我們?cè)谑褂渺o態(tài)資源的時(shí)候就不能hard code,那我們?cè)趺醋瞿??我們使用wxs來(lái)配置靜態(tài)資源的前綴。
client/wxs這一目錄存放的是wxs文件,其中我們預(yù)定義了cdnPathTable.wxs,它的含義類(lèi)似于client/config.apiUrlTable.js,我們定義了local、dev、release三個(gè)環(huán)境,然后在wxml文件中使用:
<!-- pages/index/index.wxml --><wxs src="../../wxs/index.wxs" modal="utils"></wxs><image src="{{utils.cdnPath}}/img/avt.jpg" />
這里的wxs和config其實(shí)沒(méi)有什么區(qū)別,選擇定義在wxs中是因?yàn)閣xs在wxml中使用十分方便。
其他
為了使開(kāi)發(fā)工作更簡(jiǎn)單高效,我們沒(méi)有采用在小程序開(kāi)發(fā)工具以外再搭建一層腳手架的做法,而是盡可能使用現(xiàn)有的工具和環(huán)境,借助于強(qiáng)大的vscode,我們還提供了:
- eslint支持;
- 借助typescript進(jìn)行語(yǔ)法提示;
…
啟用eslint功能只需要在根目錄下運(yùn)行npm install即可,typescript主要是實(shí)現(xiàn)小程序api的語(yǔ)法提示功能,當(dāng)然這功能直接使用現(xiàn)有的vscode插件就可以實(shí)現(xiàn),不過(guò)我目前沒(méi)有找到比較好用的~考慮到微信的api文檔更新比較頻繁,插件的維護(hù)速度可能跟不上,所以簡(jiǎn)單地實(shí)現(xiàn)了一個(gè)本地化,在開(kāi)發(fā)過(guò)程中可以手動(dòng)補(bǔ)充,將自己常用的api定義好就足以提高效率了。
版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶(hù)自發(fā)貢獻(xiàn),該文觀點(diǎn)僅代表作者本人。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請(qǐng)發(fā)送郵件至 舉報(bào),一經(jīng)查實(shí),本站將立刻刪除。