1、頁面文件App跟Page的關(guān)系是,App在整個小程序中只能有一個,唯一的一個。但這個小程序中可以有多個頁面,就是多個Page,這些頁面相關(guān)的文件都放在根目錄下的pages目錄,每個頁面主要由四類文件組成,分另以頁面名命名,但不同的后綴的文件:xxx.js / xxx.wxml / xxx.wxss / xxx.json,如下圖: 文件夾的層次結(jié)構(gòu)可以隨便定義,甚至你想放到根目錄其實都是可以的,只是同個頁面相關(guān)文件要同名,且放同個目錄。那么問題來了,程序怎么知道你的頁面都放哪呢? 可能有讀者已經(jīng)回想起第一篇文章中講到的 app.json 這個配置文件了。其中有一個pages的屬性,它用來聲明這個程序中到底有哪些頁面的:
2、例子簡介下面我們先來總體分析一下這個小例子。上圖: 3、wxml代碼分析(1)相關(guān)組件
view元素就相當于HTML中的<div>元素。重點介紹一下scroll-view組件,點擊查看官網(wǎng)文檔。它用來定義一個可滾動的視圖區(qū)域,相當于ios開發(fā)中的UIScrollView。里面的內(nèi)容如果超過這個區(qū)域的寬或高時,就會出現(xiàn)滾動條。上面定義的class為scroll-view-item的view就是一個36Kr的新聞項,一條新聞,布局很直觀,左側(cè)一個image,右側(cè)一個新聞標題的<text>,加上補充信息。<text>相當于<p>標簽,用來包裹文本內(nèi)容。<image>就是圖片元素,相當于HTML中的<img>標簽。scroll-view有一些屬性,重點介紹幾個,它默認是不允許滾動的,用scroll-x來設(shè)置橫向滾動(默認false),scroll-y設(shè)置豎直滾動(默認false)。bindscrolltoupper,這個屬性用來設(shè)置滾動到頂部/左邊時,觸發(fā) scrolltoupper 事件,用這個來做刷新。bindscrolltolower用來設(shè)置滾動到底部/右邊時,觸發(fā) scrolltolower 事件,可以用來做加載更多的操作。本例子中沒有用到這兩個,不過加到代碼中用來做使用說明。bindscroll用來綁定滾動時觸發(fā),這個可以用來做用戶手勢的判斷等。其它屬性,讀者可以參數(shù)官方文檔。 (2)數(shù)據(jù)綁定
data字段,用來定義當前頁面的所有的數(shù)據(jù),可以理解為數(shù)據(jù)層,剛剛的wxml是view層,而Page({…})里的其它地方就是邏輯層。一個完整的MVC模型就很好理解了。 wxml里有個語法:wx:for,它會解析后面news這個數(shù)組,循環(huán),一個個取出數(shù)據(jù),并賦給item變量,里面就可以通過{{item.xxx}}來引用這些數(shù)據(jù)了。所以代碼寫起來非常簡潔。類似wx:for的還有wx:if等等,wx:if用來定義一個條件判斷,如果成立,就會解析當前標簽及其子標簽。{{…}}這里面除了以上提到的用法外,還可以做四則運算、三目運算、邏輯大小判斷、字符串相加等,甚至可以定義成一個json對象,如:{{a: 1, b: 2}}。還可以使用es6的語法,如{{...myJson}} ,用…把myJson這個對象解包展開平鋪到這個地方。相關(guān)的官方文檔。 有wx:if,那就應(yīng)該有wx:else了。這里給個官方的例子,看下就明白了:
文檔除了介紹if之外,還講了另一個類似功能的 hidden,使用: <block>標簽。這是一個不會顯示出來的輔助標簽,在wx:if時,如果你想作用于幾個并列在一起的標簽,那就可以用block把它們包起來。同樣,如果你在用wx:for時,遇到?jīng)]有外層標簽的情況,只有幾個標簽并排著,這時也可以用block把它們包起來。
(3)事件綁定 列表中每個item都有一個事件的綁定,catchtap="bindItemTap",綁定在用戶點擊時做頁面的切換。 組件的事件有很多種,每個組件都有自己定義的組件,如<input>有input事件,<form>有submit事件等,詳見各組件。不過有一些大部分組件都共同的事件,主要有:touchstart、touchmove、touchend、touchcancel、longtap、tap。前三個都很熟悉了,其它幾個,touchcancel指的是用戶的觸摸事件被其它東西打斷,比如突然彈窗,或者突然有個電話進來。longtap就是長按事件,微信官網(wǎng)解釋是指超過350ms的touch。tap就類似于pc瀏覽器上的click點擊事件。 這六個事件都是會冒泡的事件,如果沒有js基礎(chǔ)的朋友不太理解冒泡,這里幫你們找了些文章來理解這個 除了這六個事件之外 ,其它事件都是非冒泡事件。事件綁定的方式就是用bind或catch這兩個詞,再加上事件的名稱(全小寫)就可以了。如bindtap, catchtap。他們的差別是,bind允許冒泡傳遞,而catch會阻止冒泡,就是把所有的事件都變成非冒泡事件。每個事件的響應(yīng)函數(shù)一般會有個event參數(shù),事件對象,這個參數(shù)的event.targe指向觸發(fā)事件的組件,里面有它的一些屬性值,而event.currentTarget則指向當前事件所在的組件,currentTarget是因為事件冒泡機制而設(shè)置的,它指向事件當前指向的組件,不一定是我們設(shè)置bindtap屬性的那個組件,而target就永遠都是指向這個綁定的原組件。 接下來講下MINA設(shè)置的一個很有意思的屬性集,event.dataset,這是一個event.target指向的組件里定義的data-xxx的屬性數(shù)據(jù)的json對象,可以用event.dataset.xxx來引用,比如最上面我們本文demo的wxml代碼中,在catchtap綁定的事件的標簽里,有一個data-id屬性,那么可以用event.dataset.id來引用這個id值。如果data-xxx里有大寫,這里都會轉(zhuǎn)化成小寫,如data-myDemo,這時要用event.dataset.mydemo來引用;如果是類似data-abc-def這種格式的屬性,則會變成abcDef,-減號后面的第一個字母會被大寫。事件相關(guān)的官方文檔在這。 所以,講到這里,希望讀者能再回去讀一下最開始的那個index.wxml代碼,會有很多收獲的。 4、js代碼分析上面提到的data不是一個普通的字段,它和用戶界面綁定,改變它的值,界面里相應(yīng)的地方也會自動跟著變。這模式是不是跟react很像?目測微信小程序內(nèi)部包裝了react的核心算法和思想。data里的值 ,跟react中的state一樣,不要去直接用等號給它賦值或改變它的值,直接修改它是無效的,要調(diào)用setData(newObj)來修改,才能觸發(fā)綁定的界面更新。傳入的參數(shù),定義你要改變的那個字段就行,比如data為{a: 1, b: 2, c: 3},要修改a的值,可以這樣調(diào)用:this.setData({a: 11}),這時界面中綁定a變量的值就會立馬跟著變化。 react帶來的一個很大的思想變革就是,不希望你通過id或class去取得或設(shè)置一個頁面dom元素的值,這也是我很喜歡react的原因,其實做前端開發(fā)的朋友平時最痛苦的事情之一就是,獲取dom節(jié)點然后做相應(yīng)的界面更新,然后,當頁面重構(gòu)師把頁面結(jié)構(gòu)改掉的時候,前端開發(fā)的js代碼就到處冒煙了。前端另一個比較推薦的框架是angular.js,它通過事件綁定的方式來減少dom操作,更新界面。(扯遠了。) MINA框架其實幫開發(fā)者做了非常多的事情,包括剛剛提到的數(shù)據(jù)綁定、界面更新的邏輯,還有頁面切換的邏輯,它內(nèi)部幫我們管理了整個小程序的頁面路由(Page()函數(shù)什么時候調(diào)用?跳轉(zhuǎn)的時候為什么不用new頁面?),整個頁面的生命周期(下面介紹)等等,開發(fā)者只需要把數(shù)據(jù)注入到框架中,并在相應(yīng)的生命周期函數(shù)中填寫相關(guān)的邏輯代碼就可以了。 剛提到的頁面切換方式,順便介紹下鏈接跳轉(zhuǎn)的方式,跟HTML不同的地方是,它不是用類似<a>標簽來實現(xiàn)的,而是通過事件來做的。頁面跳轉(zhuǎn),通過 wx.navigateTo 這個接口來實現(xiàn),點擊進入官網(wǎng)api的說明。navigateTo會保留當前頁面的條件下,切換到新頁面,可以用wx.navigateBack 返回。然而還有另一個跳轉(zhuǎn)的api,wx.redirectTo,它則不保留當前頁面,會關(guān)閉它,官網(wǎng)沒有提供這個跳轉(zhuǎn)方式返回的api,或許這時候,要想回到之前的這個頁面,就得去新建了。 兩個跳轉(zhuǎn)函數(shù)的參數(shù)都是一個object,格式如下:
一般帶上一個url就可以了。url格式:'../article/content' 是個相對地址,指向新頁面的位置,注意不要寫后綴。 5、Page函數(shù)跟介紹App函數(shù)一樣,先來理解一下Page的生命周期。
數(shù)據(jù)可以隨便定義在Page({ … })里成為一個屬性,類似于react的props,而data屬性里定義的數(shù)據(jù)就要注意些,它類似于react的state,用來實際綁定界面數(shù)據(jù)用的,它是一個json格式的數(shù)據(jù)。
這樣就可以了,微信會幫我們把這個函數(shù)跟我們在wxml里定義的綁定關(guān)聯(lián)起來。 |
|