原生小程序 基础学习笔记

1.数据绑定

小程序的逻辑层和渲染层是分开的两个线程。在渲染层,宿主环境会把WXML转化成对应的JS对象,在逻辑层发生数据变更的时候,我们需要通过宿主环境提供的setData方法把数据从逻辑层传递到渲染层,再经过对比前后差异,把差异应用在原来的Dom树上,渲染出正确的UI界面。

通过setData把msg数据从“Hello World”变成“Goodbye”,产生的JS对象对应的节点就会发生变化,此时可以对比前后两个JS对象得到变化的部分,然后把这个差异应用到原来的Dom树上,从而达到更新UI的目的,这就是“数据驱动”的原理。

小程序的渲染层和逻辑层分别在两个线程中运行,所以setData传递数据实际是一个异步的过程,所以setData的第二个参数是一个callback回调,在这次setData对界面渲染完毕后触发。
setData其一般调用格式是 setData(data, callback),其中data是由多个key: value构成的Object对象。

还需注意:

  1. 直接修改 Page实例的this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致。
  2. 由于setData是需要两个线程的一些通信消耗,为了提高性能,每次设置的数据不应超过1024kB。
  3. 不要把data中的任意一项的value设为undefined,否则可能会有引起一些不可预料的bug。

2.渲染层与逻辑层

小程序的JS脚本是运行在JsCore的线程里,小程序的每个页面各自有一个WebView线程进行渲染,所以小程序切换页面时,小程序逻辑层的JS脚本运行上下文依旧在同一个JsCore线程中。

【注意】所有页面的脚本逻辑都跑在同一个JsCore线程,页面使用setTimeout或者setInterval的定时器,然后跳转到其他页面时,这些定时器并没有被清除,需要开发者自己在页面离开的时候进行清理。

 3.生命周期(onLoad, onShow, onReady, onHide, onUnload)

页面初次加载的时候,微信客户端就会给Page实例派发onLoad事件,Page构造器参数所定义的onLoad方法会被调用,onLoad在页面没被销毁之前只会触发1次,在onLoad的回调中,可以获取当前页面所调用的打开参数option,关于打开参数我们放在这一节的最后再展开阐述。
页面显示之后,Page构造器参数所定义的onShow方法会被调用,一般从别的页面返回到当前页面时,当前页的onShow方法都会被调用
在页面初次渲染完成时,Page构造器参数所定义的onReady方法会被调用,onReady在页面没被销毁前只会触发1次,onReady触发时,表示页面已经准备妥当,在逻辑层就可以和视图层进行交互了。
以上三个事件触发的时机是:onLoad早于 onShow,onShow早于onReady

页面不可见时,Page构造器参数所定义的onHide方法会被调用,这种情况会在使用wx.navigateTo切换到其他页面、底部tab切换时触发。
当前页面使用wx.redirectTo或wx.navigateBack返回到其他页时,当前页面会被微信客户端销毁回收,此时Page构造器参数所定义的onUnload方法会被调用。

在列表页打开商品详情页时把商品的id传递过来,详情页通过刚刚说的onLoad回调的参数option就可以拿到商品id,从而绘制出对应的商品,代码如代码清单3-9所示。

// pages/list/list.js
// 列表页使用navigateTo跳转到详情页
wx.navigateTo({ url: 'pages/detail/detail?id=1&other=abc' })

// pages/detail/detail.js
Page({
  onLoad: function(option) {
        console.log(option.id)
        console.log(option.other)
  }
})

4.用户行为

  • 下拉刷新 onPullDownRefresh

监听用户下拉刷新事件,需要在app.json的window选项中或页面配置page.json中设置enablePullDownRefresh为true。当处理完数据刷新后,wx.stopPullDownRefresh可以停止当前页面的下拉刷新。

  • 上拉触底 onReachBottom

监听用户上拉触底事件。可以在app.json的window选项中或页面配置page.json中设置触发距离onReachBottomDistance。在触发距离内滑动期间,本事件只会被触发一次。

  • 页面滚动 onPageScroll

监听用户滑动页面事件,参数为 Object,包含 scrollTop 字段,表示页面在垂直方向已滚动的距离(单位px)。

  • 用户转发 onShareAppMessage

