WXML 中的动态数据均来自对应 Page 的 data。

  数据绑定使用 Mustache 语法(双大括号)将变量包起来,可以作用于许多地方。

# 一、数据绑定

  其实小程序中的Mustache 语法和 vue 中的插值表达式类似

vud 中的插值表达式使用位置只能在内容节点,不能在属性节点。

小程序的 Mustache 语法既可以使用于内容节点,还可以使用于属性节点。

# 1、内容渲染

<view> {{ text-message }} </view>

<rich-text nodes="{{html-message}}"></rich-text>
Page({
  data: {
    text-message: "纯文本",
    html-message: "HTML标签字符串"
  }
})

在 vue 中则是通过 v-text、v-html 属性和文本插值实现

Mustache 语法使用:

<!-- 运算 -->
<div>{{ number + 1 }}</div>

<!-- 三元运算 -->
<view hidden="{{flag ? true : false}}"> Hidden </view>

<!-- 非字符串类型、关键字👀 -->
<checkbox checked="{{false}}"> </checkbox>

<!-- 数组和对象中👀 -->
<view wx:for="{{[zero, 1, 2, 3, 4]}}"> {{item}} </view>
<template is="objectCombine" data="{{for: a, bar: b}}"></template>
<template is="objectCombine" data="{{foo, bar}}"></template>

<!-- 拼接🍗 -->
<div id="{{'list-' + id}}"></div>

# 2、属性绑定

  从上面的代码示例可以发现,在小程序中进行属性绑定时,不需要在属性前加上 v-bind(:),而是直接使用 Mustache 语法即可。

在小程序中几乎关系数据绑定的使用的都是 Mustache 语法

提示

  花括号和引号之间如果有空格,将最终被解析成为字符串

<swiper>
  <block wx:for="{{banners}}" wx:key="image">
    <swiper-item>
      <view class="swiper-item {{item}}"></view>
    </swiper-item>
  </block>
</swiper>

# 3、变量赋值

Page.prototype.setData(Object data, Function callback)

  setData 函数用于将数据从逻辑层发送到视图层(异步),同时改变对应的 this.data 的值(同步)

// index.js
Page({
  data: {
    text: 'init data',
    num: 0,
    array: [{ text: 'init data' }],
    object: {
      text: 'init data'
    }
  },
  // 1、若修改this.data(视图不会更新)
  changeText: function () {
    // this.data.text = 'changed data' // ✖
    // 【对于一些没有视图更新需求的数据,是可以直接这样写的,简洁👀】
  },

  // 2、可以在函数内修改后赋值
  changeNum: function () {
    this.data.num = 1
    this.setData({
      num: this.data.num
    })
  },

  // 3、数组和对象中的赋值
  changeItemInArray_Object: function () {
    this.setData({
      'array[0].text': 'changed data',
      'object.text': 'changed data'
    })
  }
})

# 4、template 模板 ✨

官方文档:

WXML 模板 (opens new window)

提示

 自从基础库版本 1.6.3 开始支持自定义组件开发后,使用 template 模板的频率就变得相对较少了 🤔。

① 代码示例

  • 定义模板
<!-- name属性作为模板的名字 -->
<template name="msgItem">
  <view>
    <text> {{index}}: {{msg}} </text>
    <text> Time: {{time}} </text>
  </view>
</template>
  • 使用模板
<!-- 使用is属性指定使用的模板 -->
<template is="msgItem" data="{{...item}}" />

② is 属性拓展

  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>

# 二、事件处理

官方描述:BaseEvent (opens new window)

# 1、事件绑定

  小程序中的事件绑定和 vue 中的事件绑定有很大的不同。

  • vue 中:
<!-- 不带参 -->
<button v-on:click="myFunction">点击我.</button>
<p id="demo" @click="myFunction">点击我.</p>
<!-- 带参 -->
<button @click="add($event, 1)">+N</button>
  • 小程序中:
<!-- 不带参 -->
<button bind:tap="myFunction">点击我.</button>
<p id="demo" bindtap="myFunction">点击我.</p>
<!-- 带参 -->
<button bindtap="add" data-num="{{1}}">+N</button>

data-num 属性:num 表示参数名

  可以发现 vue 中的事件绑定采用v-on,而小程序中采用bind:;并且在事件传参上的使用是不同的。

传参变化原因

  根本原因就是小程序采用的是双线程模型,我们不能直接在逻辑层使用逻辑层传来的数据。

  但我们可以巧妙的借助自定义属性实现解决这个问题。

① 小程序常用事件:

事件类型 事件绑定 说明
tap bindtap 触摸后离开(类似于 HTML 中的 click)
input bindinput 文本框输入事件
change bindchange 状态改变时触发

