微信小程序学习笔记四 之小程序宿主环境

渲染层和逻辑层

  1. 渲染 “Hello World” 页面

    WXML 模板使用 view标签,其子节点用 {{}}的语法绑定一个 msg 的变量

    <view>{{msg}}</view>
    

    在 JS 脚本使用 this.setData方法把 msg 字段设置成"Hello World"

    Page({
        onLoad:function(){
            this.setData({{msg:'Hello World'}})
        }
    })
    
    • 渲染层与数据相关
    • 逻辑层负责产生、处理数据
    • 逻辑层通过 Page实例的 setData方法传递数据到渲染层
  2. 通信模型

    在这里插入图片描述

  3. 数据驱动

    WXML 结构实际上等价于一棵 Dom 树,通过一个 JS 对象也可以来表达 Dom 树的结构

在这里插入图片描述

WXML 可先转成 JS 对象,然后再渲染出真正的 Dom 树,回到 “Hello World”

setData更新 msg数据,产生的 JS 对象对应的节点会发生变化,此时可对比前后两个JS对象得到变化的部分,然后把这个差异应用到原来的 Dom 树上,从而达到更新 UI 的目的,"数据驱动"的原理

在这里插入图片描述

  1. 双线程下的界面渲染
    • 渲染层,宿主环境把WXML转化成对应的JS对象,

    • 逻辑层发生数据变更的时候,通过宿主环境提供的setData方法把数据从逻辑层传递到渲染层,

    • 经过前后对比差异,把差异应用在原来的Dom树上,渲染出正确的UI界面

    在这里插入图片描述

程序和页面

逻辑组成,一个小程序由多个"页面"组成的"程序"

程序

  1. 程序构造器App()
    • App() 构造器必需写在项目根目录的 app.js 中,

    • 获取App实例(单例对象)

      //other.js
      var appInstance = getApp()
      
    • APP 构造器

      App({
          onLaunch:function(options) {},
          onShow:function(options){},
          onHide:function() {},
          onError:function(msg) {},
          globalData: 'I am global data'
      })
      
      参数属性类型描述
      onLaunchFunction小程序初始化完成时,会触发onLaunch(全局触发一次)
      onShowFunction小程序启动后,或从后台进入前台显示,触发
      onHideFunction小程序从前台进入后台,触发
      onErrorFunction发生脚本错误,或API调用失败,触发并带上错误信息
      其他字段任意添加任意函数或数据到Object参数中,在App实例回调用this可访问
  2. 程序的生命周期和打开场景

    App的生命周期是由微信客户端根据用户操作主动触发

    微信客户端打开小程序有很多途径,微信客户端会将打开方式带给 onLaunch 和 onShow 的调用参数options

    最新打开场景

    字段类型描述
    pathString打开小程序的页面路径
    queryObject页面参数
    sceneNumber场景值
    shareTicketString
    referrerInfoObject场景为从另一小程序或公众号打开时,返回此字段
    referrerInfo.appIdString来源小程序或公众号或App的appId
    referrerInfo.extraDataObject来源小程序传来的数据,scene=1037或1038时支持

    以下场景支持返回 referrerInfo.appId

    场景值场景appId 信息含义
    1020公众号profile页相关小程序列表,返回来源公众号appId
    1035公众号自定义菜单返回来源公众号 appId
    1036App 分享消息卡片返回来源应用 appId
    1037小程序打开小程序返回来源小程序 appId
    1038从另一小程序返回返回来源小程序 appId
    1043公众号模板消息返回来源公众号 appId
  3. 小程序全局数据

    共享全局数据

    App({
        globalData:'I am global data' //全局共享数据
    })
    // 其他页面脚本 other.js
    var appInstance = getApp()
    console.log(appInstance.globalData)
    

    【注】页面逻辑都跑在同一个JsCore 线程,页面使用 定时器,然后跳转至其他页面时,这些定时器并未被清除,需要开发者在页面离开的时候进行清理

