微信小程序開發進階 - 數據綁定與模塊化
微信小程序的 UI 層如何與控制層交互, 以及怎么樣響應用戶操作事件, 這次咱們來聊聊。
WXML
微信小程序使用 WXML 文件作為 UI 視圖。 WXML 其實就是 WeiXin Markup Language 的縮寫。 是一種類似 XML 語法結構的 UI 定義方式。
它可以進行數據綁定, 顯示 Page 中相應的屬性:
<!--
<view> {{message}} </view>
-->
兩對括號中的 message 對應 Page 中 data 屬性中的 message:
Page({
data: {
message: 'Hello World'
}
})
當然, 我們還可以進行循環顯示, 這個語法可能會和大家平時使用過的模板語法不太相同:
<!--
<view wx:for="{{array}}"> {{item}} </view>
-->
wx:for 是微信定義的一個特殊屬性, 其實相當于一個 for 循環, 重復顯示 View 空間, 然后將數組中的每一個元素都遍歷一遍, 下面是 array 在 Page 中的定義:
Page({
data: {
array: ["Swift", "Objctive-C", "Javascript"]
}
})
上面 WXML 例子中的 代表我們 data 中的 array 數組, 而 表示的就是數組遍歷中的每一個元素, 編譯運行后的界面顯示如下:
除了 wx:for 這種循環遍歷語法之外, 微信還提供了另外一種, wx:if, 大家從名稱中應該就可以想到, 它是一個條件判斷, 只有當條件判斷成立, 才會顯示這個 View。 除了 wx:if 之外, 還提供了了 wx:elif, wx:else
<!--
<view wx:if="{{false}}" >Hello Title</view>
<view wx:elif="{{false}}" >Hello World</view>
<view wx:else >Hello Wechat</view>
-->
注意這三個屬性的用法, wx:if 和 wx:elif 這兩個屬性后面需要跟隨一個布爾表達式用于判斷, 而 wx:else 后面不需要跟隨任何表達式。 這三個屬性的邏輯和我們平時開發中的 if else 判斷邏輯完全一樣,也比較好理解。
關于 wx:else 微信官方的示例中是給他指定了表達式屬性的。 但我在真實環境上測試了一下, wx:else 無論是否指定后面的屬性值,最終的輸出結果都是一樣的, 所以這可能是官方示例的一個筆誤。 按照 if 表達式正常的邏輯來看,應該不需要給它再設屬性了。 大家可以留意一下。
模板
說完了循環和條件判斷語法, WXML 還支持模板定義, 比如這樣:
<!--
<template name="hello" >
<view>
Hello, {{name}}
</view>
</template>
<template is="hello" data="{{...swift}}" ></template>
<template is="hello" data="{{...objc}}" ></template>
-->
簡單解釋一下, 第一個 template 標簽是模板定義, name 屬性定義了它的名字,在兩個標簽之間是它的內部結構。 然后緊接著的后兩個 template 標簽是模板的引用, is 屬性代表要引用哪個模板。 我們這里填入的都是 hello, 也就是我們最開始定義的這個模板結構。 然后就是 data 屬性,通過它傳入模板需要的相關數據。 先來開一下 swift 和 objc 這兩個數據的定義:
Page({
data: {
swift: { name: "Swift"},
objc: { name: "Objective-C"}
}
})
swift 和 objc 都是兩個 JSON 對象, 都包含一個 name 屬性。 大家注意看我們前面模板引用 data 屬性的方式:
<!-- <template is="hello" data="{{...swift}}" ></template> -->
這里我們在一對大括號中的變量名前面還寫了三個點 —— …
… 其實是一個操作符, 用于將 swift 變量內部的值 “展開”, 這么說可能不太好理解, 咱們還回到模板的定義中:
<!--
<template name="hello" >
<view>
Hello, {{name}}
</view>
</template>
-->
我們看到, template 內部使用 來引用我們傳入對象的屬性。 這就需要我們 “展開” 傳入的對象, 才能讓模板找到對應 key 的值。 簡單來說, 如果我們不適用 … 這個操作符,而是直接像這樣傳入對象:
<!--
<template is="hello" data="{{swift}}" ></template>
-->
如果這樣運行程序的話, 模板是不能正確讀取到 name 屬性的。
模板的引用
當然, 我們可以不用把模板的定義和引用它的代碼寫到一起, 我們可以把模板的定義單獨寫在一個 WXML 文件中, 然后在另外一個文件中使用 import 來引入它。 這也是一個結構良好的項目的通常做法。 比如我們剛才的模板存放到 hello.wxml 中, 我們就可以這樣引用它:
<!--
<import src="hello.wxml" />
<template is="hello" data="{{...swift}}" ></template>
<template is="hello" data="{{...objc}}" ></template>
-->
這樣我們可以比較好的進行模塊劃分。 當然, 除了 import 之外, 微信還給我們提供了另外一種引用方式, include。 簡而言之, 他們之間的區別是這樣, import 只能引入目標文件中的 template 定義, 不會引入具體的 UI 內容。 而 include 正好相反, 它只會引入目標文件中的內容,不會引入 template 定義, 比如我們有一個文件,叫做 header.wxml:
<!--
<view>Header Title</view>
-->
然后我們在 index.wxml 中這樣引用:
<!--
<include src="header.wxml" />
<view>Hello world!</view>
-->
這樣就會引入 header.wxml 中定義的內容了, 最后的輸出結果就是他們兩個文件中所有 UI 組件的整合了。 這就是 import 和 include 的區別了。
來自:http://www.swiftcafe.io/2016/09/28/wx-app3/