第一次接觸小程序大概是17年初,當時小程序剛剛內側,當時就被各類限制折騰的死去活來的,單向綁定,
沒有promise,請求數限制,包大小限制,各類反人類,...反正我是感覺到了滿滿的惡意.
最近接到一個工程類的小程序項目,作技術選型的時候,又把之前的東西撿起來看了看,從新熟悉了一下,
感受小程序仍是有在努力的,支持大部分es6語法了,還出了一個類Vue的mvvm框架wepy,還支持redux狀態管理,
就大體建了個demo,跑了起來,趕忙雖然沒有vue那麼酸爽,可是仍是挺ok的,至少比原生的小程序語法親民不少.
而後就開始用wepy搭項目,寫靜態頁面(因爲公司的開發模式是先寫靜態頁面,
等待後端的同窗接口出來了再綁定數據),雖然wepy用起來比原生的順手,
可是仍是有不少坑的,這裏就不列舉了.....vue
就在咱們靜態頁面快寫完的時候,某天晚上論壇的時候看到一條消息, 美團出了個小程序框架mpVue
(不知道爲何,每次看到這個名字,我只想到3個字,沒朋友,哈哈),
大體看了一下官方的介紹,主要有一下亮點:webpack
也就是說,不但能夠用咱們熟悉的vue語法開發,還有可能直接把你的h5頁面編譯成小程序.
該項目到目前位置,開源不到20天,已經收到將近7000個star,可見天下苦秦已久。git
建了個demo,跑了一下,感受簡直就是開發界的良心之做啊.順便把以前寫的wepy的靜態頁面代碼複製過來看了一下,
發現只要改動一點點,就能夠順利從wepy切換到mpvue上來(整個項目的切換時間在半天左右).
說作就作,當天就切到mpvue.一直到如今項目接近尾聲了,整個開發過程,真是使人愉悅.es6
Bug....我今天好像不是來給mpvue作廣告的,我是來找茬的..github
下面就盤點一下我最近用mpvue開發,遇到的一些須要須要注意的細節.(或者說跟vue不一樣的地方)web
一, 這個我的感受是最大的坑,除了缺乏文件會報錯外,其餘的代碼語法錯誤等,
控制檯大部分時間都是安靜的(偶爾也會報一個xxx is undefined)
比較常常碰到的是這樣 this.xxx =5 有些狀況下會報錯,而有些狀況下則沒有任何反應,
具體什麼狀況下會,什麼狀況下不會,我如今還沒摸出規律來..vuex
有一次我把json
this.dataObject.map(() => { ...這裏省略... })
結果map前面的 . 不當心給露掉了,實際代碼變成redux
this.dataObjectmap(() => { ...這裏省略... })
結果找了半天沒找到問題的緣由 canvas
二, 這個也是比較難受的地方,就是模板的數據綁定裏面,沒辦法在模板語法裏面調用methods方法
(或者說沒辦法調用computed之外的函數),有人也許會說,那能夠用computed屬性,那若是我想給函數傳參怎麼辦?
看下面代碼:
<template> <view v-for="item in costList" > {{formatCost(item)}} </view> </template> <script> export default { data(){ return{ costList:[] } }, methods: { formatCost(item){ return item.toFixed(2) }, getData(){ let arr = [3.255,4.1,5,15] this.costList = arr } } </script>
這個時候 {{formatCost(item)}}
裏面的內容,會渲染成空字符串,理由就是由於不支持函數,並且這中狀況,
也沒法使用computed屬性,除非你想爲每一個數組元素寫一個computed
這種狀況,個人解決方案是在在獲取到數據的時候,就先把數據改了.如上面的例子,咱們能夠在 getData方法裏面這樣寫
let arr = [3.255,4.1,5,15] // 遍歷數組裏面的元素,而後格式化一下,添加到 costList裏去 arr.map(item => { this.costList.push = this.formatCost(item) })
三, 全部頁面裏面的created生命週期函數 都會在小程序加載的時候,
一次性執行,而不是每進入一個頁面執行一次,如,我有3個頁面
pageA
...省略一些代碼... creatted(){ console.log('pageA 的 created函數執行') }
pageB
...省略一些代碼... creatted(){ console.log('pageB 的 created函數執行') }
pageC
...省略一些代碼... creatted(){ console.log('pageC 的 created函數執行') }
而後,啓動小程序,不進入這3個頁面,假設我如今有一個index頁面,咱們打開這個頁面,會有一下輸出
pageA 的 created函數執行 pageB 的 created函數執行 pageC 的 created函數執行
這個其實很好解決,用mounted或者onLoad或者onReady代替,說到這幾個函數,那就順便提一下,
這裏的created和mounted是vue(mpvue)的生命週期,而onLoad、onReady是小程序的生命週期,mpvue官方給的說明是:
除了 Vue 自己的生命週期外,mpvue 還兼容了小程序生命週期,這部分生命週期鉤子的來源於微信小程序的
Page, 除特殊狀況外,不建議使用小程序的生命週期鉤子。
可是官方給的生命週期圖示裏面,也代表了,小程序的onLoad、onReady比created、mounted執行的早,
也就是說若是咱們在和onLoad onReady裏面去請求數據的話,會相對的減小白屏時間(這裏說的白屏是指數據未渲染的界面),
並且官方沒說明爲何不建議使用小程序的生命週期,咱們也嘗試了,用小程序的生命週期,沒發現生命問題,
因此咱們仍是比較傾向優先使用小程序的生命週期,畢竟用戶體驗纔是王道。
4、掛載在Vue.prototype上的屬性,在模板語法裏面是undefined,必須通過computed計算過一下才能用。
在用vue的時候,我喜歡把圖片的服務器路徑存到vue的原型裏面:
import config from './config' Vue.prototype.$serverPath = config.serverPath
而後 咱們在頁面裏面這樣用
<img :src="$serverPath + 'logo.png'" />
這樣 就能夠避免在每一個頁面導入config文件,後期若是咱們發佈正式版的時候,只要在這邊修改一下config配置文件就能夠了
然額,這樣寫在mpvue裏面,實際渲染出來的會是
<image src="undefinedlogo.png" ></image>
要想在每一個頁面裏面使用,只能乖乖在每一個頁面裏面導入,或者在computed裏面返回this.$serverPath
5、用 v-for循環的時候,若是要給當前項指定一個索引,在vue下,爲了省事,我一般喜歡這樣作
v-for="item,index in list"
由於多打一對括號真的是很煩人。可是在mpvue下面卻不行,你必須老老實實這樣寫,不然會報錯。
v-for="(item,index) in list"
6、單獨爲每一個頁面的設置頁面頭部信息,有提供這個功能,不過文檔不是很詳細,幾經嘗試,才試出來。
咱們的入口文件main.js(延續vue的叫法,暫且這麼稱呼吧,其實我以爲應該叫配置文件)裏面能夠這樣配置,
官方文檔大概也是這麼說的
這部份內容來源於 app 和 page 的 entry 文件,一般習慣是 main.js,你須要在你的入口文件中
export default { config: {} },這才能被咱們的 loader 識別爲這是一個配置,須要寫成 json 文件。
import Vue from 'vue'; import App from './app'; const vueApp = new Vue(App); vueApp.$mount(); // 這個是咱們約定的額外的配置 export default { // 這個字段下的數據會被填充到 app.json / page.json config: { pages: ['static/calendar/calendar', '^pages/list/list'], // Will be filled in webpack window: { // 頂部欄的統一配置 backgroundTextStyle: 'light', navigationBarBackgroundColor: '#455A73', navigationBarTitleText: '美團汽車票', navigationBarTextStyle: '#fff' } } };
同時,這個時候,咱們會根據 entry 的頁面數據,自動填充到 app.json 中的 pages 字段。
pages 字段也是能夠自定義的,約定帶有 ^ 符號開頭的頁面,會放到數組的最前面。
咱們看到,能夠在config.window下面配置全局的頂部欄樣式,可是若是咱們想爲每一個頁面指定一個樣式呢?事實上,
以上方法只適合配置app.json裏面的內容,若是你想要爲你的每一個頁面都添加一種樣式,那麼應該這樣作:
在頁面所屬的入口文件(main.js)裏面添加如下內容,好比我想爲 userCenter/index頁面設置一個標題,
應該在userCenter/main.js裏面加入
export default { config: { navigationBarTitleText: '我的中心', } }
注意 這裏跟上面那個全局配置不一樣的是,配置內容navigationBarTitleText是config的屬性,
而全局配置裏,則是config.window的屬性
7、組件的命名問題,有一次,我寫了一個局部的組件,爲何叫局部的組件呢,由於我只在某個頁面裏面使用,
因此爲了簡單化,我給這個組件取了個名字叫list.vue
,而後在父組件引用:
<template> <!-- 省略其餘代碼 --> <list /> </template> <script> import list from './components/list' export default { components: {list}, // 省略其餘代碼 } </script>
組件能正常顯示,樣式也沒問題,一切看上去都是那麼的正常,然而組件裏面的邏輯就是不會執行。
加上本文第一點提到的,不會報錯,讓我一頓好找啊...
通過排查發現,跟組件的引入名稱有關,應該是跟微信的關鍵字同名了。
<template> <!-- 省略其餘代碼 --> <listA /> </template> <script> import listA from './components/list' export default { components: {listA}, // 省略其餘代碼 } </script>
這樣就能正常運行,出了list,我目前踩到的還有tabbar,搞得我如今命名的時候,看到一些疑似關鍵的字眼,心理都有點陰影。。
這個應該是微信的問題吧,總之遇到了,就一塊寫出來。
8、組件第一次加載的時候不能執行onShow裏面的內容,只有在隱藏又顯示後,纔會顯示,而頁面卻每次進入都會顯示
例如咱們在一個組件裏有一下代碼
onLoad () { console.log('onLoad') }, onShow () { console.log('onShow') }, mounted () { console.log('mounted') },
頁面加載的時候,咱們指望打印出來的是
onLoad onShow mounted
而後實際上,只打印出
onLoad mounted
這個問題,我已給官方提Issue,不過目前還沒獲得迴應
說到這裏,咱們順便看看小程序的頁面跳轉方式,小程序在一個頁面跳轉(調用wx.navigateTo)到另外一個頁面的時候,
並不會銷燬原來的頁面,而是轉到後臺去,而且執行原頁面裏面的onHide裏的代碼,
這也是爲何小程序的頁面路徑最多隻能十層,由於你訪問過的頁面,正常都會保存在內存裏,至關於vue裏的keep-alive,
若是容許跳轉很是多頁面的話,很容易致使內存使用太高。
固然,咱們也可使用wx.navigateBack wx.redirectTo wx.reLaunch 來銷燬頁面,這3個方法,會調用頁面的onUnload函數
9、canvas放在scroll-view不會隨着頁面滾動,看起來好像是fixed固定在某個位置的,可是在普通的view裏面卻能夠正常滾動。
這個問題實際上是微信的問題,官方文檔裏面是有說明這點,不過我碰見問題的時候,沒想到會是微信官方出的問題,各類百度谷歌,
都沒找到這跟這個問題有關的,甚至我很懷疑是我本身代碼的問題,因而新建了一個項目,而後直接考官方的示例代碼,也是同樣的效果。
後面就準備放棄,想其餘解決方案了,沒想到今天在官方文檔 -scroll-view組件
的介紹的最底部的 小字 裏看到了
tip: 請勿在 scroll-view 中使用 textarea、map、canvas、video 組件
進一步查看了canvas組件
的文檔,發現也有相似的提示
tip: 請勿在 scroll-view、swiper、picker-view、movable-view 中使用 canvas 組件。
之因此把這一點也算進來,一是爲這個問題坑了我好幾天,我都在想其餘方案了,二是這幾天各類百度谷歌,
是有搜到幾個相似的問題,可是都沒人回答,我就在這邊記錄一下,但願後面踩到這個坑的童鞋能搜到。
10、同一個子組件,在2個不一樣的地方引用,會致使2個地方的樣式都加載不了,而若是隻在一個地方引用卻沒問題,
爲何把這個問題放到最後? 由於這只是前幾個版本的腳手架有這個問題,後面的應該就沒有這個問題了。
這個問題我也給官方提過Issue,官方給的回答是用新版本的腳手架從新生成項目,可是項目都快作完了,
這個時候從新生成,而後拷貝代碼,感受心太累了,因此抱着不折騰不罷休的態度,終於找到緣由,是由於早期版本的腳手架,
缺乏了 webpack-mpvue-asset-plugin 這個插件,新版的cli裏面會自動添加這個插件。具體看Issue #180
還有一些官方明確指出的問題,這裏就不一一列舉了,有興趣的童鞋能夠直接查看mpvue官方文檔
另外,最近正在作一個mpvue的基礎教程,有興趣的童鞋請前往個人
github mpvue-tutorials,您的一個Star,就是我最大的動力了。