全局对象

在小程序中,一个应用由多个页面组成,一个页面由多个组件组成。

app.js就是用来定义全局配置对象, 全局数据对象,全局回调,全局样式及import所有页面。

app.js外表上看来是一个React组件

  • 全局配置对象 config 配置标题栏与tab栏

  • 全局数据对象 globalData

  • 全局回调

    • onGlobalLoad 每个页面在初次加载时就会执行此回调,注意不存在页面级别的onLoad方法
    • onGlobalReady 每个页面在初次渲染后(布局完成)就会执行此回调,注意不存在页面级别的onReady方法
    • onGlobalUnload 每个页面在被销毁时就会调用此方法,注意不存在页面级别的onUnload方法, 其次路由切换导致当前页面隐藏时,页面不一定销毁,只有此页面被踢出页面栈时才会销毁。页面栈一共保存10个页面. 想用页面级别的onUnload方法,可以用componentWillUnmount代替。
    • onGlobalShow 每个页面在显示时就会调用此方法,页面有onShow方法时,也会同时执行此方法
    • onGlobalHide 每个页面在隐藏时就会调用此方法,页面有onHide方法时,也会同时执行此方法
    • onGlobalShare 只有页面组件没有定义onShare/onShareAppMessage方法,才会调用此方法,此方法要求返回对象
    • onCollectLogs 所有click/tap/change/input/blur等核心的与用户行为相关的事件触发时,都会调用这个回调
    • onSendLogs onCollectLogs理应凑够一定数量的日志就会调用此方法,用于上传日
  • 全局样式 自己手动import 'app.scss'import 'app.less'

  • import 所有以 ./pages/ 开头的依赖放到 app.jsonpages 配置项中。

  • 默认我们会把 第一个./pages开头的依赖当作首页

此外,app.js还支持原生的onLaunch, onError, onShow, onHide。

其中onShow, onHide不等同于onGlobalShow, onGlobalHide, 前两者是小程序从前台进入后台或从后台进入前台触发的, 后两者是页面级别的监听方法。由于快应用不支持应用级别的onShow方法,因此不要使用。

在快应用下,它没有onLaunch, onHide, 娜娜奇会在自动转译成 onCreate、onDestroy方法。

  1. import React from '@react';
  2. import './pages/index/index'; //引入所有页面。
  3. import './pages/demo/base/index';
  4. import './pages/demo/native/index/index';
  5. import './app.less';
  6. class Global extends React.Component {
  7. //全局配置
  8. config = {
  9. window: {
  10. backgroundTextStyle: 'light',
  11. navigationBarBackgroundColor: '#0088a4',
  12. navigationBarTitleText: 'mpreact',
  13. navigationBarTextStyle: '#fff'
  14. }
  15. };
  16. // 全局数据
  17. globalData = {
  18. ufo: 'nanachi',//only test
  19. __storage: {} //快应用的storage在这里保存一份副本
  20. };
  21. onGlobalLoad(){}
  22. onGlobalReady(){}
  23. onGlobalUnload(){}
  24. onGlobalShow(){}
  25. onGlobalHide(){}
  26. onGlobalShare(){
  27. return {};
  28. }
  29. onCollectLogs(){}
  30. onHide(){
  31. var app = React.getApp()
  32. console.log(app == this)//由于平台的差异性,React.getApp()得到的对象不定是new App的实例
  33. }
  34. onGlobalLoad(){
  35. //快应用需要在每个页面打开的瞬间初始化同步storage API
  36. //即getStorageSync, setStorageSync, removeStorageSync, clearStorageSync
  37. let ANU_ENV = process.env.ANU_ENV;
  38. if ( ANU_ENV === 'quick' ) {
  39. React.api.initStorageSync &&
  40. React.api.initStorageSync(this.globalData.__storage)
  41. }
  42. }
  43. onLaunch() {
  44. let ANU_ENV = process.env.ANU_ENV;
  45. if ( ANU_ENV === 'quick' ) { //非快应用的平台在编译阶段会被干掉
  46. if ( this.$data && typeof global === 'object') { //针对快应用的全局getApp补丁
  47. var ref = Object.getPrototypeOf(global) || global;
  48. var _this = this;
  49. ref.getApp = function() {
  50. return _this;
  51. };
  52. this.globalData = this.$def.globalData;
  53. }
  54. }
  55. console.log('App launched');
  56. }
  57. }
  58. export default App(new Global());

globalData的设计

在我们公司,globalData会将登录信息(微信的getUserInfo, 里面有openId什么),页面的参数, 场景值全部缓存起来,这样以后大家直接访问React.getApp().globalData就能拿到,建议用户们可以模仿。

  1. //app.js
  2. globalData = {
  3. systemInfo: {},
  4. // 页面渲染时间
  5. _timestamp: 0,
  6. // 页面留存时间
  7. _staytime: 0,
  8. _startimestamp: 0,
  9. location: {},
  10. // 外链带入渠道
  11. bd_origin: '',
  12. // 小程序内部渠道,路由跳转会自动替换
  13. hd_origin: '',
  14. scene: '',
  15. logs: [] //日志, 满10条就会自动发送后台
  16. };
  17. onLaunch(e) {
  18. this.globalData.scene = e.scene
  19. if(process.env.ANU_ENV === 'quick') {
  20. this.onLaunchQuick(e);
  21. }
  22. this.onLaunchNormal(e);
  23. }
  24. onHide(){
  25. this.globalData._staytime = Data.now - this.globalData._startimestamp
  26. }
  27. async onLaunchNormal(e) {
  28. // 统计总体停留时长
  29. this.globalData._startimestamp = +new Date();
  30. // 这里要把系统信息放到全局 方便日志收集 业务线调用时要使用util下的getSystemInfo
  31. React.api.getSystemInfo({
  32. success: res => {
  33. this.globalData.systemInfo = res;
  34. }
  35. });
  36. }
  37. onLaunchQuick(e) {
  38. //针对快应用的全局getApp补丁
  39. if (this.$data && typeof global === 'object') {
  40. var ref = Object.getPrototypeOf(global) || global;
  41. var _this = this;
  42. this.globalData = this.$def.globalData || {};
  43. ref.getApp = function() {
  44. return _this;
  45. };
  46. }
  47. // 统计总体停留时长
  48. this.globalData._startimestamp = +new Date();
  49. React.api.getSystemInfo({
  50. success: res => {
  51. this.globalData.systemInfo = res;
  52. }
  53. });
  54. // 拿openId 更新token
  55. user.appLanchInfos();
  56. // 获取地理位置 埋点所需 百度账号未登录会报错
  57. React.api.getLocation({
  58. success: (res) => {
  59. this.globalData.location = {
  60. lat: res.latitude,
  61. lgt: res.longitude
  62. };
  63. }
  64. });
  65. // 将bd_origin存到全局变量内
  66. const scene = this.globalData.scene;
  67. if (e.query) {
  68. // 缓存初始的bdo
  69. this.globalData.bd_origin = e.query.bd_origin || '';
  70. this.globalData.hd_origin = e.query.hd_origin || '';
  71. }
  72. }

React.getApp()的使用场合

React.getApp()必须放在app.js 或页面组件或普通组件的生命周期钩子里面执行,不要放在全局作用域下执行

快应用可以这样设置跨页面的全局数据 this.$app.$data = {a:1}

其他配置项统一放在config对象中,详细配置列表参见这里

nanachi