您现在的位置是:首页 >学无止境 >微信小程序开发手册 - 04数据绑定与交互网站首页学无止境

微信小程序开发手册 - 04数据绑定与交互

竹苏 2024-08-23 12:01:02
简介微信小程序开发手册 - 04数据绑定与交互

用过react的小伙伴对于小程序的数据绑定肯定相当熟悉,在react中我们是用 {} 在视图层进行解析JS中的变量,而小程序中是通过 {{}} 解析。

数据绑定

我们先看一个简单的数据绑定

Page({
  data: {
    message: "Hello World"
  }
})
<view>{{message}}</view>

image.png
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]
  }
})

image.png
从上面的代码中我们可以看出 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: '在河之洲' }
    ]
  }
})

image.png
在上面的例子中我们都是把 wx:for 放在一个组件上的,假如现在我们有个需求需要同时遍历多个组件怎么办,这个时候可能有小伙伴想到用 view 包裹那些组件,但是这个就会造成DOM结构变得异常复杂,我们知道小程序的DOM节点嵌套是有一定限制警告的,可查看小程序性能中 控制WXML节点数量和层级
这个时候怎么办呢?官方为我们提供了 block 标签,可用来渲染一个包含多节点的结构块

<block wx:for="{{[1, 2, 4]}}" wx:key="*this">
  <view>下标: {{index}} </view>
  <view>元素: {{item}} </view>
</block>

image.png
从图中我们可以看出 block 是不作为标签渲染在DOM节点中
有细心的小伙伴应该发现了,我在写每一个 wx:for 都加了一个 wx:key ,这又是因为什么呢?
用过vue 和 react 应该对这个 key 比较了解了,对于 wx:for 循环 wx:key 就是性能优化的方法,假设我们现在有一个数组[1, 2, 3, 4, 5],然后将这五项渲染出来,现在我们要改变其中某一个值,如果我们没设置 key 就会重新渲染,如果我们添加了key,小程序就会以key 为一个查找标准,避免全部重新渲染,从而达到一个渲染优化
wx:key 的值以两种形式展示

  1. 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
  2. 保留关键字 *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
  }]
}

更多详情内容,请见事件详解

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。