IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 自学小程序之路(三),来自一个Android 开发人员的碎碎念 -> 正文阅读

[移动开发]自学小程序之路(三),来自一个Android 开发人员的碎碎念

在说明如何修改页面的数据之前,我们必须要先制造一个改变数据的契机。比如我们点击了一个按钮。

所以还是先了解一下小程序中的组件的点击事件吧。

事件的绑定和参数

新建小程序项目的时候,会有一部分自动生成的代码,同时还会展示出来一个带有我们头像和昵称的页面。

如果点击头像,会发现跳往了另一个页面。

?

<!--index.wxml-->
<view class="container">
  <view class="userinfo">
    <block wx:if=“{{canIUseOpenData}}”>

<!—- 这个view定义了点击事件 bindtap—->
      <view class="userinfo-avatar" bindtap="bindViewTap">
        <open-data type="userAvatarUrl"></open-data>
      </view>
      <open-data type="userNickName"></open-data>
    </block>
</view>

也就是说点击头像的view的时候,触发了bindViewTap事件

而这个事件是bindTap这个属性的值,那看来还是得去研究下这个bindtap咯。

打开微信官方文档

先来看一看事件类型

也就是说这个tap相当于我们Android中的click。那bind又是怎么回事呢,这个本篇后面会讲到。

此外,官方文档中还提到

当事件回调触发的时候,会收到一个事件对象。

同时这个对象有以下属性?

?

也就是说在我们的index.js中,bindViewTap()写全的话是这样的。

//index.js  
bindViewTap: function(e){
    // 尝试打印一下这个e
    console.log(e);
        wx.navigateTo({
      url: '../logs/logs'
    })
  },

为了清楚的看到这个传回来的参数对象的属性,我把这个对象在控制台上打印了出来。

点击头像,就会在控制台看到以下内容。

?

需要注意的是target和current target的区别,currenttarget是绑定了属性bindtap的组件,而target是点击时手指点击的组件。

可以在头像的view层外面包裹一层父view来做个试验

<!--index.wxml-->
<view class="container">
  <view class="userinfo">
    <block wx:if="{{canIUseOpenData}}">
    <!-- 在头像的view外面套一层父view,id为outter,同时将点击事件绑到父view身上 -->
    <view id="outter" bindtap="bindViewTap">
    <!-- 原本的头像id设置为inner -->
      <view id="inner" class="userinfo-avatar" >
        <open-data type="userAvatarUrl"></open-data>
      </view>
    </view>
      <open-data type="userNickName"></open-data>
    </block>
</view>

然后再点击头像会看下打印的log?

?

可以看到currentTarget是父view也就是绑

定了点击事件的view。而target是inner,也就是手指触碰的view。

看到这里,就会想到的Android的事件拦截机制。

事件的捕获、冒泡和中断

在小程序中,也存在事件拦截机制,发生在官方文档说的捕获与冒泡的过程中。

?一下为微信官方的文档说明

事件绑定的写法和组件属性一致,以key="value"的形式,其中:

  1. key以bind或者catch开头,然后跟上事件的类型,如bindtap、catchtouchstart。自基础库版本1.5.0起,bind和catch后可以紧跟一个冒号,其含义不变,如bind:tap、catch:touchstart。同时bind和catch前还可以加上capture-来表示捕获阶段。
  2. value是一个字符串,需要在对应的页面Page构造器中定义同名的函数,否则触发事件时在控制台会有报错信息。
    bind和capture-bind的含义分别代表事件的冒泡阶段和捕获阶段(也就是说之前的bindtap的意思是此次点击事件是冒泡阶段)

上图来表示下所谓的捕获阶段和冒泡阶段

?

可以看出capture-bind指定的时间是由父组件一层层传到子组件,

bind事件是从子组件一层层传到父组件。

“这种感觉特别像你往一个一层套一层的套盒中扔了一个蹦蹦球。

这个蹦蹦球下落过程中,一直从外向内,由父到子的触发了每个箱子的cpature-bind机关。这个过程称之为捕获阶段

