自学微信小程序开发第二天-事件处理、数据流


之前学习了微信小程序开发的相关环境,测试了小程序开发工具,并且了解了程序开发框架、架构等信息。这里继续学习

事件处理

绑定冒泡事件

在HTML里,基本上就是使用类似OnClick就可以绑定到后台事件了。微信小程序的名字有些特殊,是bindtap,即绑定触碰事件。用法如下:

<!--wxml-->
<view class="container">
<button bindtap="tap">点击一下</button>
</view>
//js
Page({
  tap: function(){
    console.log('Tap')
  }
})

一些比较常用的事件的bind事件(冒泡事件):

touchstart 手指触摸动作开始
touchmove 手指触摸后移动
touchcancel 手指触摸动作被打断,如来电提醒,弹窗
touchend 手指触摸动作结束
tap 手指触摸后马上离开
longpress 手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发
transitionend 会在 WXSS transition 或 wx.createAnimation 动画结束后触发
animationstart 会在一个 WXSS animation 动画开始时触发
animationiteration 会在一个 WXSS animation 一次迭代结束时触发
animationend 会在一个 WXSS animation 动画完成时触发

阻止冒泡事件

冒泡事件是当一个组件上的事件被触发后,该事件会向父节点传递。可以使用catch绑定事件阻止冒泡,例如:

<!--wxml-->
<view id="v1" bindtap="handleTap1">
   view1
  <view id="v2" catchtap="handleTap2">
     view2
    <view id="v3" bindtap="handleTap3">
       view3
    </view>
  </view>
</view>

这里点击view3后,会先后调用handleTap3handleTap2(因为tap事件会冒泡到view2,而view2阻止了tap事件冒泡)

互斥事件

另外使用mut-bind绑定的事件是互斥事件,只会有一个方法被触发。例:

<!--wxml-->
<view id="v1" mut-bind:tap="handleTap1">
   view1
  <view id="v2" bindtap="handleTap2">
     view2
    <view id="v3" mut-bind:tap="handleTap3">
       view3
    </view>
  </view>
</view>

这里点击view3后,会先后调用handleTap3handleTap2,而不调用handTap1,因为和handleTap3互斥。

事件传参

这里研究的事件传参指的不是函数参数,而是多个元素使用同一函数时,确定哪个元素触发的函数。在ASP.NET时,可以通过获取触发的元素对象,或者通过函数参数来确定哪个元素触发函数。在小程序中是有些不一样的,绑定事件时只是绑定的函数名称,并不能给函数参数。

在小程序的函数里,只有1个参数ee.target就是触发事件的对象,我们可以使用e.target.dataset传递参数。可以在触发事件的元素后面以data-??="xxx"的形式,将参数写到e.target.dataset内。例如:

<!--wxml-->
<view class="container">
    <button bindtap="tap" data-id="click">点击一下</button>
</view>
//js
Page({
  tap: function(e){
    console.dir(e.target.dataset)
  },
})

点击后,在控制台内能看到Object,点击前方的小三角就能看到传递的参数id: “click”。使用的时候,也可以用e.target.dataset.id来调取,返回值就是click

事件对象的属性

当事件回调触发时,会收到一个事件对象 event ,即事件 function 的参数 e 。之前发现可以通过 e.target.dataset 来传递参数,这里详细研究下这个 eevent 对象的比较重要的详细属性如下:

属性类型说明
typeString事件类型
timeStampInteger页面打开到触发事件所经过的毫秒数
targetObject触发事件的组件的一些属性值集合
currentTargetObject当前组件的一些属性值集合
detailObject额外的信息
touchesArray触摸事件,当前停留在屏幕中的触摸点信息的数组
changedTouchesArray触摸事件,当前变化的触摸点信息的数组

其中需要注意的是 targetcurrentTarget 的区别。target 是触发事件的组件,而 currentTarget 是当前事件所绑定的组件。乍一看两者是相同的,其实还是有区别的。最常见到的就是在事件冒泡的过程中,target 是不会改变的,都指向了触发事件的源头组件,而 currentTarget 则会根据事件的冒泡而变成当前事件所绑定的组件。

数据流