页面

  1. 文字构成和路径

    页面构成:界面(wxml,wxss),配置(json),逻辑(js),页面文件需要放置在同一目录下

    页面路径需要在小程序代码根目录 app.json 中的 pages 字段声明,否则此页面不会被注册至宿主环境中,默认 pages 字段的第一个页面为首页

  2. 页面构造器 Page()
    Page({
        data:{text:"This is page data."},
        //当前页面WXML模板中可用来做数据绑定的初始数据
        onLoad: function(options) { },
        onReady: function() { },
        onShow: function() { },
        onHide: function() { },
        onUnload: function() { },
        onPullDownRefresh: function() { },
        onReachBottom: function() { },
        onShareAppMessage: function() { },
        onPageScroll: function() { }
    })
    

    Page 构造器参数

    参数属性类型描述
    dataObject页面初始数据
    onLoadFunction生命周期函数–监听页面加载,触发时机早于onShow和onReady
    onReadyFunction生命周期函数–监听页面初次渲染完成
    onShowFunction生命周期函数–监听页面显示,触发事件早于onReady
    onHideFunction生命周期函数–监听页面隐藏
    onUnloadFunction生命周期函数–监听页面卸载
    onPullDownRefreshFunction页面相关事件处理函数–监听用户下拉动作
    onReachBottomFunction页面上拉触底事件的处理函数
    onShareAppMessageFunction用户点击右上角转发
    onPageScrollFunction页面滚动触发事件的处理函数
    其他Any可添加任意的函数或数据,在Page实例的其他函数中用this可访问
  3. 页面的生命周期和打开参数

    页面打开参数构造器

    //pages/list/list.js
    //页面使用 navigate To 跳转到详情页
    wx.navigateTo({url:'pages/detail/detail?id=1&other=abc'})
    
    //pages/detail/detail.js
    Page({
        onLoad:function(option){
            console.log(option.id)
            xonsole.log(option.other)
        }
    })
    

    小程序把页面的打开路径定义成页面URL,其组成格式和网页的URL类似,在页面路径后使用英文 ? 分隔path和query部分,query部分的多个参数使用 & 进行分隔,参数的名字和值使用 key=value 的形式声明。在页面Page构造器里onLoad的option可以拿到当前页面的打开参数,其类型是一个Object,其键值对与页面URL上query键值对一一对应。和网页URL一样,页面URL上的value如果涉及特殊字符(例如:&字符、?字符、中文字符等,详情参考URI的RFC3986说明 ),需要采用UrlEncode后再拼接到页面URL

  4. 页面的数据

    data 参数是页面第一次渲染时从逻辑层传递到渲染层的数据

    <!--page.wxml-->
    <view>{{text}}</view>
    <view>{{text}}</text>
    
    //page.js
    Page({
        data:{
            text:'init data',
            array:[{msg:'1'},{msg:'2'}]
        }
    })
    

    宿主环境所提供的Page实例的原型中有 setData 函数,可在Page实例下的方法调用this.setData把数据传递给渲染层,从而更新界面。小程序的逻辑层和渲染层分别在两个线程中运行,setData传递数据是一个异步的过程

    setData(data,callback)

    // page.js
    Page({
        onLoad:function(){
            this.setData({
                text:'change data'
            },function(){
                //在这次 setData 对界面渲染完毕后触发
            })
        }
    })
    
    • 直接修改Page实例的this.data而不调用this.setData无法改变页面状态,还会导致数据不一致;

    • 由于setData是需要两个线程的一些通信消耗,为了提高性能,每次设置的数据不应超过1024kb

    • 不要把data中的任意一项的value设为undefined,否则可能引起不可预料的bug

    • 每次设置只需更改最小单位数据

      //page.js
      Page({
          data:{
              a:1,b:2,c:3,
              d:[1,{text:'Hello'},3,4]
          }
          onLoad:function(){
          //a需要变化时,只需要setData设置a字段即可
          this.setData({a:2})
      }
      })
      
  5. 页面的用户行为
    • 下拉刷新 onPullDownRefresh

      //app.json的window选项 或 page.json
      enablePullDownRefreah:true
      处理完数据刷新后,wx.stopPullDownRefresh可停止当前页面下拉刷新
      
    • 上拉触底 onReachBottom

      onReachBottomDistance设置触发距离, 在触发距离内滑动期间,本事件只会被触发一次

    • 页面滚动 onPageScroll

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

    • 用户转发 onShareAppMessage

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

    一个小程序拥有多个页面,我们可以通过wx.navigateTo推入一个新的页面

    页面栈 [pageA,pageB,pageC],pageA在底部

    使用wx.navigateTo({url:'pageD'})可往当前页面栈多推入一个pageD,此时页面栈为[pageA,pageB,pageC,pageD]

    wx.navigateBack()可退出当前页面栈的最顶上页面,[pageA,pageB,pageC]

    wx.redirectTo({url:'pageE'})是替换当前页面为 pageE,[pageA,ageB,pageE]

    {
        "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.navigateTowx.redirectTo只能打开非TabBar页面wx.switchTab只能打开Tabbar页面。
    使用 wx. reLaunch({ url: 'pageH' })重启小程序,并且打开pageH,此时页面栈为 [ pageH ]。

    页面路由触发方式及页面生命周期的对应关系

    路由方式触发时机路由当前页面生命周期路由后页面生命周期
    初始化小程序打开的第一个页面onLoad,onShow
    打开新页面 调用API wx.navigateToonHideonLoad,onShow
    页面重定向 调用API wx.redirectToonUnloadonLoad,onShow
    页面返回 调用API wx.navigateBackonUnloadonShow
    Tab切换 调用 API wx.switchTab
    重启动调用 API wx.reLaunchonUnloadonLoad,onShow

    Tab 切换对应的生命周期(),Tabbar 页面初始化后不会被销毁

    当前页面路由后页面触发的生命周期
    AA
    ABA.onHide(),B.onLoad(),B.onShow()
    AB(再次打开)A.onHide(),B.onShow()
    CAC.onUnload(),A.onShow()
    CBC.onUnload(),B.onLoad(),B.onShow()
    DBD.onUnload(),C.onUnload(),B.onLoad(),B.onShow()
    D(从转发进入)AD.onUnload(),A.onLoad(),A.onShow()
    D(从转发进入)BD.onUnload(),B.onLoad(),B.onShow()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值