页面结构文件WXML
WXML(WeiXin Markup Language) 是框架设计的一套标记语言,用于渲染界面,WXML的渲染原理和React Native思路一致,通过一套标记语言,在不同平台被解析为不同端的渲染文件。
-
WXML语言最终会转译为宿主端对应的语言,所以WXML中所使用的标签一定是小程序定义的标签,不能使用自定义标签,这样才能保证页面能被正确转译。
-
使用微信开发者工具开发时,在WXML中编写一些HTML标签或自定义标签仍然会被正常解析,这会给开发者造成一种小程序能直接支持HTM标签的误解。这是因为微信开发者工具内核是浏览器内核,同时小程序框架并没对WXML中的标签和wxss中的内容进行强验证,所以HTML和CS能直接被解析,但这种不合法的wxML在手机端微信中是不能正常显示的。开发过程中我们一定要拿真机进行测试,保证程序能正常运行。
-
WXML具有数据绑定、列表渲染、亲件渲染、模板、事件等能力。
数据绑定 data
-
小程序中页面渲染时,框架会将WXML文件同对应Page的data进行绑定,在页面中我们可以直接使用data中的属性。小程序的数据绑定使用 Mustache语法(双大括号)将变量或简单的运算规则包起来,主要有以下几种渲染方式。
-
使用{{}}可以获取data中的值
-
简单绑定
简单绑定是指我们使用双大括号将变量包起来,在模板中直接作为字符串输出使用,可作用于内容、组件属性、控制属性、关键字等输出,期中关键字输出是指将JavaScript中的关键字按其真值输出。
<!-- 作为内容 --> <view>{{content}}</view> <!-- 作为组件属性 --> {{border}} <!-- 作为控制属性 --> <view wx: if="{{showContent}}">作为属性渲染</view>
Page({ data:{ border:'solid lpx #000', id: 1, content: '内容', showContent: false } });
运算
在{{}}内可以做一些简单的运算,支持的运算有三元运算、算数运算、逻辑判断、字符串运算,这些运算均符合Javascript运算规则。
<!-- 三元表达式 -->
<view>{{showContent ? '显示文本': '不显示文本'}}</view>
<!-- 算数运算符 -->
<view>{{num1 + num2}} + 1 + {{num3}} = ?</view>
<!-- 字符串运算 -->
<view>{{"name:" + name}}</view>
<!-- 逻辑判断 -->
<view>{{num3 > 0}}</view>
<!-- 数据路径运算 -->
<view>{{myObject.age}}:{{myArray[1]}}</view>
Page({
data:{
showContent: false,
num1: 1,
num2: 2,
num3: 3,
name: 'weixin',
myObject:{
age: 12
},
myArray: ['arr1', 'arr2']
}
});
效果展示
组合
data中的数据可以在模板再次组合成新的数据结构,这种组合常常在数组或对象中使用。
<view>{{[myValue, 2, 3, 'stringtype']}}</view>
Page({
data: {
myValue: 0
}
});
最终页面组合成的对象为[0, 2, 3, ‘stringtype’]。
对象组合有3种组合方式,以数据注入模板为例(模板的使用在下方有介绍,这里只需初步了解)。
-
直接将数据作为value值进行组合
<template name="testTemp"> <view>name = {{name}}</view> <view>age = {{age}}</view> </template> <template is="testTemp" data="{{name:myValue1, age:myValue2}}"></template>
// 运算 Page({ data:{ myValue1: 'value1', myValue2: 'value2' } });
效果展示
-
通过"…"将第一个对象展开,把key-value值拷贝到新的结构中
<template name="testTemp"> <view>key1 = {{key1}}</view> <view>key2 = {{key2}}</view> <view>key3 = {{key3}}</view> <view>key4 = {{key4}}</view> <view>key5 = {{key5}}</view> <view>key6 = {{key6}}</view> </template> <template is = "testTemp" data = "{{...myObject1, key5: 5, ...myObject2, key6: 6}}"></template>
Page({ data:{ myObject1:{ key1: 1, key2: 2 }, myObject2:{ key3: 3, key4: 4 } } });
效果展示
-
如果对象key和value相同,可以只写key值
<template name="testTemp"> <view>key1:{{key1}}</view> <view>key2:{{key2}}</view> </template> <template is = "testTemp" data = "{{key1, key2}}"></template>
Page({ data:{ key1: 1, key2: 2 } });
这种写法最后组合成的结果是key1: 1, key2: 2
注意:当一个组合中有相同的属性名时,后面的属性将会覆盖前面的属性。
条件语句
-
wx: if
除了简单的数据绑定,我们常常会使用逻辑分支,这时候可以使用wx: if"{{判断条件}}"来进行条件渲染,当条件成立时渲染该代码块
<view wx:if="{{showContent}}">内容</view>
Page({ data:{ showContent: false } });
示例中view代码块将不会渲染,只有当showContent的值为true时才渲染。和普通的编程语言一样,WXML也支持wx: elif 和wx: else
-
wx: elif、wx: else
<view wx:if="{{false}}">1</view> <view wx:elif="{{false}}">2</view> <view wx:else>3</view>
示例中页面只渲染最后一个。wx: elif、wx: else必须和wx: if配合使用,否则会导致页面解析出错。
-
block wx:if
wx: if是一个控制属性,可以添置在任何组件标签上,但如果我们需要包装多个组件,又不想影响布局,这时就需要使用
<block/>
标签将需要包装的组件放置在里面,通过wx: if作判断。<block/>
不是一个组件,仅仅是一个包装元素。<block wx:if = "{{true}}"> <view>view组件</view> <image/> </block>
-
wx: if 与 hidden
除了wx:if 组件,也可以通过 hidden属性控制组件是否显示,开发者难免有疑问,这两种方式该怎样取舍,这里我们整理了两种方式的区别:
- wx:if :控制是否渲染条件块内的模板,当其条件值切换时,会触发局部渲染以确保条件块在切换时销毁或重新渲染。wx:if是惰性的,如果在初始渲染条件为 false时,框架将什么也不做,在条件第一次为真时才局部渲染。
- hidden :控制组件是否显示,组件始终会被渲染,只是简单控制显示与隐藏,并不会触发重新渲染和销毁。
综合两个渲染流程可以看出,由于wx:if会触发框架局部渲染过程,在频繁切换状态的场景中,会产生更大的消耗,这时尽量使用 hidden;在运行时条件变动不大的场景中我们使用wx:if,这样能保证页面有更高效的渲染,而不用把所有组件都渲染出来。
遍历循环
-
wx: for
组件的wx: for控制属性用于遍历数组,重复渲染该组件,遍历过程中当前项的下标变量名默认为index,数组当前变量名默认为item
<view wx:for="{{myArray}}"> {{index}}:{{item}} </view>
Page({ data:{ myArray: ['value1', 'value2'] } });
通过遍历myArray,页面渲染了两个
<view/>
结果如下
-
wx: for-index 和 wx:for-item
index、item变量名可以通过wx: for-index、wx: for-item属性修改
<view wx:for="{{myArray}}" wx:for-index="myIndex" wx:for-item="myItem"> {{myIndex}}:{{myItem.name}} </view>
Page({ data:{ myArray:[ {name:'value1'}, {name:'value2'} ] } });
效果和上例一致
-
wx:for嵌套使用
普通遍历中我们没必要修改index、item变量名,而在使用wx:for嵌套时,就有必要设置变量名,避免变量名冲突。(当然也可以不用重命名)
<view wx:for="{{myArray}}" wx:for-index="myIndex" wx:for-item="myItem"> <block wx:for="{{myItem}}" wx:for-index="subIndex" wx:for-item="subItem"> {{subItem}} </block> <!-- 简写,效果相同 --> <!-- <view wx:for="{{myArray}}" > <block wx:for="{{item}}"> {{item}} </block> </view> --> </view>
Page({ data:{ myArray:[ [1, 2, 3], [4, 5, 6], [7, 8, 9] ] } });
输出结果:在本示例中,我们使用了
<block/>
标签,以渲染一个包含多个节点的结构块。
同步笔记在微信公众号持续更新:小程笔记