04小程序逻辑层App() ,Page() 中的生命周期函数 和 页面路由(页面栈 )

小程序 逻辑层 概述:

小程序开发框架的逻辑层使用 JavaScript 引擎为小程序提供开发者 JavaScript 代码的运行环境以及微信小程序的特有功能。

逻辑层将数据进行处理后发送给视图层,同时接受视图层的事件反馈。

开发者写的所有代码最终将会打包成一份 JavaScript 文件,并在小程序启动的时候运行,直到小程序销毁。这一行为类似 ServiceWorker,所以逻辑层也称之为 App Service。

在 JavaScript 的基础上,我们增加了一些功能,以方便小程序的开发:

  • 增加 App 和 Page 方法,进行程序注册页面注册
  • 增加 getApp 和 getCurrentPages 方法,分别用来获取 App 实例和当前页面栈。
  • 提供丰富的 API,如微信用户数据,扫一扫,支付等微信特有能力。
  • 提供模块化能力,每个页面有独立的作用域

注意:小程序框架的逻辑层并非运行在浏览器中,因此 JavaScript 在 web 中一些能力都无法使用,如 windowdocument 等。

app.js 中 APP方法:  

每个小程序都需要在 app.js 中调用 App 方法注册小程序实例,绑定生命周期回调函数、错误监听和页面不存在监听函数等。

下面我们看 App() 里所绑定的 生命周期 方法,

1,onLaunch(options):

调用时机:小程序被加载完毕的时候调用。这个方法一般用来做一些初始化的事情。比如获取用户信息、获取历史缓存信息、获取小程序打开来源等。

参数:

| 参数 | 类型 | 说明 |
| path | String | 打开小程序的路径 |
| query | Object | 打开小程序的query |
| scene | Number | 打开小程序的场景值 |
| shareTicket | String | shareTicket,详见 获取更多转发信息 |
| referrerInfo | Object | 当场景为由从另一个小程序或公众号或App打开时,返回此字段 |
| referrerInfo.appId | String | 来源小程序或公众号或App的 appId,详见下方说明 |
| referrerInfo.extraData | Object | 来源小程序传过来的数据,scene=1037或1038时支持 |

这就是onLauch()  当小程序 被加载完毕之后,就会执行它,    

2,onShow(options):

调用时机:小程序启动,或从后台进入前台显示时调用

如果想要在小程序每次进入到前台的时候都执行一些事情,那么可以把代码放在这个里面。比如一些实时动态更改的数据,用户每次进来都要从服务器更新,那么我们就可以在这个里面做。
参数:同onLaunch  。

onShow 和  onLaunch  的区别:

onShow可能被调用多次, onLauch 调用一次,  

3, onHide():

调用时机:小程序被切换到后台(包括微信自身被切换到后台或者小程序暂时被切换到后台时)。可以在这个方法中做一些数据的保存


参数:无。


4, onError(String error):


调用时机:小程序发生脚本错误,或者 api 调用失败时触发。

在小程序发生错误的时候,会把错误信息发送到这个函数中,所以可以在这个函数中做一些错误收集
参数:error。

getApp() 函数:

获取当前的app对象。一般在其他的page页面中调用。有以下两个注意点:

  1. 不要在定义于 App() 内的函数中调用 getApp() ,使用 this 就可以拿到 app 实例。
  2. 通过 getApp() 获取实例之后,不要私自调用生命周期函数。

具体页面.js  中的Page方法 :

Page(Object)函数用来注册一个页面。接受一个 Object 类型参数,其指定页面的初始数据生命周期回调事件处理函数  等。

数据渲染: 

在 模板中需要使用  的数据,需要放在  Page 中的对象的  data属性中,

如果以后想要修改data中的值,应该使用setData方法。setData函数用于将数据从逻辑层发送到视图层(异步),同时改变对应的 this.data 的值(同步)。

注意事项: 

  1. 直接修改 this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致。
  2. 放到data中的值,只能使用可以JSON序列化的:字符串,数字,布尔值,对象,数组。否则将不会渲染(例如函数不可以被序列化)。
  3. 其中key可以以数据路径的形式给出,支持改变数组中的某一项或对象的某个属性,如 array[2].messagea.b.c.d,并且不需要在 this.data中预先定义。 

有关于上面的第3条:  

修改后的效果:

 可以 直接这样修改, 比较方便!!!  但是对于比较复杂的数据修改还是要 采用 先将 data 取出来 ,然后再修改,  

补充:

上面的代码实现的是 每次点击都将 获取全局 globalData中的数字,然后使用,最后加1并写入 全局data 中!  

