视图层内容
小程序的视图层包括几个方面的内容:WXML(WeiXin Markup language) 、WXSS(WeiXin Style Sheet) 、WXS(WeiXin Script) 、组件(Component)。
- WXML:用于描述页面的结构。
- WXSS:用于描述页面的样式。
- WXS:是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。
- 组件:是视图的基本组成单元。
WXML
WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。
WXML的功能有以下几个方面:
数据绑定:WXML 中的动态数据均来自对应 Page 的 data。
- 简单绑定:数据绑定使用 Mustache 语法(双大括号)将变量包起来,可以作用于:
- 内容:
<view> {{ message }} </view>
- 组件属性(需要在双引号之内):
<view id="item-{{id}}"> </view>
- 控制属性(需要在双引号之内):
<view wx:if="{{condition}}"> </view>
- 关键字(需要在双引号之内):
<checkbox checked="{{false}}"> </checkbox>
- 运算:可以在 {{}} 内进行简单的运算,支持的有如下几种方式:
- 三元运算:
<view hidden="{{flag ? true : false}}"> Hidden </view>
- 算数运算:
<view> {{a + b}} + {{c}} + d </view>
- 逻辑判断:
<view wx:if="{{length > 5}}"> </view>
- 字符串运算:
<view>{{"hello" + name}}</view>
- 数据路径运算:
<view>{{object.key}} {{array[0]}}</view>
- 组合:可以在 Mustache 内直接进行组合,构成新的对象或者数组。
- 数组:
<view wx:for="{{[zero, 1, 2, 3, 4]}}"> {{item}} </view>
- 对象:
<template is="objectCombine" data="{{for: a, bar: b}}"></template>
js中:Page({ data: { a: 1, b: 2 } })
最后组合成对象:{for: 1, bar: 2}
也可以用扩展运算符…将一个对象展开
<template is="objectCombine" data="{{...obj1, ...obj2, e: 5}}"></template>
js中:Page({ data: { obj1: { a: 1, b: 2 }, obj2: { c: 3, d: 4 } } })
最终组合成对象:{a: 1, b: 2, c: 3, d: 4, e: 5}
如果对象的 key 和 value 相同,也可以间接地表达:<template is="objectCombine" data="{{foo, bar}}"></template>
注意:1、上述方式可以随意组合,但是如有存在变量名相同的情况,后边的会覆盖前面
2、花括号和引号之间不能有空格,如果有空格将最终被解析成为字符串
例如:<view wx:for="{{[1,2,3]}} "> {{item}} </view>
后面有空格等同于:<view wx:for="{{[1,2,3] + ' '}}"> {{item}} </view>
列表渲染
- wx:for
在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。
默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item。
<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>
- block wx:for
类似 block wx:if,也可以将 wx:for 用在标签上,以渲染一个包含多节点的结构块。例如:
<block wx:for="{{[1, 2, 3]}}">
<view> {{index}}: </view>
<view> {{item}} </view>
</block>
- wx:key
wx:key 的值以两种形式提供
- 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
- 保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字
条件渲染
- wx:if
在框架中,使用 wx:if="{{condition}}" 来判断是否需要渲染该代码块,也可以用 wx:elif 和 wx:else 来添加一个 else 块。
<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>
- block wx:if
因为 wx:if 是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个 标签将多个组件包装起来,并在上边使用 wx:if 控制属性。
<block wx:if="{{true}}">
<view> view1 </view>
<view> view2 </view>
</block>
注意: 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
3. wx:if vs hidden
wx:if 之中的模板可能包含数据绑定,所以当 wx:if 的条件值切换时,框架有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。
同时 wx:if 也是惰性的,如果在初始渲染条件为 false,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。
相比之下,hidden 就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。
模版
WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用。
- 定义模板
使用 name 属性,作为模板的名字。然后在内定义代码片段,如:
<template name="msgItem">
<view>
<text> {{index}}: {{msg}} </text>
<text> Time: {{time}} </text>
</view>
</template>
- 使用模板
使用 is 属性,声明需要的使用的模板,然后将模板所需要的 data 传入,如:
<template is="msgItem" data="{{...item}}"/>
Page({
data: {
item: {
index: 0,
msg: 'this is a template',
time: '2016-09-15'
}
}
})
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>
- 模板的作用域
模板拥有自己的作用域,只能使用 data 传入的数据以及模板定义文件中定义的 模块。
事件
-
使用方式
(1) 在组件中绑定一个事件处理函数。
如bindtap,当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数。
<view id="tapTest" data-hi="WeChat" bindtap="tapName"> Click me! </view>
(2) 在相应的Page定义中写上相应的事件处理函数,参数是event。Page({ tapName: function(event) { console.log(event) } })
-
事件分类
事件分为冒泡事件和非冒泡事件:
- 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
- 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。
除了手势相关操作和动画类操作事件,大部分事件都是非冒泡事件。
- 事件绑定和冒泡
- 事件绑定的写法同组件的属性,以 key、value 的形式。key 以bind或catch开头,然后跟上事件的类型,如bindtap。
- value 是一个字符串,需要在对应的 Page 中定义同名的函数。不然当触发事件的时候会报错。
区别:bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡。
- 事件的捕获
自基础库版本 1.5.0 起,触摸类事件支持捕获阶段。捕获阶段位于冒泡阶段之前,且在捕获阶段中,事件到达节点的顺序与冒泡阶段恰好相反。需要在捕获阶段监听事件时,可以采用capture-bind、capture-catch关键字,后者将中断捕获阶段和取消冒泡阶段。 - 事件对象
如无特殊说明,当组件触发事件时,逻辑层绑定该事件的处理函数会收到一个事件对象。
引用
WXML 提供两种文件引用方式import和include。
- import可以在该文件中使用目标文件定义的template。
- import 有作用域的概念,即只会 import 目标文件中定义的 template,而不会 import 目标文件 import 的 template。(即没有传递性)
<template name="item">
<text>{{text}}</text>
</template>
//另一个文件中引用
<import src="item.wxml"/>
<template is="item" data="{{text: 'forbar'}}"/>
- include 可以将目标文件除了 外的整个代码引入,相当于是拷贝到 include 位置。
<!-- index.wxml -->
<include src="header.wxml"/>. //相当将header.wxml内容拷贝到这里
<view> body </view>
<include src="footer.wxml"/>
<!-- header.wxml -->
<view> header </view>
<!-- footer.wxml -->
<view> footer </view>
WXSS
WXSS(WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式, 用来决定 WXML 的组件应该怎么显示。
WXSS 具有 CSS 大部分特性,也进行了一些修改和拓展。
- 拓展
- 尺寸单位
rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。 - 样式导入
使用@import语句可以导入外联样式表,@import后跟需要导入的外联样式表的相对路径,用;表示语句结束。如:@import "common.wxss";
- 内联样式
框架组件上支持使用 style、class 属性来控制组件的样式。
- style:style 接收动态的样式,在运行时会进行解析。静态的样式统一写到 class 中。
<view style="color:{{color}};" />
- class:用于指定样式规则,其属性值是样式规则中类选择器名(样式类名)的集合,样式类名不需要带上.,样式类名之间用空格分隔。
- 选择器
目前支持的选择器有: - 全局样式和局部样式
定义在 app.wxss 中的样式为全局样式,作用于每一个页面。在 page 的 wxss 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 app.wxss 中相同的选择器。
组件
一个组件通常包括 开始标签 和 结束标签,属性 用来修饰这个组件,内容 在两个标签之内。所有组件与属性都是小写,以连字符-连接
组件属性类型有:Boolean、Number、String、Array、Object、EvenHandler(事件处理函数名)、Any(任意属性)
WXS
WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。
注意:
- wxs 不依赖于运行时的基础库版本,可以在所有版本的小程序中运行。
- wxs 与 javascript 是不同的语言,有自己的语法,并不和 javascript 一致。
- wxs 的运行环境和其他 javascript 代码是隔离的,wxs 中不能调用其他 javascript 文件中定义的函数,也不能调用小程序提供的API。
- wxs 函数不能作为组件的事件回调。
- 由于运行环境的差异,在 iOS 设备上小程序内的 wxs 会比 javascript 代码快 2 ~ 20 倍。在 android 设备上二者运行效率无差异。
下面是wxs的一些介绍:
- WXS模块
WXS 代码可以编写在 wxml 文件中的 标签内,或以 .wxs 为后缀名的文件内。
- 每一个 .wxs 文件和 标签都是一个单独的模块。
- 每个模块都有自己独立的作用域,一个模块的变量和函数对其他模块不可见。
- 一个模块要想对外暴露其内部的私有变量与函数,只能通过 module.exports 实现。
- module对象
每个 wxs 模块均有一个内置的 module 对象,module对象有一个属性exports,通过该属性,可以对外共享本模块的私有变量与函数。 - require函数
在.wxs模块中引用其他 wxs 文件模块,可以使用 require 函数。
注意:require只能引用 .wxs文件模块,且路径要是相对路径;wxs 模块均为单例,多个地方引用的都是同一个wxs对象;如果一个 wxs 模块在定义之后,一直没有被引用,则该模块不会被解析与运行。 - <wxs标签
wxs标签有两个属性:module和src。
module属性:module是当前wxs标签的模块名,必填;在单个 wxml 文件内,名称须唯一,否则后面的模块名会覆盖前面的,不同文件之间的 wxs 模块名不会相互覆盖。
src属性:src 属性可以用来引用其他的 wxs 文件模块,和require类似,也有同样的注意事项。 - 注意
1、<wxs模块只能在定义模块的 WXML 文件中被访问到。使用 或 <import 时,<wxs 模块不会被引入到对应的 WXML 文件中。
2、<template 标签中,只能使用定义该 <template 的 WXML 文件中定义的 <wxs 模块。
- 变量
- WXS 中的变量均为值的引用。
- 没有声明的变量直接赋值使用,会被定义为全局变量。
- 如果只声明变量而不赋值,则默认值为 undefined。
- var表现与javascript一致,会有变量提升。
变量命名规则:
- 首字符必须是:字母(a-zA-Z),下划线(_)
- 剩余字符可以是:字母(a-zA-Z),下划线(_), 数字(0-9)
-
注释
方法一:单行注释 //xxx
方法二:多行注释/* xxx /
方法三:结尾注释/ , 即从 /* 开始往后的所有 WXS 代码均被注释. -
运算符
wxs拥有基本的+、-、*、/等基础运算符,自增++自减–等一元运算符,比较运算符,等值运算符、赋值运算符,位运算符,二元运算符等等。 -
语句
wxs也有基本的执行控制语句:if()else{}、switch (注意case 关键词后面只能使用:变量,数字,字符串。)、for、while、do while,用法和java类似。 -
数据类型
wxs支持的数据类型有以下几种:
- number : 数值(包括整数、小数)
- string :字符串("xxx"或者’xxx’)
- boolean:布尔值
- object:对象(object 是一种无序的键值对)
- function:函数(function 里面可以使用 arguments 关键词,该关键词支持lenght和[index]属性)
- array : 数组(数组里的元素类型可以不同)
- date:日期(生成 date 对象需要使用 getDate函数, 返回一个当前时间的对象。)
- regexp:正则(生成 regexp 对象需要使用 getRegExp函数,getRegExp(pattern[, flags]))
参数:
pattern: 正则表达式的内容。
flags:修饰符。该字段只能包含以下字符:
g: global
i: ignoreCase
m: multiline。