WXML语法
在开发PC端或者移动端的页面,一般都是用的是HTML构建页面的结构,但是在微信小程序这里就不一样了,这里有一套标记语言专门给微信小程序构建页面,它就是WXML(WeiXin Markup Language),WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出小程序的页面的结构。
基本语法
<!-- index.wxml 页面结构
跟HTML标签语法的类似,有成对标签:<view></view>...,也有单标签:<input />...
wxml的有些标签跟HTML的一样
-->
<view class="test">
{{message}}
<view class="demo">该标签跟HTML的div标签作用一样</view>
<input type="text" maxlength="10" placeholder="请输入文字"/>
</view>
/** index.wxss 样式表
它的语法跟css的语法很像
**/
.test{
color: red;
}
.demo{
color: green;
}
/** index.js 逻辑
它的语法跟JavaScript的语法一样
**/
Page({
data: {
msg: 'Holle Word'
}
})
数据绑定
<!--wxml-->
<!--
变量名是大小写敏感的,也就是说 {{name}} 和 {{NAME}} 是两个不同的变量。
注: {{}} 叫做Mustache 语法。
{{}} 具有两种功能:动态渲染、逻辑运算。
{{}} 中除了变量名,还可以放置数字、字符串,并且做一些逻辑运算:算数运算、字符串拼接、三元运算
-->
<view>{{message}}</view>
// page.js
Page({
data: {
message: 'Hello MINA!'
}
})
组件属性(需要在双引号之内)
<!-- wxml -->
<view id="item-{{id}}"> </view>
/** js **/
Pages({
data:{
id:1
}
})
控制属性(需要在双引号之内)
<!-- wxml -->
<view wx:if="{{condition}}">Hello Word</view>
/** js **/
Pages({
data:{
condition:false
}
})
关键字(需要在双引号之内)
true
:boolean 类型的 true,代表真值。
false
: boolean 类型的 false,代表假值。
<!-- wxml
特别注意:不要直接写 checked="false",其计算结果是一个字符串,转成 boolean 类型后代表真值。
-->
<checkbox checked="{{true}}"> </checkbox>
运算
可以在 {{}}
内进行简单的运算,支持的有如下几种方式:
<view hidden="{{flag ? true : false}}"> Hidden </view>
算数运算
<!-- wxml -->
<view> {{a + b}} + {{c}} + d </view>
/** js **/
Pages({
data:{
a:1,
b:2,
c:3,
d:4
}
})
逻辑判断
<!-- wxml -->
<view wx:if="{{length > 5}}">test</view>
/** js **/
Pages({
data:{
length:6
}
})
字符串运算
<!-- wxml -->
<view>{{"hello " + name}}</view>
/** js **/
Pages({
data:{
name:'word'
}
})
数据路径运算
<!-- wxml
注意:由于语法问题,复制下面代码片段要把空格去掉
-->
<view>{{object.key}} {{array[0]}}</view>
<!-- 组合 -->
<view wx:for="{{[zero, 1, 2, 3, 4]}}"> {{item}} </view>
/** js **/
Pages({
data:{
object: {
key: 'Hello '
},
array: ['word'],
zero: 0
}
})
列表渲染
wx:for
在组件上使用 wx:for
控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。
默认数组的当前项的下标变量名默认为 index
,数组当前项的变量名默认为 item
<!-- wxml -->
<view wx:for="{{array}}">
{{index}}: {{item.message}}
</view>
<!--
使用 wx:for-item 可以指定数组当前元素的变量名,
使用 wx:for-index 可以指定数组当前下标的变量名:
-->
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
{{idx}}: {{itemName.message}}
</view>
<!--
`wx:key` 的值以两种形式提供
1. 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
2. 保留关键字 `this` 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字。
当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。
如不提供wx:key,会报一个warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
-->
<view wx:for="{{array}}" wx:key="key" wx:for-item="itemName">
{{itemName.message}}
</view>
/** js **/
Pages({
data:{
array: [{
message: 'foo',
}, {
message: 'bar'
}]
}
})
注意
当 wx:for
的值为字符串时,会将字符串解析成字符串数组
花括号和引号之间如果有空格,将最终被解析成为字符串
<view wx:for="array">
{{item}}
</view>
<view wx:for="{{[1,2,3]}} ">
{{item}}
</view>
条件渲染
wx:if
在框架中,使用 wx:if=""
来判断是否需要渲染该代码块:
<!-- wxml -->
<view wx:if="{{condition}}">Hello Word</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>
/** js **/
Pages({
data:{
condition:false,
length:4
}
})
wx:if
vs hidden
因为 wx:if
之中的模板也可能包含数据绑定,所以当 wx:if
的条件值切换时,框架有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。
同时 wx:if
也是惰性的,如果在初始渲染条件为 false
,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。
相比之下,hidden
就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。
一般来说,wx:if
有更高的切换消耗而 hidden
有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden
更好,如果在运行时条件不大可能改变则 wx:if
较好。
模板
WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用。
定义模板
使用 name 属性,作为模板的名字。然后在<template/>
内定义代码片段,如:
<!-- wxml
注意:由于语法问题,复制下面代码片段要把空格去掉
-->
<template name="msgItem">
<view>
<text> {{index}}: {{msg}} </text>
<text> Time: {{time}} </text>
</view>
</template>
使用模板
使用 is 属性,声明需要的使用的模板,然后将模板所需要的 data 传入,如:
<template is="msgItem" data="{{...item}}"/>
is 属性可以使用 Mustache 语法,来动态决定具体需要渲染哪个模板:
<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>
引用
WXML 提供两种文件引用方式import
和include
import
import
可以在该文件中使用目标文件定义的template
,如:
在 item.wxml 中定义了一个叫item
的template
:
<!-- test.wxml -->
<template name="item">
<text>{{text}}</text>
</template>
在 index.wxml 中引用了 test.wxml,就可以使用item
模板:
<!-- test.wxml -->
<import src="../test/test.wxml"/>
<template is="item" data="{{text: 'forbar'}}"/>
import 的作用域
import 有作用域的概念,即只会 import 目标文件中定义的 template,而不会 import 目标文件 import 的 template。
如:C import B,B import A,在C中可以使用B定义的template,在B中可以使用A定义的template,但是C不能使用A定义的template。
<!-- test.wxml
注意:由于语法问题,复制下面代码片段要把空格去掉
-->
<template name="A">
<text> A template </text>
</template>
<!-- index.wxml
注意:由于语法问题,复制下面代码片段要把空格去掉
-->
<import src="../test/test.wxml"/>
<template name="B">
<text> B template </text>
</template>
<!-- demo.wxml
注意:由于语法问题,复制下面代码片段要把空格去掉
-->
<import src="../index/index.wxml"/>
<template is="A"/> <!-- Error! Can not use tempalte when not import A. -->
<template is="B"/>
include
include
可以将目标文件除了 <template/>
<wxs/>
外的整个代码引入,相当于是拷贝到 include
位置,如:
<!-- index.wxml -->
<include src="header.wxml"/>
<view> body </view>
<include src="footer.wxml"/>
<!-- header.wxml -->
<view> header </view>
<!-- footer.wxml -->
<view> footer </view>