uni-app的h5页面的onHide/onUnload方法不触发的问题解决

背景

  • 目的:对h5页面进行埋点过程中,需要对页面浏览时长进行统计,通过生命周期的监听上传埋点日志
  • 预设方案:通过个页面的onShow/onHide/onUnload生命周期对页面的展示/隐藏/销毁进行监听
  • 问题:仅在首页正常触发生命周期,通过跳转进入的其他页面的onShow正常触发,onHide与onUnload不触发

解决过程

  • 推测原因:通过路由跳转的页面属于二级页面,而onHide与onUnload生命周期仅在一级页面中存在

解决方法

  • 二级页面:
    • onShow:正常使用该生命周期监听页面显示,包括后台进前台与路由跳转进入
    • destroyed:用组件生命周期代替onHide与onUnload,监听路由跳转离开
  • app.vue:
    • onHide:应用生命周期对整个应用的前台进入后台进行监听,通过url区分不同页面的埋点日志上传

示例代码

// 一级页面-首页
onShow() {
    this.$$DI.track('enter_page', {
        page_name: '首页'
    })
},
onHide() {
    this.$$DI.track('leave_page', {
        page_name: '首页'
    })
},
onUnLoad() {
    this.$$DI.track('leave_page', {
        page_name: '首页'
    })
},


// 二级页面
onShow() {
    this.$$DI.track('enter_page', {
        page_name: 'a页面'
    })
},
destroyed() {
    this.$$DI.track('leave_page', {
        page_name: 'a页面'
    })
}


// app.vue
onHide() {
    let page_name
    // 根据需要监听的页面路由进行判断添加
    if(window.location.href.includes('basic')) page_name = 'a页面'
    if(page_name) {
        this.$$DI.track('leave_page', {
            page_name
        })
    }
},
### Uniapp 生命周期详解 #### 1. **应用生命周期** 应用级别的生命周期主要涉及整个应用程序的状态变化,这些方法在整个应用运行期间只会触发特定次数。 - `onLaunch` 当 uni-app 初始化完成时触发,这是应用的入口函数,且仅在应用首次启动时调用一次[^1]。 - `onShow` 当 uni-app 启动或者从后台切换至前台显示时触发。此方法可能多次调用,因为用户可以在同场景间切换[^2]。 - `onHide` 当 uni-app 进入后台时触发。例如,当用户按下 Home 键或将应用最小化时,这个方法会被调用[^2]。 --- #### 2. **页面生命周期** 页面级别生命周期主要用于管理单个页面的行为和状态,以下是常见的页面生命周期及其执行顺序: - `onInit` 页面初始化时触发,其参数与 `onLoad` 的参数相同,通常用于接收上一页面传递的数据。需要注意的是,`onInit` 是小程序特有的生命周期,在部分平台(如 H5)可能会生效。 - `onLoad` 页面加载时触发,此时可以获取到通过 URL 或其他方式传递给页面的参数。这是一个非常重要的生命周期,常用来处理页面初始数据请求[^1]。 - `onShow` 页面每次展示时都会触发,无论是第一次打开还是从其他页面返回当前页面时。它适用于需要频繁刷新或更新界面的情况[^2]。 - `onReady` 页面初次渲染完成后触发。如果页面渲染速度较快,则可能会在页面进入动画完成前就触发该事件。 - `onHide` 页面隐藏时触发,比如跳转到另一个页面或点击返回按钮离开当前页面时。 - `onUnload` 页面卸载时触发,表示页面即将被销毁。在此处可清理一些资源或保存临时数据。 --- #### 3. **组件生命周期** 组件级别的生命周期则专注于 Vue.js 驱动下的组件行为控制,具体如下: - `beforeCreate` 在实例初始化之后立即调用,此时还未开始解析模板、挂载 DOM 和设置响应式数据[^2]。 - `created` 完成实例创建后立刻调用,此时已经完成了选项配置和数据观测,但尚未挂载到真实 DOM 上[^2]。 - `beforeMount` 开始挂载过程之前调用,此时模板已经被编译为虚拟 DOM 树,但还没有将其渲染到实际页面中[^2]。 - `mounted` 组件成功挂载到实例并插入父容器节点后调用。需注意,这里无法保证所有子组件都已经完成挂载;若依赖子组件完全挂载后的逻辑,应考虑使用 `$nextTick()` 方法- `beforeUpdate` 数据发生改变而引发视图重新渲染的过程中调用,发生在虚拟 DOM 更新之前。 - `updated` 虚拟 DOM 已经完成更新并反映到了真实的 DOM 中时调用。适合做某些基于最新 DOM 结构的操作。 - `beforeDestroy` 实例销毁之前的最后一个周期钩子,仍能访问完整的实例对象及属性。 - `destroyed` 实例彻底销毁后调用,意味着所有的指令绑定已解除,所有事件监听器已被移除,所有子实例也被销毁[^2]。 --- #### 4. **综合执行顺序** 根据以上分析,Uniapp 的整体生命周期执行顺序总结如下: ```plaintext 应用生命周期 -> 页面生命周期 -> 组件生命周期 ``` 具体的流程为: 1. 应用层面:`onLaunch` → `onShow` 2. 页面层面:`onLoad` → `onShow` → `onReady` 3. 组件层面:`beforeCreate` → `created` → `beforeMount` → `mounted` 最终形成的整体顺序为: ```plaintext onLaunch ----> onShow ----> beforeCreate (组件) ----> created (组件) ----> onLoad (页面) ----> onShow (页面) ----> mounted (组件) ----> onReady (页面) ``` --- ### 示例代码 以下是一个简单的示例,展示了如何利用生命周期打印日志以便调试: ```javascript // App.vue 文件中的应用生命周期 export default { onLaunch() { console.log('App Launch'); }, onShow() { console.log('App Show'); }, onHide() { console.log('App Hide'); } }; // Page.vue 文件中的页面生命周期 export default { data() { return {}; }, onLoad(options) { console.log('Page Load', options); }, onShow() { console.log('Page Show'); }, onReady() { console.log('Page Ready'); }, onHide() { console.log('Page Hide'); }, onUnload() { console.log('Page Unload'); } }; ``` ---
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值