当蹦蹦球触底弹起后,有从内向外,有子到父的触发了每个箱子的bind机关。这个阶段称之为冒泡阶段。

两个阶段组合在一起形成了一条顺序执行的事件链条?

而我们定义的bindtap阶段,也就是说该事件发生在从子到父的冒泡阶段中

做个试验:

父view设置了capture-bind和bind

子view也设置了capture-bind和bind,

看下这四个事件如何执行

<!--index.wxml-->
<view class="container">
  <view class="userinfo">
    <block wx:if="{{canIUseOpenData}}">
    <!-- 在头像的view外面套一层父view,设置了capture-bind和bind -->
    <view id="outter" bindtap="outterbind" capture-bind:tap="outterCapturebind">
    <!-- 原本的头像id设置为inner 也设置了capture-bind和bind-->
      <view id="inner" class="userinfo-avatar" bindtap="innerbind" capture-bind:tap="innerCapturebind">
        <open-data type="userAvatarUrl"></open-data>
      </view>
    </view>
      <open-data type="userNickName"></open-data>
    </block>
// index.js
outterbind: function (e) {
    console.log("outterbind");
  },
  outterCapturebind: function (e) {
    console.log("outterCapturebind");
  },
  innerbind: function (e) {
    console.log("innerbind");
  },
  innerCapturebind: function (e) {
    console.log("innerCapturebind");
  },

接下来点击头像,实际上就是点击id为inner的view

打印的log如下

?

由此可见,确实是先执行capturebind从父到子的捕获阶段,然后在执行bind从子到父的冒泡阶段

事件顺序知道了,再看一下他的拦截机制。

截止现在,了解的有capturebind事件和bind事件,如果把capturebind改为capturecatch,把bind改为catch,就是说把bind改为catch)就意味着事件到此截止。

👆的链条?模式就会被打断

依然做个试验

父控件在捕获阶段就进行拦截。即把capture-bind改为capture-catch

<!--index.wxml-->
<view class="container">
  <view class="userinfo">
    <block wx:if="{{canIUseOpenData}}">
    <!-- 在头像的view外面套一层父view,设置了capture-catch和bind -->
    <view id="outter" bindtap="outterbind" capture-catch:tap="outterCapturecatch">
    <!-- 原本的头像id设置为inner 也设置了capture-bind和bind-->
      <view id="inner" class="userinfo-avatar" bindtap="innerbind" capture-bind:tap="innerCapturebind">
        <open-data type="userAvatarUrl"></open-data>
      </view>
    </view>
      <open-data type="userNickName"></open-data>
    </block>
</view>

然后给js文件加入capture-catch事件的函数。

//index.js
  outterCapturecatch: function (e) {
    console.log("outterCapture-catch");
  },

依然点击头像,实际上就是点击id为inner的view

打印的log如下

可以看到由于父组件的从上到下的capture链条由于父组件的拦截导致链条在第一步就中断了。用微信的话说也就是中断了捕获阶段,自然也不会走到冒泡阶段了。

各位看官可以自己试试父子俩其他的时间的bind改为catch看看。

搞清楚点击事件的机理后,貌似扯得有些远了,再来看看如何js如何让数据改变并更新到wxml上。?

setData更改数据

依然拿文本部分开刀。

<!—- index.wxml —->

<view class="usermotto">

? ? <!--加入点击事件-->

? ? <text class=“usermotto" bindtap=“txttap">{{motto}}</text>

? </view>

在js文件中加入方法声明

//index.js
txttap:function(e){
      this.setData({
        motto:"hello no world",
      }
      )
  },

可以看到这个方法内部执行了一个setData()的方法,方法中传入了一个对象作为参数,this和在Java中的意思一样,指的是Page这个对象。

参数对象里面把data对象中的motto的值改为了”hello no world”

因为页面中的text组件显示的内容是{{motto}}的值,那按理说执行点击方法后text的值也会发生变化。

然后我们点击下helloworld文字区域看一下。

?

可以看到确实发生了变化。

