框架的視圖層由 WXML 與 WXSS 編寫寂殉,由組件來進行展示囚巴。
將邏輯層的數(shù)據(jù)反應(yīng)成視圖,同時將視圖層的事件發(fā)送給邏輯層友扰。
WXML(WeiXin Markup language) 用于描述頁面的結(jié)構(gòu)彤叉。
WXS(WeiXin Script) 是小程序的一套腳本語言,結(jié)合 WXML村怪,可以構(gòu)建出頁面的結(jié)構(gòu)秽浇。
WXSS(WeiXin Style Sheet) 用于描述頁面的樣式。
組件(Component)是視圖的基本組成單元甚负。
2.4.1 WXML
WXML(WeiXin Markup Language)是框架設(shè)計的一套標簽語言柬焕,結(jié)合基礎(chǔ)組件审残、事件系統(tǒng),可以構(gòu)建出頁面的結(jié)構(gòu)击喂。
WXML 具有以下能力:
- 數(shù)據(jù)綁定
- 列表渲染
- 條件渲染
- 模板
- 事件
2.4.1.1 數(shù)據(jù)綁定
WXML 中的動態(tài)數(shù)據(jù)均來自對應(yīng) Page 的 data维苔。
2.4.1.1.1 簡單綁定
數(shù)據(jù)綁定使用 Mustache 語法(雙大括號)將變量包起來,可以作用于:
1懂昂、內(nèi)容
<view> {{ message }} </view>
Page({
data: {
message: 'Hello MINA!'
}
})
2介时、組件屬性(需要在雙引號之內(nèi))
<view id="item-{{id}}"> </view>
Page({
data: {
id: 0
}
})
3、控制屬性(需要在雙引號之內(nèi))
<view wx:if="{{condition}}"> </view>
Page({
data: {
condition: true
}
})
4凌彬、關(guān)鍵字(需要在雙引號之內(nèi))
true
:boolean 類型的 true沸柔,代表真值。
false
: boolean 類型的 false铲敛,代表假值褐澎。
<checkbox checked="{{false}}"> </checkbox>
特別注意:不要直接寫 checked="false",其計算結(jié)果是一個字符串伐蒋,轉(zhuǎn)成 boolean 類型后代表真值工三。
2.4.1.1.2 運算
可以在 {{ }}
內(nèi)進行簡單的運算,支持的有如下幾種方式:
1先鱼、三元運算
<view hidden="{{flag ? true : false}}"> Hidden </view>
2俭正、算數(shù)運算
<view> {{a + b}} + {{c}} + d </view>
Page({
data: {
a: 1,
b: 2,
c: 3
}
})
3、邏輯判斷
<view wx:if="{{length > 5}}"> </view>
4焙畔、字符串運算
<view>{{"hello" + name}}</view>
Page({
data:{
name: 'MINA'
}
})
5掸读、數(shù)據(jù)路徑運算
<view>{{object.key}} {{array[0]}}</view>
Page({
data: {
object: {
key: 'Hello '
},
array: ['MINA']
}
})
2.4.1.1.3 組合
也可以在 Mustache 內(nèi)直接進行組合,構(gòu)成新的對象或者數(shù)組宏多。
1儿惫、數(shù)組
<view wx:for="{{[zero, 1, 2, 3, 4]}}"> {{item}} </view>
Page({
data: {
zero: 0
}
})
最終組合成數(shù)組[0, 1, 2, 3, 4]。
2伸但、對象
<template is="objectCombine" data="{{for: a, bar: b}}"></template>
Page({
data: {
a: 1,
b: 2
}
})
最終組合成的對象是 {for: 1, bar: 2}
注意: 花括號和引號之間如果有空格肾请,將最終被解析成為字符串
<view wx:for="{{[1,2,3]}} ">
{{item}}
</view>
等同于
<view wx:for="{{[1,2,3] + ' '}}">
{{item}}
</view>
2.4.1.2 列表渲染
1、wx:for
在組件上使用 wx:for 控制屬性綁定一個數(shù)組更胖,即可使用數(shù)組中各項的數(shù)據(jù)重復(fù)渲染該組件筐喳。
默認數(shù)組的當前項的下標變量名默認為 index,數(shù)組當前項的變量名默認為 item
<view wx:for="{{array}}">
{{index}}: {{item.message}}
</view>
Page({
data: {
array: [{
message: 'foo',
}, {
message: 'bar'
}]
}
})
2函喉、block wx:for
類似 block wx:if,也可以將 wx:for 用在<block/>標簽上荣月,以渲染一個包含多節(jié)點的結(jié)構(gòu)塊管呵。例如:
<block wx:for="{{[1, 2, 3]}}">
<view> {{index}}: </view>
<view> {{item}} </view>
</block>
3、wx:key
如果列表中項目的位置會動態(tài)改變或者有新的項目添加到列表中哺窄,并且希望列表中的項目保持自己的特征和狀態(tài)(如 <input/>
中的輸入內(nèi)容捐下,<switch/>
的選中狀態(tài))账锹,需要使用 wx:key
來指定列表中項目的唯一的標識符。
2.4.1.3 條件渲染
1坷襟、wx:if
在框架中奸柬,使用 wx:if="{{condition}}" 來判斷是否需要渲染該代碼塊:
<view wx:if="{{condition}}"> True </view>
也可以用 wx:elif 和 wx:else 來添加一個 else 塊:
<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>
2、block wx:if
因為 wx:if 是一個控制屬性婴程,需要將它添加到一個標簽上廓奕。如果要一次性判斷多個組件標簽,可以使用一個 <block/> 標簽將多個組件包裝起來档叔,并在上邊使用 wx:if 控制屬性桌粉。
<block wx:if="{{true}}">
<view> view1 </view>
<view> view2 </view>
</block>
注意: <block/>
并不是一個組件,它僅僅是一個包裝元素衙四,不會在頁面中做任何渲染铃肯,只接受控制屬性。
3传蹈、wx:if vs hidden
因為 wx:if
之中的模板也可能包含數(shù)據(jù)綁定押逼,所有當 wx:if
的條件值切換時,框架有一個局部渲染的過程惦界,因為它會確保條件塊在切換時銷毀或重新渲染挑格。
同時 wx:if
也是惰性的,如果在初始渲染條件為 false表锻,框架什么也不做恕齐,在條件第一次變成真的時候才開始局部渲染。
相比之下瞬逊,hidden
就簡單的多显歧,組件始終會被渲染,只是簡單的控制顯示與隱藏确镊。
一般來說士骤,wx:if
有更高的切換消耗而 hidden
有更高的初始渲染消耗。因此蕾域,如果需要頻繁切換的情景下拷肌,用 hidden
更好,如果在運行時條件不大可能改變則 wx:if
較好旨巷。
2.4.1.4 模板
WXML提供模板(template)巨缘,可以在模板中定義代碼片段,然后在不同的地方調(diào)用采呐。
1若锁、定義模板
使用 name 屬性,作為模板的名字斧吐。然后在<template/>內(nèi)定義代碼片段又固,如:
<!--
index: int
msg: string
time: string
-->
<template name="msgItem">
<view>
<text> {{index}}: {{msg}} </text>
<text> Time: {{time}} </text>
</view>
</template>
2仲器、使用模板
使用 is 屬性,聲明需要的使用的模板仰冠,然后將模板所需要的 data 傳入乏冀,如:
<template is="msgItem" data="{{...item}}"/>
Page({
data: {
item: {
index: 0,
msg: 'this is a template',
time: '2016-09-15'
}
}
})
is 屬性可以使用 Mustache 語法,來動態(tài)決定具體需要渲染哪個模板:
<template name="odd">
<view> odd </view>
</template>
<template name="even">
<view> even </view>
</template>
<block wx:for="{{[1, 2, 3, 4, 5]}}">
<template is="{{item % 2 == 0 ? 'even' : 'odd'}}"/>
</block>
3洋只、模板的作用域
模板擁有自己的作用域辆沦,只能使用 data 傳入的數(shù)據(jù)以及模板定義文件中定義的 <wxs />
模塊。
2.4.1.5 事件
2.4.1.5.1 什么是事件
- 事件是視圖層到邏輯層的通訊方式木张。
- 事件可以將用戶的行為反饋到邏輯層進行處理众辨。
- 事件可以綁定在組件上,當達到觸發(fā)事件舷礼,就會執(zhí)行邏輯層中對應(yīng)的事件處理函數(shù)鹃彻。
- 事件對象可以攜帶額外信息,如 id, dataset, touches妻献。
2.4.1.5.2 事件的使用方式
1蛛株、在組件中綁定一個事件處理函數(shù)
如 bindtap
,當用戶點擊該組件的時候會在該頁面對應(yīng)的Page中找到相應(yīng)的事件處理函數(shù)育拨。
<view id="tapTest" data-hi="WeChat" bindtap="tapName"> Click me! </view>
2谨履、在相應(yīng)的Page 定義中寫上相應(yīng)的事件處理函數(shù),參數(shù)是event熬丧。
Page({
tapName: function(event) {
console.log(event)
}
})
3笋粟、可以看到log 出來的信息。
2.4.1.5.3 事件詳解
1析蝴、事件分類
事件分為冒泡事件和非冒泡事件:
- 冒泡事件:當一個組件上的事件被觸發(fā)后害捕,該事件會向父節(jié)點傳遞。
- 非冒泡事件:當一個組件上的事件被觸發(fā)后闷畸,該事件不會向父節(jié)點傳遞尝盼。
2、事件綁定和冒泡
事件綁定的寫法同組件的屬性佑菩,以 key盾沫、value 的形式。
key 以bind或catch開頭殿漠,然后跟上事件的類型赴精,如bindtap、catchtouchstart绞幌。自基礎(chǔ)庫版本 1.5.0起蕾哟,bind和catch后可以緊跟一個冒號,其含義不變,如bind:tap渐苏、、catch:touchstart菇夸。
value 是一個字符串琼富,需要在對應(yīng)的 Page 中定義同名的函數(shù)。不然當觸發(fā)事件的時候會報錯庄新。
bind事件綁定不會阻止冒泡事件向上冒泡鞠眉,catch事件綁定可以阻止冒泡事件向上冒泡。
3择诈、事件的捕獲階段
自基礎(chǔ)庫版本 1.5.0 起械蹋,觸摸類事件支持捕獲階段。捕獲階段位于冒泡階段之前羞芍,且在捕獲階段中哗戈,事件到達節(jié)點的順序與冒泡階段恰好相反。需要在捕獲階段監(jiān)聽事件時荷科,可以采用capture-bind唯咬、capture-catch關(guān)鍵字,后者將中斷捕獲階段和取消冒泡階段畏浆。
4胆胰、事件對象
如無特殊說明,當組件觸發(fā)事件時刻获,邏輯層綁定該事件的處理函數(shù)會收到一個事件對象蜀涨。
2.4.1.6 引用
WXML 提供兩種文件引用方式 import
和 include
。
1蝎毡、import
import
可以在該文件中使用目標文件定義的 template
厚柳,如:
在 item.wxml 中定義了一個叫 item
的 template
:
<!-- item.wxml -->
<template name="item">
<text>{{text}}</text>
</template>
在 index.wxml 中引用了 item.wxml,就可以使用item模板:
<import src="item.wxml"/>
<template is="item" data="{{text: 'forbar'}}"/>
2顶掉、import 的作用域
import 有作用域的概念草娜,即只會 import 目標文件中定義的 template,而不會 import 目標文件 import 的 template痒筒。
3宰闰、include
include
可以將目標文件除了 <template/>
<wxs/>
外的整個代碼引入,相當于是拷貝到 include
位置簿透。
參考資料:https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/