首先從(cong) 官方文檔給的框架說起,微信小程序官方文檔給出了app.js, app.json, app.wxss. 先從(cong) 這三個(ge) 文件說起. - app.js 這個(ge) 文件是整個(ge) 小程序的入口文件,開發者的邏輯代碼在這裏麵實現,同時在這個(ge) 文件夾裏麵可以定義(yi) 全局變量. - app.json 這個(ge) 文件可以對小程序進行全局配置,決(jue) 定頁麵文件的路徑,窗口表現,設置網絡超時時間,設置多tab等. - app.wxss 是小程序的公共樣式表.(為(wei) 了適應廣大的前端開發者,我們(men) 的 WXSS 具有 CSS 大部分特性。 同時為(wei) 了更適合開發微信小程序,我們(men) 對 CSS 進行了擴充以及修改。)
接著我們(men) 就結合官方給出的代碼具體(ti) 說一下上麵提到的三個(ge) 文件.
"pages": [ "pages/index/index", "pages/logs/index" ]
可以看出,每一項分別對應的都是實現文件的路徑以及他的文件名. 注意:這個配置裏麵的第一行配置是它的初始頁麵,例如上麵代碼的初始頁麵就是index這個(ge) 配置項是用來設置小程序的狀態欄、導航條、標題、窗口背景色。他給出了六個(ge) 屬性(navigationBarBackgroundColor(HexColor), navigationBarTextStyle(String-(black,white)), navigationBarTitleText(String), backgroundColor(HexColor), backgroundTextStyle(String-(dark,light)), enablePullDownRefresh(Boolean)),開發者可以根據自己的需求來進行配置.
我們(men) 詳細說一下這幾個(ge) 屬性分別的功能:
這個(ge) 配置項是用來配置頁麵底部的tab欄的,開發者可以根據自己的需求來進行配置.
注意: tabBar是一個(ge) 數組,隻能配置最少2個(ge) ,最多5個(ge) ,而且tab欄的順序是按照數組的排序來的.
tabBar官方給出了一下五個(ge) 屬性(color(HexColor), selectedColor(HexColor), backgroundColor(HexColor), borderStyle(String), list(Array) ).
接下來說說我對這五個(ge) 屬性的理解:
borderStyle 設置邊框的顏色,現在僅(jin) 支持(black和white)
上麵這四個(ge) 屬性就是按照官方給出的API來設置就可以,下麵說一下list屬性.list屬性接受的是一個(ge) 數組(Array),在list下麵配置的每一項都是一個(ge) 對象,他們(men) 都有以下這四個(ge) 屬性(pagePath(String), text(String), iconPath( String), selectedIconPath(String)).
pagePath 這個(ge) 定義(yi) 的是頁麵的路徑,但是這個(ge) 屬性定義(yi) 的路徑必須是在pages上定義(yi) 過的.
text 設置的是按鈕上的文字
iconPath 是定義(yi) icon圖片的路徑,這個(ge) 屬性定義(yi) 的圖片大小不超過40kb selectedIconPath 定義(yi) 的是當選中按鈕之後顯示的圖片,同樣圖片的大小不能超過40kb.
下麵是官方給出的效果圖:
它是用來設置各種網絡請求的超時時間的,單位是毫秒,官方給出了四個(ge) 屬性(request, connectSocket, uploadFile, downloadFile)這四個(ge) 屬性分別定義(yi) 的是wx.request, wx.connectSocket, wx.uploadFile, downloadFile 這四個(ge) API的超時時間.
如果在app.json將debug配置為(wei) true,那麽(me) 在開發者工具的控製台麵板中可以輸出詳細的調試信息.
以上就是根據官方給出的文檔,我學習(xi) 之後對app.json配置一些心得,下麵我們(men) 在看一下app.js 這個(ge) 文件.
可以看到app.js這個(ge) 文件的後綴是js,沒錯,微信小程序的開發框架在邏輯層用的語言就是JavaScript.但是微信小程序也在JavaScript的基礎上做了一個(ge) 修改,可以稱之為(wei) 一個(ge) 新的輪子.這個(ge) 框架可以使開發者更加方便的調用一些微信的功能,例如掃一掃,微信支付等一些微信特有的功能.
我們(men) 接著回到app.js這個(ge) 文件中來,其他的稍後再說.
這個(ge) 文件是整個(ge) 小程序的入口文件,也可以說是控製整個(ge) 小程序生命周期的文件,那麽(me) 我們(men) 就不難想象,我們(men) 在這個(ge) 文件中應該實現的幾個(ge) 功能,首先我們(men) 肯定需要對整個(ge) 程序進行注冊(ce) ,正好微信給我們(men) 提供了一個(ge) app()來實現對整個(ge) 程序的注冊(ce) ,同時app()裏麵還實現了對小程序生命周期的監控函數(onLaunch, onShow, onHide), 其中onLaunch是監聽小程序初始化,當初始化完成時會(hui) 觸發onLaunch,當然這個(ge) 函數是全局隻觸發一次.onShow是監聽小程序的顯示,在小程序啟動時候,或者當你從(cong) 後台進入到前台的時候就會(hui) 觸發這個(ge) 函數.而onHide函數是監聽小程序的隱藏的,當你從(cong) 前台切換到後台的時候,會(hui) 觸發onHide.有了這些一個(ge) 小程序的實例基本上算是完成了,當然為(wei) 了讓開發者加入更多自己的邏輯,微信還提供了讓開發者在app()中加入自己的邏輯,開發者可以可以添加任意的函數或數據到 Object 參數中,用 this 可以訪問.
注意:app()隻能定義(yi) 在app.js中,而且不能注冊(ce) 多個(ge) .
當在app.js中注冊(ce) 了實例之後,如果你想在自己的邏輯頁麵調用它,你可以用getApp()這個(ge) 全局函數,這樣你就可以全局調用app()裏麵的數據.
微信給出的官方代碼如下:
注意:getApp()獲取裏實例之後,不要私自調用生命周期函數. 而且不要在app.js中用getApp()函數,用this就可以調用app()裏麵的東(dong) 西.
基本上app.js就這些東(dong) 西,還有一些API裏麵的內(nei) 容會(hui) 在後麵一一介紹.下麵我們(men) 就看一下app.wxss這個(ge) 文件,一般來說做過網站開發的(我自己是用php來開發的,這是我個(ge) 人的一點拙見,如有不對請見諒)相信對css寫(xie) 在單獨的文件中應該不會(hui) 陌生,這個(ge) app.wxss也是類似的,不過他的的配置是針對全局的,也就是說如果你在後麵的page中沒有重新配置他,那麽(me) 他就會(hui) 調用這個(ge) 文件中的樣式設置,但是如果你有個(ge) 人需求,需要在每個(ge) 頁麵重新寫(xie) 樣式,那也沒關(guan) 係,他會(hui) 自動覆蓋宰割文件中的樣式.
當你重新創建一個(ge) 微信小程序他就會(hui) 出現這幾個(ge) 文件,以上是我結合官方文檔對他們(men) 的一些理解,接下來就是page的邏輯,視圖,配置的一些心得.
這一塊就是開發者自己的業(ye) 務實現文件了. 每一個(ge) 頁麵可以放在一個(ge) 文件夾中,這個(ge) 文件夾中一般包括.js, .json, .wxml, .wxss 這四個(ge) 文件,微信官方還建議這四個(ge) 文件的名字最好和文件夾的名字一致.這個(ge) 便於(yu) 框架自動查找,不需要做更多的配置.
當你開始做頁麵的功能的時候這個(ge) 時候在.js,也需要注冊(ce) ,微信官方給出Page()這個(ge) 函數來注冊(ce) 一個(ge) 頁麵,他接受一個(ge) object參數,用其來指定頁麵的初始數據,生命周期函數,事件處理函數.需要注意的是當你在注冊(ce) 這個(ge) 頁麵的時候要確定在最開始的app.json這個(ge) 配置文件中已經配置過這個(ge) 頁麵,而且當你對程序有所改變的時候也要確保app.json這個(ge) 文件中的內(nei) 容也隨之相應改動.
微信給Page()函數一下幾個(ge) 屬性(data(Object), onLoad(function), onReady(Function), onShow(Function), onHide(Function), onUpload(Function), onPullDownRefresh(Function)),而且你也可以添加任意函數或者數據到object參數中,在這個(ge) 頁麵用this即可訪問.
下麵就簡單的介紹一下這幾個(ge) 官方給出的屬性:
下麵是微信給出的官方代碼:
上麵說了用data屬性來設置頁麵的初始化數據,但是如果我們(men) 想改變數據裏麵的值,怎麽(me) 辦??那麽(me) 我們(men) 就介紹一個(ge) 微信官方給我們(men) 提供的setData()函數,這個(ge) 函數可以將數據從(cong) 邏輯層發送到數據層,同時還可以改變this.data的值.
setData()接受一個(ge) 對象參數,讓數據以key,value的形式表示將this.data中key對應的值改變成value.下麵是微信官方給出的page的生命周期的圖片:
在小程序中的所有頁麵路由全部由框架進行管理,對於(yu) 路由的觸發方式以及頁麵的生命周期函數可以通過調用API來進行..
下麵我們(men) 就簡單的介紹一下微信小程序的API.
微信小程序框架給我們(men) 提供了豐(feng) 富的微信原生API,可以方便的調用微信提供的能力,如獲取用戶信息,本地存儲(chu) ,支付功能等.
下麵是微信關(guan) 於(yu) API提供的說明:
wx.on 開頭的API是監聽某個(ge) 事件發生的API接口,接受一個(ge) CALLBACK函數作為(wei) 參數,當事件觸發時,會(hui) 調用CALLBACK函數.
OBJECT 可以指定success,fail,complete來接受接口調用結果.
API的具體(ti) 調用請看 微信小程序API文檔
因為(wei) 現在微信小程序還在內(nei) 測期間,我也沒有內(nei) 測號,所以具體(ti) 的調用API代碼需要在微信小程序開放之後,根據具體(ti) 的邏輯進行實現.而且微信API文檔已經給的非常清楚,相信調用不會(hui) 太過困難.
上麵的這些就是微信小程序page的頁麵注冊(ce) 以及API功能實現,但是我們(men) 知道光有這些是不夠的,在互聯網發展到現在我們(men) 更加注重的是人機交互,讓用戶有一個(ge) 更好的體(ti) 驗才算是 一個(ge) 好的程序,那麽(me) 接下來我們(men) 就講講微信小程序是如何對頁麵進行渲染的。
在微信小程序中采用了微信自己原生的渲染方式。微信小程序的頁麵布局采用的是wxml,然後結合基礎組件,事件係統構建出來頁麵的結構。
wxml中有數據綁定,條件渲染,列表渲染, 模版,事件, 引用這幾種方式,下麵我們(men) 就具體(ti) 說說這幾種方式。
數據綁定 在上麵我們(men) 已經說過了在Page()注冊(ce) 頁麵的時候,裏麵會(hui) 有一個(ge) data屬性來定義(yi) 初始化數據,現在頁麵渲染的數據綁定的時候就需要調用data裏麵的數據了。下麵看一下官方給出的例子。
從(cong) 上麵的代碼可以看出來在視圖層接受邏輯層的代碼的時候需要用2個(ge) 大括號把數據的鍵值包起來就可以得到數據的值。當然在視圖層還可以進行運算(三元運算,算術運算),邏輯判斷,字符串運算,而且還可以在大括號裏麵進行組合(數組,對象(雖然可以隨意組合,但是如果後麵的變量名和前麵的變量名相同的話,那麽(me) 後麵的會(hui) 覆蓋前麵的))。
條件渲染 顧名思義(yi) 所謂的條件渲染,就是通過條件來判斷是否需要渲染該代碼塊。條件渲染主要是用到wx:if 和 block wx:if 這兩(liang) 個(ge) ,第一個(ge) 相信好理解,第二個(ge) 是在block裏麵進行條件渲染,這裏我們(men) 特別說明一下< block/>並不是一個(ge) 組件,它僅(jin) 僅(jin) 是一個(ge) 包裝元素,不會(hui) 在頁麵中做任何渲染,隻接受控製屬性。和我們(men) 以前的邏輯編程類似,既然有了wx:if ,那麽(me) 我們(men) 也會(hui) 有wx:elseif和wx.else,這幾個(ge) 組合起來,可以使條件渲染更加靈活。
在這裏官方文檔中提到了一個(ge) wx:if和hidden的對比,通過合理的運用這兩(liang) 種方法可以使你的程序更優(you) 。下麵我們(men) 就是說說他們(men) 倆(lia) 的區別:
因為(wei) wx:if之中也可能包含數據綁定,所以當wx:if的條件值切換時,框架有一個(ge) 局部渲染的過程,他會(hui) 確保條件在切換是銷毀或者重新渲染。同時wx:if也是有惰性的,如果初始渲染條件為(wei) false,框架什麽(me) 也不會(hui) 做,隻有在條件第一次變為(wei) 真的時候才會(hui) 開始渲染。相比之下hidden就簡單的多,組件始終都會(hui) 被渲染,隻是簡單的控製顯示和隱藏,一般來說,wx:if 有更高的切換消耗,而hidden有更高的初始渲染消耗,你可以根據自己的需求來調用。
列表渲染 -- wx:for
下麵我們(men) 就說說wx:for的用法,wx:for綁定一個(ge) 數組,就可使用數組中各項數據重複渲染該組件,注意默認數組的當前項的下標變量名默認為(wei) index,數組當前項的變量名為(wei) item,,當然你也可以根據自己的需要來重新定義(yi) 這兩(liang) 個(ge) 名字,使用wx:for-item可以指定數組當前元素的變量名,wx:for-index可以指定數組當前下標的變量名,wx:for也可以嵌套,這個(ge) 時候就需要改變默認框架給定義(yi) 的名字了。
下麵是官方給出的事例代碼:
模版
WXML提供模版(template),可以在模版中定義(yi) 代碼片段,然後在不同的地方調用.微信小程序的模版可以用name來命名它的名字,在使用的時候用is來聲明使用的模版,然後將模版所需要的data傳(chuan) 入即可,下麵我們(men) 用官方文檔給的代碼來看一下如何聲明及調用模版.
通過上麵對條件渲染的介紹,我們(men) 可以看到在循環掉數組[1,2,3,4,5]之後item數組屬性在三元運算中判斷調用哪一個(ge) 模版.
在這兒(er) 再多說一句模版也有自己的作用域,隻能使用data傳(chuan) 入的數據,當然data傳(chuan) 入的數據可以是你自己新建的數據,也可以是你在配置中寫(xie) 好的初始化數據.
好了現在我們(men) 說完模版了,可能有的同學就該想了,我寫(xie) 好模版之後該如何調用它,如果他們(men) 是在一個(ge) 頁麵那肯定沒問題,但是這樣的話可用性還是很差啊,如果我想把模版單獨放在一個(ge) 頁麵,在調用它的時候該怎麽(me) 辦啊?沒關(guan) 係,微信小程序早就考慮到了,那麽(me) 我們(men) 接下來就說說引用.
引用
WXML提供兩(liang) 種引用方式import和include.
接下來我們(men) 就先說說import這種方式,我們(men) 就結合代碼來看,它調用在不同頁麵的模版消息如下:
<!-- item.wxml --><template name="item"> <text>{{text}}</text></template>
在 index.wxml 中引用了 item.wxml,就可以使用item模板:
<import src="item.wxml"/><template is="item" data="{{text: 'forbar'}}"/>
這裏要注意一下,import引用也是有作用域這個(ge) 概念存在的,它隻會(hui) 定義(yi) import目標文件中定義(yi) 的template,而不會(hui) import目標文件import中的template.簡而言之就是import隻能引用template而不能引用import.
上麵說了import是如何引用的,那麽(me) 我們(men) 接著看一下include是怎麽(me) 引用的.
include引用和import唯一不同點就是他的引用相當於(yu) 複製,他會(hui) 複製< template>裏麵的全部內(nei) 容,但是不包含< template>,看一下代碼相信你可以理解的更加明白.
<!-- index.wxml --><include src="header.wxml"/><view> body </view><include src="footer.wxml"/>
<!-- header.wxml --><view> header </view>
<!-- footer.wxml --><view> footer </view>
上麵我們(men) 說的視圖層這些方法已經可以構成一個(ge) 靜態的頁麵了,但我們(men) 現在是21世紀啊,一個(ge) 沒有人機交互的程序怎麽(me) 能在這個(ge) 世界生存下來了?在用戶體(ti) 驗至上的今天,微信小程序不可能不考慮到這一點,接下來我們(men) 就說說視圖層的事件方法.
先來說說什麽(me) 是事件,相信有的人看到這兒(er) 肯定是一臉懵逼,你這說的啥玩意兒(er) ,說的這麽(me) 專(zhuan) 業(ye) ,我還不如看文檔去.那麽(me) 我們(men) 就說說什麽(me) 是事件.
事件就是一種頁麵到邏輯層的通訊方式,比如說你的操作想得到機器的反饋,這時候就用到事件了.事件可以將用戶的行為(wei) 反饋到邏輯層進行處理.
說到這兒(er) 不禁又有一個(ge) 問題,那他是怎麽(me) 用的呢? 事件可以綁定到組件上,當觸發事件,就會(hui) 執行邏輯層對應的事件處理函數,當然為(wei) 了更加方便人機交互,用戶還可以攜帶額外的信息,如id,data等.
可能有人看完剛才的一段就說了,好了,你剛才說的事件解釋的差不多了,可是你為(wei) 什麽(me) 有冒出一個(ge) 組件,這讓我這麽(me) 理解?
既然說到組件了,我們(men) 就先簡單的了解一下,在之後的組件板塊再詳說,先保證大家能看懂什麽(me) 是事件就好了.
為(wei) 什麽(me) 要有組件呢?組件是框架為(wei) 了開發者進行快速的開發而設計的.
那什麽(me) 是組件呢? 組件是視圖層的基本組成單元,在微信小程序中組件自帶一些功能與(yu) 微信風格的樣式,一個(ge) 組件通常包括開始標簽和結束標簽,屬性是用來修飾這個(ge) 組件,內(nei) 容在兩(liang) 個(ge) 標簽之內(nei) .
<tagname property="value"> Content goes here ...</tagename>
在這裏需要注意一點,組件和屬性都是小寫(xie) ,並且以"-"進行連接.
簡單的介紹一下組件,那我們(men) 繼續說事件.
事件分為(wei) 冒泡事件和非冒泡事件,冒泡事件是當一個(ge) 組件上的事件被觸發後,該事件會(hui) 向父節點傳(chuan) 遞,而非冒泡事件則不會(hui) .
現在微信小程序給出的冒泡事件僅(jin) 僅(jin) 有6個(ge) (touchstart,touchmove, touchcancel,touchend,tap, longtap),下圖是他們(men) 分別對應的觸發條件.
剩下的都屬於(yu) 非冒泡事件.
接下來我們(men) 就說說事件怎麽(me) 用?
事件是通過事件綁定來實現的.它的寫(xie) 法是以key,value的形式來寫(xie) 的.key以bind 和catch 開頭,然後跟上事件的類型. value 是一個(ge) 字符串,需要在對應的page中定義(yi) 同名的函數,不然當觸發事件的時候會(hui) 報錯.(bind 事件綁定不會(hui) 阻止冒泡事件向上冒泡,而catch 可以阻止冒泡事件向上冒泡).
說完了如何進行事件綁定了,我們(men) 再說說,當事件觸發是邏輯層的事件處理函數會(hui) 收到什麽(me) ? 事件處理函數會(hui) 收到一個(ge) 事件對象. 那麽(me) 這個(ge) 事件對象裏麵都有什麽(me) 屬性呢?? 裏麵的屬性有(type, timeStamp, target, currentTarget, touches, detail),下麵是他們(men) 的一些說明:
其他的屬性按照上麵的說明簡單了解即可,在這裏我們(men) 說一下target和currentTarget中的dataset,我們(men) 知道在組件中可以定義(yi) 數據,這些數據會(hui) 通過事件傳(chuan) 遞給 SERVICE書(shu) 寫(xie) 方式: 以data-開頭,多個(ge) 單詞由連字符-鏈接,不能有大寫(xie) (大寫(xie) 會(hui) 自動轉成小寫(xie) )如data-element-type,最終在 event.target.dataset 中會(hui) 將連字符轉成駝峰elementType。用一段代碼來說話相信大家就更清楚了.
<view data-alpha-beta="1" data-alphaBeta="2" bindtap="bindViewTap"> DataSet Test </view>Page({ bindViewTap:function(event){ event.target.dataset.alphaBeta == 1 // - 會(hui) 轉為(wei) 駝峰寫(xie) 法 event.target.dataset.alphabeta == 2 // 大寫(xie) 會(hui) 轉為(wei) 小寫(xie) } })
我不知道大家感覺怎麽(me) 樣,要是我自己剛開始看我寫(xie) 的這一大段內(nei) 容,我感覺我就該罵娘了,不是說麽(me) NO圖NO BB,下麵我就給大家上代碼,相信看完之後事件這一塊基本上就明白了.
//視圖層的事件綁定
<view id="tapTest" data-hi="MINA" bindtap="tapName"> Click me! </view>
//邏輯層的事件處理函數
Page({
tapName: function(event) {
console.log(event)
}
})
//邏輯層的事件處理函數輸出的信息
//邏輯層的事件處理函數輸出的信息
{
"type": "tap",
"timeStamp": 1252,
"target": {
"id": "tapTest",
"offsetLeft": 0,
"offsetTop": 0,
"dataset": { "hi": "MINA" }
},
"currentTarget": {
"id": "tapTest",
"offsetLeft": 0,
"offsetTop": 0,
"dataset": { "hi": "MINA" }
},
"touches": [{
"pageX": 30,
"pageY": 12,
"clientX": 30,
"clientY": 12,
"screenX": 112, "screenY": 151
}],
"detail": { "x": 30, "y": 12}}
到這兒(er) WXML的頁麵結構就說完了,接著我們(men) 簡單說說WXSS就基本說完了.
在WXSS中引入了新的 尺寸單位rpx 它規定1rpx=0.5px = 1物理像素
WXSS的樣式導入使用@import語句可以導入外聯樣式表,@import後跟需要導入的外聯樣式表的相對路徑,用;表示語句結束.剩下的內(nei) 容基本上和css相差不大,有興(xing) 趣的可以看一下官方文檔WXSS