小程序的数据绑定和事件绑定

206 阅读4分钟

「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战

数据绑定

数据绑定的基本原则

  • data 中定义数据
  • WXML 中使用数据

在 data 中定义页面的数据

在页面对应的 .js 文件中,把数据定义到 data 对象中即可

Page({
    data: {
        //定义字符串类型的数据
        info:"hello world"
    },
})

Mustache 语法的格式

data 中的数据绑定到页面中渲染,使用 Mustache 语法(双大括号)将变量包起来即可,语法格式为:

<view>{{info}}</view>

Mustache 语法的应用场景

  • 绑定内容

    页面数据:

    Page({
        data: {
            info:"hello world"
        },
    })
    

    页面结构:

    <view>{{info}}</view>
    
  • 绑定组件属性

    页面数据:

    Page({
        data: {
            imgSrc:"http://www.test.com/images/logo.png"
        },
    })
    

    页面结构:

    <image src="{{imgSrc}}" mode="widthFix"></image>
    
  • 进行运算(三元运算、算术运算等)

    页面数据:

    Page({
        data: {
            randomNum:Math.random().toFixed(2)
        },
    })
    

    页面结构:

    <view>{{randomNum * 100}}</view>
    

事件绑定

什么是事件

事件:渲染层到逻辑层的通讯方式,通过事件可以将用户在渲染层产生的行为,反馈到逻辑曾进行业务的处理

Snip20220120_27.png

小程序中常用的事件

类型绑定方式事件描述
tapbindtap 或 bind:tap手指触摸后马上离开,类似于HTML中的click事件
inputbindinput 或 bind:input文本框的输入事件
changebindchange 或 bind:change状态改变时触发

事件对象的属性列表

当事件回调触发的时候,会收到一个事件对象 event,它的详细属性如下

属性类型说明
typeString事件类型 (tap、input等等)
timeStampInteger页面打开到触发事件所经过的毫秒数
target(常用)Object触发事件的组件的一些属性值集合
currentTargetObject当前组件的一些属性值集合
detail(常用)Object额外的信息
touchesArray触摸事件,当前停留在屏幕中的触摸点信息的数据
changedTouchesArray触摸事件,当前变化的触摸点信息的数组

target 和 currentTarget 的区别

  • target 是触发该事件的源头组件

  • currentTarget是当前事件所绑定的组件

    Snip20220120_28.png

    点击内部的按钮,点击事件会以冒泡的方式向外扩散,也会触发外层 viewtap 事件处理函数。此时,对于外层的 view 来说: e.target 指向的时触发事件的源头组件,为内部的按钮组件。 e.currentTarget 指向的是当前正在触发事件的那个组件,为当前的 view 组件

bindtap 的语法格式

在小程序中,不存在 HTML 中的 onclick 鼠标点击事件,而是通过 tap 事件来响应用户的触摸行为,步骤如下:

  1. 通过 bindtap,可以为组件绑定 tap 触摸事件,语法如下

    页面结构:

    <button type="primary" bindtap="btnTapHandler">按钮</button>
    
  2. 在页面的 .js 文件中定义对应的事件处理函数,事件参数通过形参 event(一般简写为e)来接收

    页面数据:

    Page({
        data: {
    
        },
    
        //定义按钮的事件处理函数
        btnTapHandler(e){
            console.log(e)
        },
    })
    

    通过控制台 Console 选项可看见log:

    Snip20220120_29.png

在事件处理函数中为 data 中的数据赋值

通过调用 this.setData(dataObject) 方法,可以给页面 data 中的数据重新赋值

页面数据:

Page({
    data: {
        count:0
    },
    
    countChange(){
        this.setData({
            count: this.data.count + 1
        })
    },
})

页面结构:

<button type="primary" bindtap="countChange">+1</button>
<view>count值:{{count}}</view>

事件传参

小程序中的事件传参比较特殊,不能在绑定事件的同时为事件处理函数传输参数

  • 错误写法:

    小程序不会把 666 当作参数传递,它会把 bindtap 设置的属性值,统一当作事件名称来处理,相当于调用一个名称为 changeNum(666) 的事件处理函数

    <button type="primary" bindtap="changeNum(666)">事件传参</button>
    
  • 正确写法:

    可以为组件提供 data-* 自定义属性传参,其中 * 代表的是参数的名字,示例如下:

    页面结构:

    info 会被解析为参数名字, 数值 666 会被解析为参数的值
    
    使用{{666}},说明666为数字
    <button type="primary" bindtap="changeNum" data-info="{{666}}">事件传参</button>
    
    使用"666",说明666为字符串
    <button type="primary" bindtap="changeNum" data-info="666">事件传参</button>
    

    在事件处理函数中, 通过 evevt.target.dataset.参数名 即可获取到具体参数的值,示例如下

    页面数据:

    changeNum(evevt){
    
        //dataset 是一个对象,包含了所有通过 data-* 传递过来的参数项
        console.log(evevt.target.dataset)
    
        //通过dataset 可以访问到具体的参数的值
        console.log(evevt.target.dataset.info)
    },
    

bindinput 的语法格式

在小程序中,通过 input 事件来响应文本框的输入事件,步骤如下:

  1. 通过 bindinput,可以为文本框绑定输入事件

    <input bindinput="inputHandler"></input>
    
  2. 在页面 .js 文件中定义事件处理函数:

    Page({
        data: {
       
        },
        //e.detail.value 是变化后,文本框最新的值
        inputHandler(e){
            console.log(e.detail.value)
        },
    })
    

实现文本框和 data 之间的数据同步

实现步骤:

  1. 定义数据(.js文件)

    Page({
        data: {
           msg:"hello world"
        }
    })
    
  2. 渲染结构(.wxml文件)

    <input value="{{msg}}" bindinput="iptHandle"></input>
    
  3. 美化样式(.wxss文件)

    input {
        border: 1px solid #eee;
        padding: 5px;    
        margin:5px;
        border-radius: 3px;
    }
    
  4. 绑定 input 事件处理函数(.js文件)

    iptHandle(e){
        this.setData({
            //通过 e.detail.value 获取到文本框最新的值
            msg:e.detail.value
        })
    },