按住Ctrl点击setdata会看到关于这个方法的一些说明

 interface InstanceMethods<D extends DataOption> {
        /** `setData` 函数用于将数据从逻辑层发送到视图层
         *(异步),同时改变对应的 `this.data` 的值(同步)。
         *
         * **注意:**
         *
         * 1. **直接修改 this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致**。
         * 1. 仅支持设置可 JSON 化的数据。
         * 1. 单次设置的数据不能超过1024kB,请尽量避免一次设置过多的数据。
         * 1. 请不要把 data 中任何一项的 value 设为 `undefined` ,否则这一项将不被设置并可能遗留一些潜在问题。
         */
        setData(
            /** 这次要改变的数据
             *
             * 以 `key: value` 的形式表示,将 `this.data` 中的 `key` 对应的值改变成 `value`。
             *
             * 其中 `key` 可以以数据路径的形式给出,支持改变数组中的某一项或对象的某个属性,如 `array[2].message`,`a.b.c.d`,并且不需要在 this.data 中预先定义。
             */
            data: Partial<D> & IAnyObject,
            /** setData引起的界面更新渲染完毕后的回调函数,最低基础库: `1.5.0` */
            callback?: () => void
        ): void

?从注释中可以看到需要注意的部分,不再赘述。

而且看到setdata其实是有两个参数的(data 和 callback)

改造一下我们的点击事件


//index.js
txttap:function(e){
      this.setData({
        motto:"hello no world",
      },
	function(){
     	  console.log("callback") 
      	}
      )
  },

执行点击后查看log

在渲染完view后,setdata的方法参数确实被回调了。

也就是说更改完数据后,如果需要什么后续操作的话可以在这个方法里进行。

在小程序里,修改数据就是从js页面重新setdata然后自动更新到wxml对应的表达式中。

这和Android中的MVVM的写法还是很像的。只不过Android的观察者模式是ObservableFiled来包装,并且需要有viewmodel和生命周期的加持。

说完了页面内的数据操作,然后说一下页面跳转怎么处理。

页面跳转

不带参数的跳转,就在微信的自动生成的代码中的点击头像的方法里就有。

就是这段。

//index.js

? bindViewTap: function (e) {

? ? // 尝试打印一下这个e

? ? console.log(e);

? ? // 跳转到logs页面

? ? wx.navigateTo({

? ? ? url: '../logs/logs'

? ? })

? },

?

就是跳到了父目录下面的logs文件夹下面四个文件组成的logs页面

带参数的跳转

比如我们给logs页面传递一个id=1这样的参数,

//index.js
  bindViewTap: function (e) {
    // 尝试打印一下这个e
    console.log(e);
    // 跳转到logs页面
    //传递参数id=1,from="index"
    wx.navigateTo({
      url: '../logs/logs?id=1&from=index'//注意&符号前后不要有空格
    })
  },

写法有些像平常的get请求的url,参数用?接在后面,key=value模式,用&拼接

注意&前后不要有空格,比如如果再form前后加了空格,那么会默认key是带引号的“from”

同时尝试在logs页面的onLoad方法中接收这些值

// logs.js
const util = require('../../utils/util.js')

Page({
  data: {
    logs: []
  },
  onLoad(argument) {//将接受的值命名为argument,并打印其属性
    console.log(argument);
    console.log(argument.id + " "+ argument.from);
    this.setData({
      logs: (wx.getStorageSync('logs') || []).map(log => {
        return {
          date: util.formatTime(new Date(log)),
          timeStamp: log
        }
      })
    })
  }
})

然后把wxml还原到一开始建好项目的样子,点击头像,跳转logs页面,看下控制台输出

?

可以看到logs页面确实收到了我们传递的对象。

小程序的页面跳转和Android的页面跳转一样采取压栈模式。

同一个栈中,后入先出。

但是又tab的页面除外,后期写到了再说。

可以看微信的官方文档了解一下。

https://developers.weixin.qq.com/ebook?action=get_post_info&docid=0004eec99acc808b00861a5bd5280a

布局,数据展示和跳转页面看完了,下一篇打算写写网络连接和微信环境的使用。比如登陆呀,授权呀,分享啊一方面的。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-07-24 11:36:36  更:2021-07-24 11:38:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/2 6:47:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码