只有定义了此事件处理函数,右上角菜单才会显示“转发”按钮,在用户点击转发按钮的时候会调用,此事件需要return一个Object,包含title和path两个字段,用于自定义转发内容,如代码清单3-13所示。

// page.js
Page({
onShareAppMessage: function () {
 return {
   title: '自定义转发标题',
   path: '/page/user?id=123'
 }
}
})

5.导航与tabBar

使用 wx.navigateTo({ url: 'pageD' }) 可以往当前页面栈多推入一个 pageD,此时页面栈变成 [ pageA, pageB, pageC, pageD ]。
使用 wx.navigateBack() 可以退出当前页面栈的最顶上页面,此时页面栈变成 [ pageA, pageB, pageC ]。
使用wx.redirectTo({ url: 'pageE' }) 是替换当前页变成pageE,此时页面栈变成 [ pageA, pageB, pageE ],当页面栈到达10层没法再新增的时候,往往就是使用redirectTo这个API进行页面跳转。

{
  "tabBar": {
    "list": [
      { "text": "Tab1", "pagePath": "pageA" },
      { "text": "Tab1", "pagePath": "pageF" },
      { "text": "Tab1", "pagePath": "pageG" }
    ]
  }
}

在上面的例子所在的页面栈中使用wx.switchTab({ url: 'pageF' }),此时原来的页面栈会被清空(除了已经声明为Tabbar页pageA外,其他页面会被销毁),然后会切到pageF所在的tab页面,页面栈变成 [ pageF ],此时点击Tab1切回到pageA时,pageA不会再触发onLoad,因为pageA没有被销毁。
【注意】wx.navigateTo和wx.redirectTo只能打开非TabBar页面,wx.switchTab只能打开Tabbar页面。


我们还可以使用 wx. reLaunch({ url: 'pageH' }) 重启小程序,并且打开pageH,此时页面栈为 [ pageH ]。

路由方式触发时机路由前页面生命周期路由后页面生命周期
初始化 小程序打开的第一个页面   onLoad, onShow
打开新页面 调用 API wx.navigateTo onHide onLoad, onShow
页面重定向 调用 API wx.redirectTo onUnload onLoad, onShow
页面返回 调用 API wx.navigateBack onUnload onShow
Tab 切换 调用 API wx.switchTab 参考下表 参考下表
重启动 调用 API wx.reLaunch onUnload onLoad, onShow

Tab 切换对应的生命周期(以 A、B 页面为 Tabbar 页面,C 是从 A 页面打开的页面,D 页面是从 C 页面打开的页面为例)

当前页面路由后页面触发的生命周期(按顺序)
A A
A B A.onHide(), B.onLoad(), B.onShow()
A B(再次打开) A.onHide(), B.onShow()
C A C.onUnload(), A.onShow()
C B C.onUnload(), B.onLoad(), B.onShow()
D B D.onUnload(), C.onUnload(), B.onLoad(), B.onShow()
D(从转发进入) A D.onUnload(), A.onLoad(), A.onShow()
D(从转发进入) B D.onUnload(), B.onLoad(), B.onShow()

 

6.事件绑定,捕获与冒泡

事件绑定的写法:

  • 以bind或者catch开头,然后跟上事件的类型,如bindtap、catchtouchstart。自基础库版本1.5.0起,bind和catch后可以紧跟一个冒号,其含义不变,如bind:tap、catch:touchstart。同时bind和catch前还可以加上capture-来表示捕获阶段。
  • value是一个字符串,需要在对应的页面Page构造器中定义同名的函数。
  • bind和capture-bind的含义分别代表事件的冒泡阶段和捕获阶段,其触发的顺序如下图所示。

常见的事件类型

类型触发条件
touchstart 手指触摸动作开始
touchmove 手指触摸后移动
touchcancel 手指触摸动作被打断,如来电提醒,弹窗
touchend 手指触摸动作结束
tap 手指触摸后马上离开
longpress 手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发
longtap 手指触摸后,超过350ms再离开(推荐使用longpress事件代替)
transitionend 会在 WXSS transition 或 wx.createAnimation 动画结束后触发
animationstart 会在一个 WXSS animation 动画开始时触发
animationiteration 会在一个 WXSS animation 一次迭代结束时触发
animationend 会在一个 WXSS animation 动画完成时触发
posted @ 2019-06-08 21:13  cecelia  阅读(412)  评论(0编辑  收藏  举报