背景
上一篇文章我们已经介绍了WXML的数据绑定,通过Mustache语法可以实现简单绑定、运算和组合,还介绍了wx:if的条件渲染,wx:if与hidden之间的差别,最后介绍了wx:for的列表渲染,嵌套时需要使用wx:for-index和wx:for-item进行改名,避免命名冲突。这篇文章将会介绍WXML的模版和用户事件相关内容。
模版
在实际的开发的过程中常常遇到某些相同的结构在不同的地方反复出现,这时通常的做法是将相同布局的代码片段放到一个模版中,在不同的地方传入相应的数据进行渲染,避免重复开发,提升开发效率。
定义模版
模版的定义十分的简单,在<template/>
标签内定义代码片段,设置name
属性指定模版的属性即可,新建myTemplate.wxml
示例代码如下:
<template name="myTemplate">
<view>{{name}}</view>
<view>{{price}}</view>
</template>
使用模版
使用模版时,通过设置is属性指向使用的模版,设置data属性,将模版所需要的变量传入,模版有自己的作用域,只能使用data属性传入的数据,而无法直接使用Page
中的data
,在渲染时<template/>
标签将被模版中的代码块完全替换。但是模版属性is
是支持数据绑定,可以通过属性绑定动态决定使用哪个模版。下面的代码演示了如何在之前的test.wxml
应用模版。
<import src="../template/myTemplate"></import>
<template is="myTemplate" data="{{name:'苹果', price : '20.12'}}"></template>
模版的数据绑定
在上一篇文章中我们讲了数据绑定,数据绑定有简单绑定、运算和组合,Page
中data
的数据可以在模版中组合成新的数据结构,上一篇文章我们已经讲述了数组的组合,现在我们结合模版的数据绑定讲述一下对象的组合,其主要有以下三种方式。
直接将数据作为value值进行组合
还是以上面的例子说明,其test.wxml
如下
<import src="../template/myTemplate"></import>
<template is="myTemplate" data="{{name : goodsName, price : goodsPrice}}"></template>
test.js如下
// pages/test/test.js
Page({
/**
* 页面的初始数据
*/
data: {
goodsName : '苹果',
goodsPrice : '20.11'
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
})
通过“...”将一个对象展开,将key-value拷贝到新的数据结构
test.wxml
内容如何:
<!--pages/test/test.wxml-->
<import src="../template/myTemplate"></import>
<template is="myTemplate" data="{{...goods}}"></template>
test.js
内容如下:
// pages/test/test.js
Page({
/**
* 页面的初始数据
*/
data: {
goods : {
name : '苹果',
price : '20.11'
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
})
如果key和value相同可以只写key
test.wxml
内容如下:
<!--pages/test/test.wxml-->
<import src="../template/myTemplate"></import>
<template is="myTemplate" data="{{name, price}}"></template>
test.js
内容如下:
// pages/test/test.js
Page({
/**
* 页面的初始数据
*/
data: {
name : '苹果',
price : '20.11'
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
})
import和include
在之前的例子中我们可以看到我们使用<import/>
引入模版,在WXML中可以通过<import/>
和<include/>
引入其他的WXML文件,其二者的区别在于<import/>
引入只接受模版的定义,忽略模版定义之外的所有内容。与<import/>
相反,<include/>
是直接将引入文件中<template/>
以外的代码直接拷贝到<include/>
处。
事件
WXML中的事件系统与HTML中的DOM事件系统极其相似,也是通过在组件上设置“bind(或catch)+ 事件名”属性进行事件绑定,当触发事件时,框架会调用逻辑层中对应的事件处理函数,并将当前的状态通过参数传递给事件处理函数,由于WXML没有DOM节点的概念,所以事件只能通过WXML绑定,不能通过逻辑层动态绑定,官方对于WXML事件定义如下:
- 事件是视图层到逻辑层的通讯方式
- 事件可以将用户的行为反馈到逻辑层进行处理
- 事件可以绑定在组件上,当触发事件时,就会执行逻辑层对应的事件处理函数
- 事件可以携带额外信息如id、dataset、touches
事件的分类
事件分为冒泡事件和非冒泡事件:
- 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递
- 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。
WXML冒泡事件如下:
- touchstart: 手指触摸动作开始
- touchmove: 手指触摸后移动
- touchcancel: 手指触摸动作被打断,如来电提醒、弹窗
- touchend: 手指触摸动作结束
- tap: 手指触摸后马上离开
- longtap: 手指触摸后,超过350ms再离开
对于冒泡事件每个组件都是默认支持的,除去上述事件外其他组件自定义事件无特殊声明都是非冒泡事件,如<form/>
的submit事件,<scroll-view/>
的scroll事件。
事件的绑定
在之前的文章也使用过事件绑定,事件的绑定的写法与组件的属性一样,以key、value形式存在。
- key:以bind或catch开头,然后跟上事件的类型,字母均小写如bindtap、catchtouchstart等
- value:事件函数名,对应于Page中定义的同名函数,找不到同名函数会报错。
绑定时bind事件绑定不会阻止事件向上冒泡,catch事件会阻止冒泡事件向上冒泡。
<view bindtap="tap1">
view1
<view catchtap="tap2">
view2
<view bindtap="tap3">
view3
</view>
</view>
</view>
如上例,点击view3,首先响应tap3,然后tap2,catchtap会阻止事件传递,所以不会触发tap1.
最后
有兴趣可以关注公众号QStack,会定期分享一些文章和免费的学习资源。