应用程序就是将一堆数据呈现在界面上,然后获取用户输入的数据,进行相应处理操作后,再呈现给用户的反复循环操作。在小程序中,就是数据在视图层和逻辑层之间的流动。因为小程序没有双向绑定机制,只能单向流动,数据从逻辑层往视图层传递通过数据绑定实现,从视图层往逻辑层传递通过事件实现。

一个实例,文本输入和输出联动。首先,先通过数据绑定从逻辑层往视图层传递数据。

<!--wxml-->
<view class="container">
  <view>
    <input value="{{massage}}" />
    <text>{{massage}}</text>
  </view>
</view>
//JS
Page({
  data: {
    massage: 'mydata'
  }
})

这样,就有了一个默认的数据传递给视图层。视图层的数据获得之前研究事件传参时,知道了通过参数对象e的成员获得。在小程序里,input可以通过绑定输入事件input,在输入框有改动时获取其值。而输入框输入的值,通过分析e知道,在e.detail.value里。这就实现了数据的双向流动。

但是在使用过程中,不能使用this.data.massage = e.detail.value 这样的语句更改massage的值让输出的内容联动更改。是因为小程序对于数据绑定是一次性的,即页面加载时进行一次数据绑定就完成了,并不监听绑定数据的更改。这就需要使用setData函数进行通知了,然后才再次进行数据绑定,做到实时同步更新数据。

更改完的代码如下:

<!--wxml-->
<view class="container">
  <view>
    <input value="{{massage}}" bindinput="input" />
    <text>{{massage}}</text>
  </view>
</view>
//js
Page({
  data: {
    massage: 'mydata'
  },
  input:function(e){
      this.setData({
        massage: e.detail.value
      })
  }
})

实例:登录页面案例

通过登录页面这个案例,来复习下视图层、逻辑层、事件和数据流的相关知识。
注:类似ASP.NET的登录页面,不获取微信ID等微信信息。

  • 页面设计
<!-- wxml -->
<view class="container">
    <view style="margin-top: 300px;" />
    <view style="border: 1px;">
        <input placeholder="请输入用户名" />
        <input placeholder="请输入密码" type="password" />
    </view>
    <view style="margin-top: 50px;">
        <button type="primary">登录</button>
        <button type="default">注册</button>
    </view>
</view>
  • 将数据绑定到特定元素
<!--index.wxml-->
<view class="container">
    <view style="margin-top: 300px;" />
    <view style="border: 1px;">
        <input placeholder="请输入用户名" value="{{username}}" />
        <input placeholder="请输入密码" type="password" value="{{password}}" />
    </view>
    <view style="margin-top: 50px;">
        <button type="primary">登录</button>
        <button type="default">注册</button>
    </view>
</view>
// index.js
Page({
    data:{
        username: '',
        password: ''
    }
})
  • 登录按钮的点击事件,处理具体的登录逻辑。
    此步骤分3步:需要获取用户输入信息,再根据用户输入的值进行判断,然后根据判断结果做出响应。这里第2、3步就不详细研究了,只研究第1步。

获取用户输入信息:我们无法直接调用用户输入的信息,需要通过事件传递的数据参数获取。也就是说要设计一个用户输入事件,来获取输入的信息。

<!--index.wxml-->
<view class="container">
    <view style="margin-top: 300px;" />
    <view style="border: 1px;">
        <input placeholder="请输入用户名" value="{{username}}" bindinput="change" data-id="username" />
        <input placeholder="请输入密码" type="password" value="{{password}}" bindinput="change" data-id="password" />
    </view>
    <view style="margin-top: 50px;">
        <button type="primary" bindtap="login">登录</button>
        <button type="default">注册</button>
    </view>
</view>
// index.js
Page({
    //数据绑定
    data: {
        username: '',
        password: ''
    },
    //用户输入事件,根据设置的data-id来判断给哪个变量赋值
    change: function (e) {
        var prop = e.target.dataset.id
        var changed = {}
        changed[prop] = e.detail.value
        this.setData(changed)
    }
})

这个实例只是复习之前学习的内容,在实际使用中,并不这样使用。因为小程序提供的有Form表单组件,可以直接调用相关信息,使用起来更加便捷。

重要参考:

B站上找到的开发教程视频,Up主不知道叫啥……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值