对于事件的具体使用,详见组件 (opens new window)

# 2、event 对象

  相较于 vue,在小程序中使用原生事件对象 event 的频率会高很多。

因为事件传参是通过 自定义属性 data-* 进行传递的。

注意

  由于事件参数也绑定到了 event 对象上,当我们要拿取事件参数时,记得使用 event.currentTarget,而不是 event.target

如果实在区分不了,在基础库版本 2.7.1 以上时,我们还可以使用 mark:*进行传参。

myFunction(e) {
  console.log(e)

  console.log(e.target.dataset) // 触发事件的源组件的参数集合
  console.log(e.detail.value) // value属性值变化🚩(数据传递👀)

  console.log(e.mark) // 仅小程序中

  // 冒泡事件中
  console.log(e.currentTarget.dataset) // 当前事件绑定的组件的参数集合
}

# 3、捕获与冒泡

  除 bind 外,也可以用 catch 来绑定事件。与 bind 不同, catch 会阻止事件向上冒泡。

  需要在捕获阶段监听事件时,可以采用 capture-bind、capture-catch 关键字,后者将中断捕获阶段和取消冒泡阶段。

# 三、条件渲染

# 1、使用示例

<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>

可以发现,小程序中使用vx:代替了 vue 中的v-

拓展:

  如果要一次性判断多个组件标签,可以使用一个 <block/>标签将多个组件包装起来,并在上边使用 wx:if 控制属性。

<block wx:if="{{true}}">
  <view> view1 </view>
  <view> view2 </view>
</block>

<block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。

# 2、显示与隐藏

<view wx:if="{{flag}}">wx:if控制的内容区域</view>

<view hidden="{{flag}}">hidden控制的内容区域</view>

 对于使用选择,可以联系到 vue 中的:

  • v-if类似于小程序中的wx:if
  • v-show类似于小程序中的hidden

# 四、列表渲染

  小程序中的列表渲染和 vue 中的列表渲染有很大的不同。

Page({
  data: {
    // 一个数组
    items: [
      { message: '1', message2: 'Foo'},
      { message: '2', message2: 'Bar'},
      // ……,
    ]
    // 单个对象
    object: {
      title: 'How to do lists in Vue',
      author: 'Jane Doe',
      publish: '2016-04-10'
    }
  }
})

# 1、使用示例

  • vue 中
<!-- 1、数组 -->
<ul id="example-1">
  <li v-for="(item, index) in items" :key="item.message">{{ item.message }}</li>
</ul>

<!-- 2、对象 -->
<ul id="example-2">
  <li v-for="(value, name, index) in object">{{ index }}. {{ name }}: {{ value }}</li>
</ul>
  • 小程序中
<!-- 1、数组 -->
<view id="example-1">
  <view wx:for="{{items}}" wx:key="message">{{index}}:{{item.message}}</view>
</view>

<!-- 2、数字、字符串 -->
<view id="example-2">
  <view wx:for="{{10}}" wx:key="*this">{{item}}</view>
</view>

  通过对比发现,在小程序中直接将 🚩 数组名挂载即可,并且相应的indexitem、可以直接使用

  • index:数组当前项下的默认标变量名
  • item:数组当前项的默认变量名

注意:wx:key 的使用不需要使用插值表达式

# 2、wx:key 使用

wx:key 值的两种形式
  • 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。

  • 保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字。

提示

  小程序中也提供了类似于 vue 中的<template></template>标签的组件 —— <block></block>

<block wx:for="{{[1, 2, 3, 4, 5]}}" wx:key="*this">
  <view>{{item % 2 == 0 ? 'even' : 'odd'}}</view>
</block>

# 3、双层 for

  小程序默认将遍历的没一项命名为 item,在多层 for 循环中,我们是可以对其命名进行修改的

wx:for-item="i"wx:for-index="itemIndex"

<view>
  <block wx:for="{{list}}" wx:key="index">
    <view>{{item}}</view>

    <block wx:for="{{list.data}}" wx:key="*this" wx:for-item="i">
      <view>{{i}}</view>
    </block>
  </block>
</view>

# 五、双向绑定

  在 WXML 中,普通的属性的绑定是单向的。如:

① 简单示例

  • 单向
<input value="{{value}}" />
  • 双向
<input model:value="{{value}}" />

② 注意事项

双向绑定的表达式只能是一个单一字段的绑定,并且不然识别 data 路径

  • 错误示例
<input model:value="值为 {{value}}" />
<input model:value="{{ a + b }}" />

<input model:value="{{ a.b }}" />
更新于 : 8/7/2024, 2:16:31 PM