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