WXML 中的动态数据均来自对应 Page 的 data。
1.简单绑定
数据绑定使用 Mustache 语法(双大括号)将变量包起来,可以作用于:
1.1.内容
代码
WXML代码
{{ message }}
JS代码
Page({
data: {
message: '简单赋值'
}
})
效果
1.2.组件属性(需要在双引号之内)
代码
WXML代码
JS代码
Page({
data: {
id: 0
}
})
1.3.控制属性(需要在双引号之内)
代码
WXML代码
JS代码
Page({
data: {
condition: true
}
})
1.4.关键字(需要在双引号之内)
true:boolean 类型的 true,代表真值。
false: boolean 类型的 false,代表假值。
代码
WXML代码
效果
特别注意:不要直接写 checked="false",其计算结果是一个字符串,转成 boolean 类型后代表真值。
2.运算
可以在 {{}}
内进行简单的运算,支持的有如下几种方式:
2.1.三元运算
代码
WXML代码
Hidden
JS代码
Page({
data: {
flag:true,
}
})
效果
即:隐藏
JS代码
Page({
data: {
flag:false,
}
})
效果
即:显示
2.2.算数运算
代码
WXML代码
{{a + b}} + {{c}} + d
JS代码
Page({
data: {
a: 1,
b: 2,
c: 3
}
})
效果
2.3.逻辑判断
代码
WXML代码
2.4.字符串运算
代码
WXML代码
{{"加油" + name}}
JS代码
Page({
data: {
name: '鲁能泰山'
}
})
效果
2.5.数据路径运算
代码
WXML代码
{{object.key}}{{array[0]}}
JS代码
Page({
data: {
object: {
key: '你好'
},
array: ['鲁能泰山队']
}
})
效果
3.组合
也可以在 Mustache 内直接进行组合,构成新的对象或者数组。
3.1.数组
代码
WXML代码
{{item}}
JS代码
Page({
data: {
zero: 0
}
})
效果
1.wx:for
在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。
默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item。
代码
WXML代码
{{index}}: {{item.message}}
JS代码
Page({
data: {
array: [{
message: '2018',
}, {
message: '2017'
},
{
message: '2016'
},
{
message: '2015'
}, {
message: '2014'
},
{
message: '2013'
},
{
message: '2012'
},
{
message: '2011'
},
{
message: '2010'
},
{
message: '2009'
},
{
message: '2008'
},
{
message: '2007'
},
{
message: '2006'
},
{
message: '2005'
},
{
message: '2004'
}
]
}
})
效果
使用 wx:for-item 可以指定数组当前元素的变量名。
使用 wx:for-index 可以指定数组当前下标的变量名。
WXML代码
{{idx}}: {{itemName.message}}
JS代码
Page({
data: {
array: [{
message: '2018',
}, {
message: '2017'
},
{
message: '2016'
},
{
message: '2015'
}, {
message: '2014'
},
{
message: '2013'
},
{
message: '2012'
},
{
message: '2011'
},
{
message: '2010'
},
{
message: '2009'
},
{
message: '2008'
},
{
message: '2007'
},
{
message: '2006'
},
{
message: '2005'
},
{
message: '2004'
}
]
}
})
效果
wx:for 也可以嵌套,下边是一个九九乘法表
WXML代码
{{i}} * {{j}} = {{i * j}}
效果
2.block wx:for
类似 block wx:if,也可以将 wx:for 用在
WXML代码
{{index}}:
{{item}}
效果
3.wx:key
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 中的输入内容,
wx:key 的值以两种形式提供
字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字,如:
当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。
如不提供 wx:key,会报一个 warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
代码
WXML代码
{{item.id}}
{{item}}
JS代码
Page({
data: {
objectArray: [
{ id: 5, unique: 'unique_5' },
{ id: 4, unique: 'unique_4' },
{ id: 3, unique: 'unique_3' },
{ id: 2, unique: 'unique_2' },
{ id: 1, unique: 'unique_1' },
{ id: 0, unique: 'unique_0' },
],
numberArray: [1, 2, 3, 4]
},
switch: function (e) {
const length = this.data.objectArray.length
for (let i = 0; i < length; ++i) {
const x = Math.floor(Math.random() * length)
const y = Math.floor(Math.random() * length)
const temp = this.data.objectArray[x]
this.data.objectArray[x] = this.data.objectArray[y]
this.data.objectArray[y] = temp
}
this.setData({
objectArray: this.data.objectArray
})
},
addToFront: function (e) {
const length = this.data.objectArray.length
this.data.objectArray = [{ id: length, unique: 'unique_' + length }].concat(this.data.objectArray)
this.setData({
objectArray: this.data.objectArray
})
},
addNumberToFront: function (e) {
this.data.numberArray = [this.data.numberArray.length + 1].concat(this.data.numberArray)
this.setData({
numberArray: this.data.numberArray
})
}
})
效果
注意:
当 wx:for 的值为字符串时,会将字符串解析成字符串数组
{{item}}
等同于
{{item}}
注意: 花括号和引号之间如果有空格,将最终被解析成为字符串
{{item}}
等同于
{{item}}
1.wx:if
1.1.在框架中,使用 wx:if="{{condition}}" 来判断是否需要渲染要显示的内容。
代码
WXML代码
是否渲染内容
JS代码
/**
* 页面的初始数据
*/
data: {
condition:true,
},
效果
JS代码
/**
* 页面的初始数据
*/
data: {
condition:false,
},
效果
1.2.也可以用 wx:elif 和 wx:else 来添加一个 else 块
代码
WXML代码
1
2
3
JS代码
/**
* 页面的初始数据
*/
data: {
length:0,
},
效果
JS代码
/**
* 页面的初始数据
*/
data: {
length:3,
},
效果
JS代码
/**
* 页面的初始数据
*/
data: {
length:7,
},
效果
2.block wx:if
因为 wx:if 是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个
代码
WXML代码
view1
view2
JS代码
/**
* 页面的初始数据
*/
data: {
condition:false,
},
效果
JS代码
/**
* 页面的初始数据
*/
data: {
condition:true,
},
效果
注意:
3.wx:if 和 hidden
因为 wx:if 之中的模板也可能包含数据绑定,所以当 wx:if 的条件值切换时,框架有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。
同时 wx:if 也是惰性的,如果在初始渲染条件为 false,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。
相比之下,hidden 就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。
一般来说,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好。
WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用。
1.定义模板
使用 name 属性,作为模板的名字。然后在内定义代码片段。
{{index}}: {{msg}}
Time: {{time}}
2.使用模板
使用 is 属性,声明需要的使用的模板,然后将模板所需要的 data 传入。
3.JS代码使用
Page({
data: {
item: {
index: 0,
msg: 'this is a template',
time: '2016-09-15'
}
}
})
4.效果
5.is 属性可以使用 Mustache 语法,来动态决定具体需要渲染哪个模板
6.WXML代
显示odd
显示even
7.效果
8.模板的作用域
模板拥有自己的作用域,只能使用 data 传入的数据以及模版定义文件中定义的
1.什么是事件
1.1.事件是视图层到逻辑层的通讯方式。
1.2.事件可以将用户的行为反馈到逻辑层进行处理。
1.3.事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
1.4.事件对象可以携带额外信息,如 id, dataset, touches。
2.事件的使用方式
2.1.在组件中绑定一个事件处理函数。
如bindtap,当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数。
代码
WXML代码
Click me!
JS代码
Page({
tapName: function () {
console.log('点击了我!')
}
})
效果
3.事件详解
3.1.事件分类
事件分为冒泡事件和非冒泡事件:
冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。
WXML的冒泡事件列表
注:除上表之外的其他组件自定义事件如无特殊声明都是非冒泡事件,如的submit事件,的input事件,
3.2.事件绑定和冒泡
事件绑定的写法同组件的属性,以 key、value 的形式。
key 以bind或catch开头,然后跟上事件的类型,如bindtap、catchtouchstart。自基础库版本 1.5.0 起,在非原生组件中,bind和catch后可以紧跟一个冒号,其含义不变,如bind:tap、catch:touchstart。
value 是一个字符串,需要在对应的 Page 中定义同名的函数。不然当触发事件的时候会报错。
bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡。
如在下边这个例子中,点击 inner view 会先后调用handleTap3和handleTap2(因为tap事件会冒泡到 middle view,而 middle view 阻止了 tap 事件冒泡,不再向父节点传递),点击 middle view 会触发handleTap2,点击 outer view 会触发handleTap1。
代码
outer view
middle view
inner view
3.3.事件的捕获阶段
自基础库版本 1.5.0 起,触摸类事件支持捕获阶段。捕获阶段位于冒泡阶段之前,且在捕获阶段中,事件到达节点的顺序与冒泡阶段恰好相反。需要在捕获阶段监听事件时,可以采用capture-bind、capture-catch关键字,后者将中断捕获阶段和取消冒泡阶段。
在下面的代码中,点击 inner view 会先后调用handleTap2、handleTap4、handleTap3、handleTap1。
代码
outer view
inner view
如果将上面代码中的第一个capture-bind改为capture-catch,将只触发handleTap2。
代码
outer view
inner view
3.4.事件对象
如无特殊说明,当组件触发事件时,逻辑层绑定该事件的处理函数会收到一个事件对象。
3.4.1.BaseEvent 基础事件对象属性列表
3.4.2.CustomEvent 自定义事件对象属性列表(继承 BaseEvent)
3.4.3.TouchEvent 触摸事件对象属性列表(继承 BaseEvent)
特殊事件: 中的触摸事件不可冒泡,所以没有 currentTarget。
3.4.4.type
代表事件的类型。
3.4.5.timeStamp
页面打开到触发事件所经过的毫秒数。
3.4.6.target
触发事件的源组件。
3.4.7.currentTarget
事件绑定的当前组件。
说明: target 和 currentTarget 可以参考上例中,点击 inner view 时,handleTap3 收到的事件对象 target 和 currentTarget 都是 inner,而 handleTap2 收到的事件对象 target 就是 inner,currentTarget 就是 middle。
3.4.8.dataset
在组件中可以定义数据,这些数据将会通过事件传递给 SERVICE。 书写方式: 以data-开头,多个单词由连字符-链接,不能有大写(大写会自动转成小写)如data-element-type,最终在 event.currentTarget.dataset 中会将连字符转成驼峰elementType。
代码
WXML
DataSet Test
JS
Page({
bindViewTap: function (event) {
event.currentTarget.dataset.alphaBeta === 1 // - 会转为驼峰写法
event.currentTarget.dataset.alphabeta === 2 // 大写会转为小写
}
})
3.4.9.touches
touches 是一个数组,每个元素为一个 Touch 对象(canvas 触摸事件中携带的 touches 是 CanvasTouch 数组)。 表示当前停留在屏幕上的触摸点。
3.4.10.Touch 对象
3.4.11.CanvasTouch 对象
3.4.12.changedTouches
changedTouches 数据格式同 touches。 表示有变化的触摸点,如从无变有(touchstart),位置变化(touchmove),从有变无(touchend、touchcancel)。
3.4.13.detail
自定义事件所携带的数据,如表单组件的提交事件会携带用户的输入,媒体的错误事件会携带错误信息,详见组件定义中各个事件的定义。
点击事件的detail 带有的 x, y 同 pageX, pageY 代表距离文档左上角的距离。
WXML 提供两种文件引用方式import和include。
1.import
import可以在该文件中使用目标文件定义的template,如:在 item.wxml 中定义了一个叫item的template。
{{text}}
在 index.wxml 中引用了 item.wxml,就可以使用item模板
2.import 的作用域
import 有作用域的概念,即只会 import 目标文件中定义的 template,而不会 import 目标文件 import 的 template。
如:C import B,B import A,在C中可以使用B定义的template,在B中可以使用A定义的template,但是C不能使用A定义的template。
A template
B template
2.include
include 可以将目标文件除了
body
header
footer