首先要聲明的是,我是一名 Android 開發(fā)者,之前基本沒有前端開發(fā)經(jīng)驗,甚至連 JS ,HTML 都是為了開發(fā)小程序現(xiàn)學(xué)的一些皮毛——所以文章中所提到的一些點也許在資深前端開發(fā)者看來只是小case,但是站在一個 Android ...
前言首先要聲明的是,我是一名 Android 開發(fā)者,之前基本沒有前端開發(fā)經(jīng)驗,甚至連 JS ,HTML 都是為了開發(fā)小程序現(xiàn)學(xué)的一些皮毛——所以文章中所提到的一些點也許在資深前端開發(fā)者看來只是小case,但是站在一個 Android 開發(fā)者的角度來看確實是大坑。 前面就不說太多東西了,文章的末尾再談?wù)勎覍π〕绦虻囊恍┛捶?mdash;—這篇文章主要是談?wù)勗陂_發(fā)小程序的過程中遇到的一些坑。 PS:推薦一下我寫的一個微信小程序版的Gank客戶端:wechat-weapp-gank
正文1,獲取小程序開發(fā)工具并正確安裝?最近在一些地方看到很多人在入小程序坑的第一步就出現(xiàn)了很多的問題,其實很早之前(22號)關(guān)于怎樣搞定小程序的開發(fā)工具就已經(jīng)有比較好的資料了,大家可以直接去看一下然后照著做,基本上就沒啥問題:獲取小程序開發(fā)工具并正確安裝的教程 2,直接在微信開發(fā)工具上寫代碼?目前來講,我們只能在微信的開發(fā)工具上編譯小程序的代碼,但是這并不意味著我們必須要在那個開發(fā)工具上寫小程序的代碼——用過那個開發(fā)工具的人就會知道,那個開發(fā)工具并沒有多好用,代碼提示挺弱雞的,而且沒有自動保存是硬傷。 那么怎么辦呢?我們完全可以在別的工具里面寫代碼然后在小程序的開發(fā)工具里面編譯。我試過 sublime 和 webstorm , 都是可以在上面開發(fā)的,但是最后還是發(fā)現(xiàn) ws 更好用。我就不講 sublime 怎么用了,大家只需要直接在里面打開項目文件夾然后點右下角選擇當(dāng)前的語言就可以了。接下來著重講一講如何在 ws 里面編寫小程序代碼。 首先選擇小程序的目錄在 ws 里面打開,這是很簡單的。但是這個時候打開里面的文件之后你會發(fā)現(xiàn),除了 js 代碼它能認(rèn)出來之外,其他的代碼他都并不能夠認(rèn)出來——主要是 .wxml 和 .wxss 文件。為什么呢?因為雖然 .wxml 和 .html 文件很像,.wxss 文件和 .css 文件很像,但是編譯器并不知道!這樣一來,我們就無法在這兩種文件里面享受 ws 強大的代碼提示功能了——我們能接受這種事么?果斷不能!那么接下來我們應(yīng)該怎么辦呢?告訴編譯器,.wxml 格式的其實是 HTML 文件,.wxss 格式的其實是 CSS 文件。
上圖把做這件事的流程講的很詳細(xì)了,.wxss 文件的轉(zhuǎn)化同理。這樣做了之后,編輯器就會知道他們的真實面目,然后就可以有棒棒的代碼提示了(但是請注意,有寫微信自己寫的東西編輯器不僅沒有代碼提示反而會報錯,不管他就好了)!接下來就可以直接 ws 一個桌面小程序開發(fā)工具一個桌面,在 ws 里面寫了代碼直接劃過去點編譯了。 3,跳轉(zhuǎn)page的時候怎么傳遞數(shù)據(jù)?小程序給我們開放了很好的接口來進(jìn)行頁面之間的跳轉(zhuǎn):
但是在這個地方微信官方對于這一個接口并沒有太多的描述,只是簡簡單單的給了我們一行代碼:wx.navigateTo({url: "test ? id = 1"}); ,其實這里這樣寫是有些難以理解的——test 是個什么鬼 ? id 是個什么鬼?中間那個問號是個什么鬼?這都是些什么鬼? 反正我看到的時候是一頭霧水的。不過還好,經(jīng)過一些摸索,終于知道了他們是啥。首先,代碼里的 test 代表要跳轉(zhuǎn)到的 page 的url 地址。比如:
那么代碼就應(yīng)該是: wx.navigateTo({url: "/pages/specific/specific"});
聰明的人可能已經(jīng)發(fā)現(xiàn)了,上面的代碼沒有了示例代碼里面 ? id = 1 的部分,怎么回事,是我寫錯了么?并不是。這一部分其實是跳轉(zhuǎn) page 時用來傳值的關(guān)鍵方法,并不必需,但很有用。 * ? 是一個分隔符一樣的東西,它的后面就是所有要傳到目標(biāo) page 的值。而這些值是通過鍵值對來一一對應(yīng)的,每個鍵值對之間用 & 隔開。但是要注意的是,似乎這種方式傳值只能傳 String 過去,不是 String 類型的值傳過去之后也會被轉(zhuǎn)化為 String 。*比如,我傳了個 array 和 json 過去: var arrayData = ["firstData" , "secondData"]; var jsonData = {first: "firstData" , second: "secondData"}; wx.navigateTo({url: "/pages/specific/specific ? data: " + arrayData + "&json=" + jsonData}); 結(jié)果目標(biāo)page里接受到的是: //目標(biāo)page的onLoad方法 onLoad: function (options) { //結(jié)果是:firstData , secondData console.log(options.data); //結(jié)果是:f console.log(options.data[0]); //結(jié)果是:[object Object] console.log(options.json); //結(jié)果是:undefined console.log(options.data.first); //很顯然,被轉(zhuǎn)化了 } 上面其實也演示了如何在目標(biāo) page 里面接收傳過來的數(shù)據(jù),直接在 onLoad() 里面的 options 取就可以了。 另外,其實更多的時候我們的需求并不是直接傳一個固定的參數(shù)到目標(biāo) page 里面去,而是根據(jù)用戶的一些操作傳遞不同的值到目標(biāo) page 里面去,這個時候該怎么辦呢?要知道,我們是沒有辦法獲得組件的(這點太坑了,沒有 window 和 document)。這個時候,我們可以通過 dataset 來通過綁定組件數(shù)據(jù)達(dá)到目的。什么?你不知道 dataset 是什么東西?
多讀書,多看報,多看文檔少睡覺。 4,某些圖片無法加載?這個坑真的是深坑,可能很久很久都不會遇到,但是一旦遇到真的很蛋疼。 我拿來練手的項目是 Gank.io 的客戶端,而 Gank 網(wǎng)站上的圖片都是寄放在新浪圖床上的,默認(rèn)的存儲的 url 是http://ww{1 || 2 || 3 || 4}.xxxxx.xxxxx.jpg,然后在小程序里死活都加載不出來這些圖片!!! 我一開始不知道到底是小程序的 <image> 標(biāo)簽的問題還是圖片的問題,就找了很多地方的圖片來做測試,包括 CSDN 上的,簡書上的,github 圖床上的,結(jié)果是這些圖片都可以正常顯示——甚至新浪微博上的,一些人的頭像,都可以顯示!后來我發(fā)現(xiàn),只要 URL 是 ww+數(shù)字 開頭的圖片,都不能正常的顯示!這也太坑了。。。后來我就在思考怎么解決這個問題——要么改變 標(biāo)簽,他自身肯定是有問題的,可能對某些來源的圖片不太友好;要么改變圖片,讓它去適應(yīng)這個 標(biāo)簽。這兩方面要改其實都挺難的,但是顯然第一種方式基本上是不可能的,就只能在第二種方式上去下功夫。 最后經(jīng)過不斷地嘗試,我總結(jié)了很多規(guī)律,最后通過把圖片的 URL 由 ww+數(shù)字變成 ws+數(shù)字 解決了這個問題,讓圖片得以顯示在小程序上。比如: 本來的URL: http://ww1.sinaimg.cn/large/610dc034jw1f87z2n2taej20u011h11h.jpg 變換之后的URL: http://ws1.sinaimg.cn/large/610dc034jw1f87z2n2taej20u011h11h.jpg 不要問我為什么這樣改了就可以顯示了,因為我也不知道。。。太神奇了。。。 5,this.setData() 顯示沒這個方法?首先想要說的是,作為一個 Android 開發(fā)者,我非常不適應(yīng)小程序的數(shù)據(jù)與控件綁定的方式。在 Android 開發(fā)的時候,我們是可以直接獲得控件然后對控件做數(shù)據(jù)綁定的工作的,而在小程序里,我并不能夠直接獲得控件的對象,所有的數(shù)據(jù)綁定與動態(tài)修改只能通過維護(hù) Page 里面的 data{} 以及調(diào)用setData() 方法來進(jìn)行,我不好評判這兩種方式的優(yōu)劣,只能說真的很不習(xí)慣。 但是有些和我一樣以前沒怎么接觸過前端開發(fā)的朋友在做這個的時候就有可能會踩坑了——setData() 是 Page 這個層級上的方法,并不是在任何地方調(diào)用 this.setData() 方法都可以順利的得到我們預(yù)期的結(jié)果的。比方說: Page({ onLoad: function (options) { wx.request({ url: Constant.GET_URL, success: function (res) { this.setData({...}); } }); }, }); 我在 wx.request() 的回調(diào)接口里面 success() 里面寫 this.setData({...}),就不能完成預(yù)期操作,程序會報錯說沒有 setData() 這個方法,因為這個時候 this 獲取到的已經(jīng)并不是 Page 了,上下文已經(jīng)發(fā)生了變化,那么當(dāng)前層級沒有 setData() 方法就很正常了。那么怎么解決這個問題呢?像這樣: Page({ onLoad: function (options) { that = this; wx.request({ url: Constant.GET_URL, success: function (res) { that.setData({...}) } }); }, }); var that; 和一開始的區(qū)別在于多了一個全局變量 that,并且在 onLoad() 方法里面對它進(jìn)行了賦值,使它等于 this。這樣的話,我們就可以在這個 Page 的任何地方調(diào)用 that.setData() 來動態(tài)的改變控件的屬性了。 結(jié)語本來是還有一些問題要談一談的,但是寫到這里篇幅已經(jīng)挺長的了,就干脆把其他的放到下一篇里面算了。剩下的問題還有:
接下來我想談一下我對小程序的看法。 |