您现在的位置是:首页 >学无止境 >微信小程序开发手册 - 04数据绑定与交互网站首页学无止境
微信小程序开发手册 - 04数据绑定与交互
用过react的小伙伴对于小程序的数据绑定肯定相当熟悉,在react中我们是用 {} 在视图层进行解析JS中的变量,而小程序中是通过 {{}} 解析。
数据绑定
我们先看一个简单的数据绑定
Page({
data: {
message: "Hello World"
}
})
<view>{{message}}</view>
JS 文件中data对象里定义着我们在小程序中所用变量的初始值
列表渲染
在 vue 中我们有 v-for ,而在小程序中我们也有 wx:for 达到同样的效果
<view wx:for="{{array}}" wx:key="*this">{{"下标: " + index + ", 值: " + item}}</view>
Page({
data: {
array: [1, 2, 3, 4, 5]
}
})
从上面的代码中我们可以看出 index 和 item 都是小程序对于 wx:for 默认提供的,在我们遍历数组时,一个代表着当前元素的下标,一个代表着当前元素自身
对于 index/item 既然是小程序默认提供的,那么我们也可以通过 wx:for-index / wx:for-item 来分别自定义 index / item 的名称,如下例
<view wx:for="{{array}}" wx:for-index="arrayIndex" wx:for-item="arrayItem" wx:key="*this">{{arrayItem.name}}</view>
Page({
data: {
array: [
{ name: '关关雉鸠' },
{ name: '在河之洲' }
]
}
})
在上面的例子中我们都是把 wx:for 放在一个组件上的,假如现在我们有个需求需要同时遍历多个组件怎么办,这个时候可能有小伙伴想到用 view 包裹那些组件,但是这个就会造成DOM结构变得异常复杂,我们知道小程序的DOM节点嵌套是有一定限制警告的,可查看小程序性能中 控制WXML节点数量和层级
这个时候怎么办呢?官方为我们提供了 block 标签,可用来渲染一个包含多节点的结构块
<block wx:for="{{[1, 2, 4]}}" wx:key="*this">
<view>下标: {{index}} </view>
<view>元素: {{item}} </view>
</block>
从图中我们可以看出 block 是不作为标签渲染在DOM节点中
有细心的小伙伴应该发现了,我在写每一个 wx:for 都加了一个 wx:key ,这又是因为什么呢?
用过vue 和 react 应该对这个 key 比较了解了,对于 wx:for 循环 wx:key 就是性能优化的方法,假设我们现在有一个数组[1, 2, 3, 4, 5],然后将这五项渲染出来,现在我们要改变其中某一个值,如果我们没设置 key 就会重新渲染,如果我们添加了key,小程序就会以key 为一个查找标准,避免全部重新渲染,从而达到一个渲染优化
wx:key 的值以两种形式展示
- 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
- 保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字。
PS: 如不提供 wx:key,会报一个 warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略
字符串形式
<view wx:for="{{array}}" wx:key="id">{{item.name}}}</view>
Page({
data: {
array: [
{ id: 0, name: '关关雉鸠' },
{ id: 1, name: '在河之洲' }
]
}
})
关键字形式
<view wx:for="{{[1, 2, 3, 4]}}" wx:key="*this">{{item}}}</view>
条件渲染
小程序为我们提供了 wx:if 判断是否显示该模块,同 vue 中的 v-if 类似
<view wx:if="{{bool}}"> True </view>
wx:if 的值为 false 时,整个组件不会解析在wxml 中,与 display: none 不同
对比 v-if 小程序还提供了wx:elif 和 wx:else 让我们可以处理多种情况
<view wx:if="{{length > 5}}">大于5</view>
<view wx:elif="{{length < 1}}">小于1</view>
<view wx:else>小于5并且大于1</view>
因为 wx:if 是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个 标签将多个组件包装起来,并在上边使用 wx:if 控制属性
<block wx:if="{{true}}">
<view> view1 </view>
<view> view2 </view>
</block>
这些需要注意的是,wx:if 的条件值切换时,在小程序中会有一个局部渲染的过程,这个过程会触发组件的销毁与创建过程,同时,wx:if 是惰性的,在初始化值为false时,小程序会什么都不做
另外小程序也提供了一个 hidden 属性,类似于 v-show 的效果,对于组件进行简单的显示于隐藏,hidden 接受值为Boolean 值,区别同 v-if 与v-show 的区别,wx:if 是对组件的创建与销毁,hidden 是对组件进行 display: none 的操作
template 模版
见官方文档
事件交互
在vue 中 我们通过v-on + 事件名(点击)绑定事件,在react中则是on + 事件名(点击)绑定事件,而在小程序中我们需要通过bind进行绑定事件
另外小程序中的点击事件为tap,更多事件请见事件分类
<view id="tapTest" data-text="Weixin" bindtap="onClick">点击</view>
小程序绑定事件和绑定数据不同,小程序的方法事件绑定时是不需要 {{}} 表达式
与vue、react 不同的是,小程序的事件传值,需要在组件节点上附加一些自定义数据,这自定义数据以 data- 开头,多个单词由连字符 - 连接,默认会转换为小写字符,如下
- data-element-type ,最终会呈现为 event.currentTarget.dataset.elementType
- data-elementType ,最终会呈现为 event.currentTarget.dataset.elementtype
Page({
onClick: function(event) {
console.log(event)
}
})
log 的打印大致如下
{
"type":"tap",
"timeStamp":895,
"target": {
"id": "tapTest",
"dataset": {
"text":"Weixin"
}
},
"currentTarget": {
"id": "tapTest",
"dataset": {
"text":"Weixin"
}
},
"detail": {
"x":53,
"y":14
},
"touches":[{
"identifier":0,
"pageX":53,
"pageY":14,
"clientX":53,
"clientY":14
}],
"changedTouches":[{
"identifier":0,
"pageX":53,
"pageY":14,
"clientX":53,
"clientY":14
}]
}
更多详情内容,请见事件详解