首先要聲明的是,我是一名 Android 開發(fā)者,之前基本沒有前端開發(fā)經(jīng)驗(yàn),甚至連 JS ,HTML 都是為了開發(fā)小程序現(xiàn)學(xué)的一些皮毛——所以文章中所提到的一些點(diǎn)也許在資深前端開發(fā)者看來只是小case,但是站在一個(gè) Android 開發(fā)者的角度來看確實(shí)是大坑。
前面就不說太多東西了,文章的末尾再談?wù)勎覍π〕绦虻囊恍┛捶ā@篇文章主要是談?wù)勗陂_發(fā)小程序的過程中遇到的一些坑。
PS:推薦一下我寫的一個(gè)微信小程序版的Gank客戶端:wechat-weapp-gank
最近在一些地方看到很多人在入小程序坑的第一步就出現(xiàn)了很多的問題,其實(shí)很早之前(22號)關(guān)于怎樣搞定小程序的開發(fā)工具就已經(jīng)有比較好的資料了,大家可以直接去看一下然后照著做,基本上就沒啥問題:獲取小程序開發(fā)工具并正確安裝的教程
目前來講,我們只能在微信的開發(fā)工具上編譯小程序的代碼,但是這并不意味著我們必須要在那個(gè)開發(fā)工具上寫小程序的代碼——用過那個(gè)開發(fā)工具的人就會知道,那個(gè)開發(fā)工具并沒有多好用,代碼提示挺弱雞的,而且沒有自動保存是硬傷。
那么怎么辦呢?我們完全可以在別的工具里面寫代碼然后在小程序的開發(fā)工具里面編譯。我試過 sublime 和 webstorm , 都是可以在上面開發(fā)的,但是最后還是發(fā)現(xiàn) ws 更好用。我就不講 sublime 怎么用了,大家只需要直接在里面打開項(xiàng)目文件夾然后點(diǎn)右下角選擇當(dāng)前的語言就可以了。接下來著重講一講如何在 ws 里面編寫小程序代碼。
首先選擇小程序的目錄在 ws 里面打開,這是很簡單的。但是這個(gè)時(shí)候打開里面的文件之后你會發(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)化同理。這樣做了之后,編輯器就會知道他們的真實(shí)面目,然后就可以有棒棒的代碼提示了(但是請注意,有寫微信自己寫的東西編輯器不僅沒有代碼提示反而會報(bào)錯(cuò),不管他就好了)!接下來就可以直接 ws 一個(gè)桌面小程序開發(fā)工具一個(gè)桌面,在 ws 里面寫了代碼直接劃過去點(diǎn)編譯了。
小程序給我們開放了很好的接口來進(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)該是:
聰明的人可能已經(jīng)發(fā)現(xiàn)了,上面的代碼沒有了示例代碼里面 ? id = 1
的部分,怎么回事,是我寫錯(cuò)了么?并不是。這一部分其實(shí)是跳轉(zhuǎn) page 時(shí)用來傳值的關(guān)鍵方法,并不必需,但很有用。
* ?
是一個(gè)分隔符一樣的東西,它的后面就是所有要傳到目標(biāo) page 的值。而這些值是通過鍵值對來一一對應(yīng)的,每個(gè)鍵值對之間用 &
隔開。但是要注意的是,似乎這種方式傳值只能傳 String 過去,不是 String 類型的值傳過去之后也會被轉(zhuǎn)化為 String 。*比如,我傳了個(gè) array
和 json
過去:
結(jié)果目標(biāo)page里接受到的是:
上面其實(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),多看文檔少睡覺。
這個(gè)坑真的是深坑,可能很久很久都不會遇到,但是一旦遇到真的很蛋疼。
我拿來練手的項(xiàng)目是 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ù)字 開頭的圖片,都不能正常的顯示!這也太坑了。。。后來我就在思考怎么解決這個(gè)問題——要么改變 標(biāo)簽,他自身肯定是有問題的,可能對某些來源的圖片不太友好;要么改變圖片,讓它去適應(yīng)這個(gè) 標(biāo)簽。這兩方面要改其實(shí)都挺難的,但是顯然第一種方式基本上是不可能的,就只能在第二種方式上去下功夫。
最后經(jīng)過不斷地嘗試,我總結(jié)了很多規(guī)律,最后通過把圖片的 URL 由 ww+數(shù)字變成 ws+數(shù)字 解決了這個(gè)問題,讓圖片得以顯示在小程序上。比如:
不要問我為什么這樣改了就可以顯示了,因?yàn)槲乙膊恢?。。。太神奇了。?!?/p>
首先想要說的是,作為一個(gè) Android 開發(fā)者,我非常不適應(yīng)小程序的數(shù)據(jù)與控件綁定的方式。在 Android 開發(fā)的時(shí)候,我們是可以直接獲得控件然后對控件做數(shù)據(jù)綁定的工作的,而在小程序里,我并不能夠直接獲得控件的對象,所有的數(shù)據(jù)綁定與動態(tài)修改只能通過維護(hù) Page 里面的 data{} 以及調(diào)用setData() 方法來進(jìn)行,我不好評判這兩種方式的優(yōu)劣,只能說真的很不習(xí)慣。
但是有些和我一樣以前沒怎么接觸過前端開發(fā)的朋友在做這個(gè)的時(shí)候就有可能會踩坑了——setData() 是 Page 這個(gè)層級上的方法,并不是在任何地方調(diào)用 this.setData() 方法都可以順利的得到我們預(yù)期的結(jié)果的。比方說:
我在 wx.request()
的回調(diào)接口里面 success()
里面寫 this.setData({...})
,就不能完成預(yù)期操作,程序會報(bào)錯(cuò)說沒有 setData()
這個(gè)方法,因?yàn)檫@個(gè)時(shí)候 this
獲取到的已經(jīng)并不是 Page 了,上下文已經(jīng)發(fā)生了變化,那么當(dāng)前層級沒有 setData()
方法就很正常了。那么怎么解決這個(gè)問題呢?像這樣:
和一開始的區(qū)別在于多了一個(gè)全局變量 that
,并且在 onLoad() 方法里面對它進(jìn)行了賦值,使它等于 this
。這樣的話,我們就可以在這個(gè) Page 的任何地方調(diào)用 that.setData()
來動態(tài)的改變控件的屬性了。
本來是還有一些問題要談一談的,但是寫到這里篇幅已經(jīng)挺長的了,就干脆把其他的放到下一篇里面算了。剩下的問題還有:
<form>
標(biāo)簽獲得的數(shù)據(jù)也不是。<form/>
里面無法獲取 <picker/>
的取值?明明文檔里有說在 <form/>
里面是可以支持 <picker/>
的,結(jié)果你會發(fā)現(xiàn)死活無法獲得他的值。接下來我想談一下我對小程序的看法。
多謝各位看官看到這,順便去點(diǎn)個(gè)star吧:wechat-weapp-gank