?記錄使用微信小程序的開發(fā)過程中遇到的各種難點(diǎn)及教程(不定時更新) 轉(zhuǎn)載 2018-12-06 weixin_34311757 碼齡4年 關(guān)注 本文為整理記錄本人使用微信小程序開發(fā)產(chǎn)品的過程中,針對項(xiàng)目中業(yè)務(wù)需求所遇到的各種難點(diǎn),、API問題,、BUG、及教程整理? 1,、wxml頁面的 Mustache 語法(雙大括號)數(shù)據(jù)綁定是不能使用全局js方法的,,例如utils.js里面定義的時間日期格式化,價(jià)錢格式化等等公共函數(shù)方法,。 只能用.wxs文件,,這是文檔:https://developers.weixin.qq....,并且.wxs文件只能使用es4語法,,不支持es6語法,,以及一些符號,比如我在vue項(xiàng)目里常用的這個郵箱正則 const emailReg = /[\w!#$%&'*+/=?^_{|}~-]+(?:.[w!#$%&'*+/=?^_{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/; ,,就會報(bào)錯,。 所以想要在.wxml頁面使用全局方法的話,就先定義好.wxs文件的全局方法,,然后如下引入就可以使用util.wxs里面的全局方法了,, <wxs src="../../utils/util.wxs" module="util" /> 但是用.wxs來做全局方法的話有局限性,例如moment.js和accounting.js,,這種使用率比較大的第三方插件,,.wxs文件是不能引用js文件的,,只能引用.wxs文件。 所以這點(diǎn)很操蛋,,只能繼續(xù)使用 utils.js 在里面定義好全局方法,,然后在app.js入口引入, /** * 全局公共方法 * @type {function} */ const utils = require('./utils/utils.js'); App({ // 全局公共方法 utils: utils, }) 接著,,假如在test頁面里,,需要使用全局方法來處理數(shù)據(jù)的美元、RMB價(jià)錢以及平方英尺,、平方米換算,。使用方法很簡單:在test.js里,,在data里聲明好變量,,然后就可以在下面使用全局方法來處理數(shù)據(jù)了。 例子: /* test.js */ // 獲取全局應(yīng)用程序?qū)嵗龑ο?/span> const app = getApp(); Page({ /** * 頁面的初始數(shù)據(jù) */ data: { price: null, }, /** * 生命周期函數(shù)--監(jiān)聽頁面加載 */ onLoad: function (options) { //js里只能這樣使用util全局方法,,結(jié)合data聲明的變量處理數(shù)據(jù) //此處是判斷服務(wù)器接口返回的數(shù)據(jù)字段是否為null,,如res.data.price = 123 this.setData({ price: app.utils.isNull0(res.data.price) }); }, }) /* test.wxml */ <view>{{ price }}</view> //最終頁面呈現(xiàn)為<view>123</view>,如果服務(wù)端接口返回的price字段是null的話,,那么經(jīng)過全局方法判斷后,,頁面這里應(yīng)該顯示- 以上這些就是小程序page子路由頁面如何使用utils全局方法的全部內(nèi)容了,這一點(diǎn)算是我入手小程序這幾天以來遇到的比較惡心?的了,,相比用vue開發(fā)webapp項(xiàng)目,,小程序這一點(diǎn)真的是反人類,很不方便?,。 2,、UI庫的使用,我用了有贊的vant-weapp和iView-weapp,。 使用方法: vant-weapp:https://github.com/youzan/van...,, iView-weapp:https://github.com/TalkingDat..., 把代碼包下載到本地后,,把里面的dist目錄放到小程序的components目錄下,,最終結(jié)構(gòu)為 然后在app.json里面定義好usingComponents字段,用到哪個組件,,按照其官方文檔的使用指南,,把組件引入到usingComponents里面就行了,注意相對路徑要設(shè)置好,,不然會報(bào)錯,。 例如我目前開發(fā)的小程序項(xiàng)目暫時用到了這幾個組件,之后開發(fā)完以后,,dist目錄里沒有用到的組件可以刪掉,。 "usingComponents": { "van-row": "../components/vant-weapp/dist/row/index", "van-col": "../components/vant-weapp/dist/col/index", "van-toast": "../components/vant-weapp/dist/toast/index", "van-notify": "../components/vant-weapp/dist/notify/index", "van-tab": "../components/vant-weapp/dist/tab/index", "van-tabs": "../components/vant-weapp/dist/tabs/index", "van-search": "../components/vant-weapp/dist/search/index", "i-spin": "../components/iView-weapp/dist/spin/index", "i-button": "../components/iView-weapp/dist/button/index", "i-drawer": "../components/iView-weapp/dist/drawer/index" } 3,、小程序的頁面間跳轉(zhuǎn)有些規(guī)則的,vue開發(fā)wabapp項(xiàng)目,,跳轉(zhuǎn)路由一般使用編程式導(dǎo)航的話是這樣的: this.$router.push({path: "/houseDetails", query: {id: id}}); //傳參在query里定義,。 而小程序的跳轉(zhuǎn)有4種: (1)、wx.navigateTo(Object object);//保留當(dāng)前頁面,,跳轉(zhuǎn)到應(yīng)用內(nèi)的某個頁面,。但是不能跳到 tabbar 頁面。使用 wx.navigateBack 可以返回到原頁面,。 (2),、wx.redirectTo(Object object);//關(guān)閉當(dāng)前頁面,跳轉(zhuǎn)到應(yīng)用內(nèi)的某個頁面,。但是不允許跳轉(zhuǎn)到 tabbar 頁面,。 (3)、wx.reLaunch(Object object);//關(guān)閉所有頁面,,打開到應(yīng)用內(nèi)的某個頁面 (4),、wx.switchTab(Object object);//跳轉(zhuǎn)到 tabBar 頁面,并關(guān)閉其他所有非 tabBar 頁面 剛開始開發(fā)首頁的時候,,用bindtap點(diǎn)擊事件綁定一個方法,,在里面用 navigateTo 怎么點(diǎn)都不跳轉(zhuǎn),沒反應(yīng),,第二天仔細(xì)看文檔才發(fā)現(xiàn),,要跳轉(zhuǎn)的頁面是 tabBar 頁面,所以向 tabBar 頁面跳轉(zhuǎn)的時候,,不能使用navigateTo,,要用 switchTab 方法來跳轉(zhuǎn)?。 4,、安裝npm第三方插件,,參考此文檔,https://developers.weixin.qq....,。 具體步驟: (1),、先在本項(xiàng)目里打開命令行,然后npm install --production (2),、跑完以后,,比如要安裝moment.js 則 npm install moment --save (3)、安裝完后 去微信開發(fā)者工具里找到菜單欄 -> 工具 -> 構(gòu)建npm 點(diǎn)擊執(zhí)行,,等待完成,。 (4)、構(gòu)建完后,,項(xiàng)目根目錄里會多出一個miniprogram_npm目錄,,里面就是安裝好的moment.js插件,。 然后在utils.js引用: // moment時間格式化 import moment from 'moment'; // moment.locale('zh-cn');//加載中文包 然后就可以在下面的全局方法 momentFormat(函數(shù)名自己取的) 里利用moment.js的 API 正常處理數(shù)據(jù)了。 5,、js里的方法不能用es6的箭頭函數(shù),,只能用function(),否則會報(bào)錯this指向,,查看報(bào)錯信息里,,this是undefined,暫不知是什么原因,。 例如: keywordChange: app.utils.debounce((e) => { this.setData({ searchKeyword: e.detail });//此時的this是undefined 所以這行會報(bào)錯 if (app.utils.getByteLen(e.detail) > 3) { this.setData({ searchLoaderShow: true }); } }, 500) keywordChange: app.utils.debounce(function(e) { this.setData({ searchKeyword: e.detail });//不用es6的箭頭函數(shù)就沒問題 if (app.utils.getByteLen(e.detail) > 3) { this.setData({ searchLoaderShow: true }); } }, 500) 6,、bindtap點(diǎn)擊事件的方法傳參要這么寫才行: <view bindtap="gotoDetails" data-searchType="{{ item.id }}"></view> //方法里這樣獲取點(diǎn)擊事件要用的key-value gotoDetails(e){ let url = '/pages/details/details?id='+ e.currentTarget.dataset.searchtype; //這里有個坑,綁定事件的設(shè)置參數(shù),,如果參數(shù)名有大寫字母的話,,下面獲取的時候要用小寫的,不然會報(bào)錯undefined,。例如:data-searchType -> e.currentTarget.dataset.searchtype wx.navigateTo({ url: url }) } //不能像vue項(xiàng)目那樣,,直接在括號里跟參數(shù),,會報(bào)錯,,哎,小程序有些地方真的反人類? <view bindtap="gotoDetails(id)"></view> 7,、報(bào)錯:wx.switchTab: url 不支持 queryString 意思是tabBar頁面不支持url傳參,,只能利用app.js定義好globalData里的query參數(shù),在要跳轉(zhuǎn)的頁面里賦值,,就可以了,。 8、吐槽下微信開發(fā)者工具的版本管理,,真TMD難用,,還不如直接用命令行操作git來的方便,跟intellij IDEA 內(nèi)置的Git管理工具差遠(yuǎn)了,。 附個微信開發(fā)者工具的版本管理的設(shè)置教程:https://static.oschina.net/ne... 9,、微信小程序設(shè)為體驗(yàn)版后,不能加載數(shù)據(jù),,進(jìn)去首頁后會彈個Toast 輕提示 報(bào)錯:Object Object 經(jīng)過百度搜索,,可能是這些原因:域名已經(jīng)備案、https已經(jīng)配置,、ssl證書在1.2以上版本,、小程序后臺已經(jīng)配置服務(wù)器域名 10、小程序遍歷對象要用wx:for-index屬性 <view wx:for="{{ obj }}" wx:for-item="item" wx:for-index="key"> <view class='aside'>{{ key }}</view> </view> 11,、小程序的自定義組件有些像vue的組件化,,比如詳情頁類型的內(nèi)容結(jié)構(gòu)復(fù)雜的頁面或者是有2處及以上有復(fù)用需求的,,可以用自定義組件來實(shí)現(xiàn),具體教程可參考: https://developers.weixin.qq.... https://blog.csdn.net/qq_4181... 注意:自定義組件不能用wxs,。 12,、如果小程序頁面要做echarts圖表可視化功能,但是echarts圖表有很多,,需要進(jìn)行封裝,,這種情況最好還是采用小程序的webview API來實(shí)現(xiàn), 具體教程可參考: https://developers.weixin.qq.... https://www.jianshu.com/p/292... 已經(jīng)有做好的webAPP項(xiàng)目,,但是要同步開發(fā)小程序,,詳情頁有很多echarts圖表,這種情況就很適合用webview,,我剛開始的時候不知道webview,,在研究自定義組件,在構(gòu)思怎么封裝全局可使用的line,、bar、pie,、面積圖這四種公共組件,,當(dāng)時沒想好怎么做,很麻煩,。后來CTO告訴我用webview來實(shí)現(xiàn)。 比如已經(jīng)做好了一個vue框架的webapp項(xiàng)目,,然后只需要vue-cli再起一個vue項(xiàng)目,,然后把以前做好的詳情頁圖表相關(guān)的代碼結(jié)構(gòu)照搬過來就行了,無非就是改一點(diǎn)兒東西,。 比如我的web端項(xiàng)目的詳情頁加起來有9個模塊,,近百個echarts圖表,如果用戶初次進(jìn)入頁面就加載全部的接口,,那么瀏覽器內(nèi)存會很高,,用戶會卡死幾秒的時間,體驗(yàn)很差,,所以用戶初次進(jìn)入頁面是默認(rèn)不加載圖表相關(guān)接口的,。我采用了每個模塊做成折疊面板的方案,點(diǎn)擊展開時展示該模塊下的所有圖表,,收起時銷毀圖表實(shí)例釋放內(nèi)存,,并且只在第一次展開時加載接口,后面收起再展開時就不需要重復(fù)請求接口了,。 而小程序webview所需的vue項(xiàng)目,,比如詳情頁9個模塊,,可以在小程序里定義為9個page頁面,然后點(diǎn)擊每個模塊時跳轉(zhuǎn)到這個模塊對應(yīng)的page頁面,,并且把這個模塊下所有圖表所需的參數(shù)(比如商品id),,通過url傳過去。然后這個page的wxml里放webview組件,,動態(tài)設(shè)置src,。js里獲取從詳情頁點(diǎn)擊模塊跳轉(zhuǎn)過來時所攜帶的query參數(shù),拼接好以后,,setData設(shè)置webviewURL,。大概是這樣: <!--商品詳情頁——圖表模塊標(biāo)題--> 點(diǎn)擊圖表模塊時跳轉(zhuǎn)到這個模塊對應(yīng)的page頁面,并且攜程必備query參數(shù)過去,,比如我是這樣寫的: <van-cell-group> <van-cell icon="location-o" title="查看圖表詳情" url="/pages/Details_RegionSituation/Details_RegionSituation?id={{id}}&zip={{zip}}" is-link /> </van-cell-group> 然后這個圖表模塊的page頁面獲取上面穿過來的query參數(shù),,并進(jìn)行拼接處理,處理好后setData設(shè)置webview的src,,我是這樣寫的: <!--圖表模塊的采用webview組件的page頁面——wxml--> <view class="page-body"> <view class="page-section page-section-gap"> <web-view src="{{ webviewURL }}"></web-view> </view> </view> <!--圖表模塊的采用webview組件的page頁面——js--> data: { id: null, //商品id zip: null, }, onLoad: function (options) { // console.log(options) //獲取url參數(shù) this.setData({ id: options.id || null, zip: options.zip || null }); let url = `https://-----此處為你配置的業(yè)務(wù)域名-------/situation?id=${this.data.id}&zip=${this.data.zip}`; // situation為模塊頁面名稱,,隨便你怎么定義。后面就是query參數(shù) this.setData({ webviewURL: url }); }, 【之所以項(xiàng)目詳情頁里有9個圖表模塊,,小程序就要新建9個page頁面,,是因?yàn)橐粋€page頁面只能放一個webview組件,并且會覆蓋掉其他組件,?!?/span> 然后在vue項(xiàng)目里獲取到小程序webview src跳轉(zhuǎn)的時候攜帶的query參數(shù),然后進(jìn)行接口請求數(shù)據(jù),,配置圖表,就完事兒了,。 記得退出頁面時也要銷毀圖表實(shí)例,,vue項(xiàng)目的生命周期是這樣的: beforeDestroy () { if(this.myEcharts){ this.myEcharts.dispose(); } }, 具體流程就是以上這些了,并不復(fù)雜,。 這樣下來節(jié)省了大量的工作,,詳情頁9個圖表模塊,加起來近百個echarts圖表,,用webview從無到有只用了三四天時間,,我就不用頭疼麻煩的用小程序的自定義組建來實(shí)現(xiàn)需求了。 |
|