Page() 方法中 的生命周期函数  : 

它们的调用顺序:

onLoad   ,onShow , onReady  

如果切入后台,就会调用 onHide 

如果切入前台,就又会调用onShow 

onLoad(Object query):

它类似于  App ()  方法 中的 onLaunch() 方法,   

页面加载时触发。一个页面只会调用一次,可以在 onLoad的参数中获取打开当前页面路径中的参数。一般建议在这个函数中做一些页面的数据初始化工作。

onShow():

页面显示/切入前台时触发。比如新推入了一个新的页面,那么原来的页面就处于后台,这时候如果把新页面又移除掉,那么下面的页面就会调用onShow方法。

onReady():

页面初次渲染完成时触发。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互了

对界面内容进行设置的 API 如wx.setNavigationBarTitleText,比较合适在这个里面执行。

onHide()

页面隐藏/切入后台时触发。如navigateTo或底部tab切换到其他页面,小程序切入后台等。

onUnload()

页面卸载时触发。

redirectTonavigateBack到其他页面时。

一开始跳转到一个页面,然后从该页面返回后  ,就会卸载该页面    

页面路由: 

在小程序中所有页面的路由全部由框架进行管理。

框架以栈的形式维护了当前的所有页面。

当发生路由切换的时候,页面栈的表现如下:

路由方式页面栈表现
初始化 新页面入栈
打开新页面 新页面入栈
页面重定向 当前页面出栈,新页面入栈
页面返回 页面不断出栈,直到目标返回页
Tab 切换 页面全部出栈,只留下新的 Tab 页面
重加载 页面全部出栈,只留下新的页面

开发者可以使用 getCurrentPages() 函数获取当前页面栈  数组  。

getCurrentPages 的使用:  

我们在跳转 过去的页面的js中  打印 pageStack:

getCurrentPages 的实际 使用:  

主要思路就是通过 getCurrentPages() 获取到page 对象,然后就可以获取它里面的 data 数据,并可以将操作后的数据 setData() 回去, 

发布微博案例:  

代码:

1 <view wx:for="{{contents}}">{{item}}</view>
2 
3 <button bindtap="onClickEvt">去发微博</button>
weibo_list.wxml
 1 /* pages/weibo_list/weibo_list.wxss */
 2 view{
 3   height: 80rpx;
 4   line-height: 80rpx;
 5   border-bottom: 1px solid #f00;
 6 
 7 
 8 }
 9 
10 button{
11   margin-top: 50rpx;
12 
13 }
weibo_list.wxss
 1 // pages/weibo_list/weibo_list.js
 2 Page({
 3 
 4   /**
 5    * 页面的初始数据
 6    */
 7   data: {
 8     contents:["Talk is cheap,show me code","To be or not to be is a question"]
 9   },
10 
11   /**
12    * 生命周期函数--监听页面加载
13    */
14   onLoad: function (options) {
15 
16   },
17   onClickEvt:function(){
18     wx.navigateTo({
19       url: '/pages/fabu/fabu',
20     })
21 
22   }
23 })
weibo_list.js
1 <!--pages/fabu/fabu.wxml-->
2 <view>
3   <form bindsubmit="onSubmitEvt">  
4     <textarea name="content" placeholder="请在此处输入你要发布的内容"></textarea>
5     <button form-type="submit">提交</button>
6   </form>
7 </view>
fabu.wxml
 1 // pages/fabu/fabu.js
 2 Page({
 3 
 4   /**
 5    * 页面的初始数据
 6    */
 7   data: {
 8   },
 9 
10   /**
11    * 生命周期函数--监听页面加载
12    */
13   onLoad: function (options) {
14 
15   },
16   onSubmitEvt:function(evt){
17     var content = evt.detail.value.content;  
18     // 然后将 content 设置到上个页面中去,  
19 
20     var page_stacks = getCurrentPages();
21     var pre_idx = page_stacks.length - 2;  
22     
23     // 获取到 上个page  
24     var page = page_stacks[pre_idx];   
25     var contents = page.data.contents; 
26     contents.push(content);  
27     page.setData({contents:contents});  
28     
29     wx.navigateBack({ });  
30 
31   }
32 
33 
34 
35 
36 })
fabu.js

form 表单提交:

这里有关的 form 表单的提交:  

 都要有,  这样,当点击 提交的时候,数据才会以key-value 的形式保存起来, key的名字是 name 的值!!! 

原文地址:https://www.cnblogs.com/zach0812/p/12264354.html