小程序中wx.request在tabbar中的onload生命周期不触发的问题

本文解析了微信小程序中onLoad与onTabItemTap的触发机制差异。作者发现仅在页面首次加载时onLoad会被触发,而后续通过tabbar切换不会再次调用。为确保每次切换页面时都能执行请求,作者推荐使用onTabItemTap代替。

遇到一个大坑!!!
小程序写的请求放在onload生命周期中,希望进入页面他就会自己执行,但是发现只有在刷新页面后才会触发一次,并且只触发一次
之后在进入这个页面就不会触发onload函数了,请求自然也不会通
后来发现是因为tabbar页面切换,他没有走onload
最后我是添加了
onTabItemTap(e){ // ajax拉去数据 console.log(e) },
成功执行了我的wx.request
巨坑!!!

<think> 在微信小程序中,当从其他页面返回到tabBar页面时,并触发tabBar页面的onLoad或onShow等生命周期函数(实际上onShow会触发,但onLoad会)。但是,有时候我们需要在返回到tabBar页面时进行一些刷新操作。 微信小程序的页面生命周期包括: - onLoad: 页面加载时触发,一个页面只会调用一次。 - onShow: 页面显示/切入前台时触发。 - onReady: 页面初次渲染完成时触发,一个页面只会调用一次。 - onHide: 页面隐藏/切入后台时触发。 - onUnload: 页面卸载时触发。 对于tabBar页面,它并会被卸载,而是会被隐藏。因此,当我们离开tabBar页面(跳转到非tabBar页面)时,会触发tabBar页面的onHide,当我们再次返回(从非tabBar页面返回)时,会触发onShow。 所以,我们可以在tabBar页面的onShow生命周期函数中进行刷新操作。 但是有一个注意点:第一次进入tabBar页面时,会触发onLoad和onShow,而我们返回时只会触发onShow。所以,我们需要在onShow中判断是否需要刷新,或者直接进行刷新(如果刷新操作频繁且对性能影响大)。 另外,微信小程序还提供了一个专门用于监听页面显示的生命周期函数:onShow,我们可以在这里执行刷新数据等操作。 示例代码: 假设我们有一个tabBar页面(首页),我们希望在每次显示这个页面的时候都刷新数据。 在home.js中: ```javascript Page({ data: { // 数据 list: [], // ...其他数据 }, onLoad: function (options) { // 第一次加载时获取数据 this.loadData(); }, onShow: function () { // 每次页面显示的时候,我们重新刷新数据 // 注意:这里可能会造成重复加载(比如第一次加载时onLoad和onShow都会触发),所以我们可以优化一下 // 方案1:在onLoad中调用,onShow中调用(但这样返回时会刷新) // 方案2:在onShow中调用,但通过一个标记避免第一次重复(因为第一次onLoad和onShow都会调用) // 方案3:直接在onShow中调用,如果刷新操作重复且可以多次执行,则无妨(例如数据相同则会重复渲染) // 或者,我们可以考虑使用一个状态来记录是否已经加载过,或者是否需要刷新 // 这里我们选择在onShow中直接刷新,但为了避免第一次进入时重复(因为onLoad中已经调用了一次),我们可以onLoad中调用,而只在onShow中调用。 // 但是注意:onLoad只在第一次加载时调用,而onShow每次显示都调用。如果我们希望每次显示都刷新,那么我们就只在onShow中调用。 // 因此,我们可以去掉onLoad中的loadData,而只在onShow中调用。 this.loadData(); }, loadData: function() { // 模拟加载数据 // 实际中可能是网络请求 const newData = ...; // 获取新数据 this.setData({ list: newData }); }, // ...其他方法 }) ``` 但是,如果我们希望第一次加载时重复,我们可以设置一个标记: ```javascript Page({ data: { list: [], isFirstLoad: true // 第一次加载标记 }, onLoad: function (options) { // 第一次加载时获取数据 this.loadData(); }, onShow: function () { if (this.data.isFirstLoad) { // 如果是第一次,因为onLoad已经调用过,所以跳过 // 然后将标记设为false this.setData({ isFirstLoad: false }); } else { // 是第一次,则刷新数据 this.loadData(); } }, loadData: function() { // 加载数据 // ... } }) ``` 或者,我们也可以考虑在onShow中每次都需要刷新,管是是第一次,因为第一次的时候数据可能已经过时(比如从其他页面操作后返回,需要刷新)。所以,如果我们的数据刷新是幂等的,而且对实时性要求高,那么可以每次onShow都刷新。 但是,这样可能会带来性能问题(频繁请求)。所以,我们需要根据业务场景来决定。 另一种做法:我们可以在页面上添加一个刷新事件,例如使用onPullDownRefresh(下拉刷新)来让用户手动刷新,然后在返回时自动刷新可能并是必须的。 所以,总结一下: 1. 如果每次进入页面都需要刷新,那么就在onShow中调用加载数据的方法(包括第一次)。 2. 如果第一次加载已经在onLoad中做了,为了避免重复,可以在onShow中通过判断条件来决定是否刷新(例如,根据时间间隔,或者根据一个标记)。 根据微信官方文档,tabBar页面在第一次加载后,再次进入时会重新加载(即触发onLoad),只会触发onShow。所以,我们可以选择在onShow中执行刷新操作,这样每次进入(包括第一次和返回)都会执行。 但是注意:第一次进入时,会先触发onLoad,再触发onShow。所以,如果我们同时在onLoad和onShow中调用同一个加载方法,那么第一次进入时就会调用两次。因此,我们通常只在onShow中调用,而再在onLoad中调用,这样就会重复。 所以,推荐做法是:将数据加载放在onShow中,这样每次进入页面(无论第一次还是返回)都会刷新数据。如果担心刷新太频繁,可以加入一些判断条件(比如距离上次刷新时间超过一定时间才刷新)。 示例: ```javascript Page({ data: { list: [], lastRefreshTime: 0 // 上次刷新时间 }, onShow: function () { const now = new Date().getTime(); // 如果距离上次刷新时间超过30秒,或者第一次(lastRefreshTime为0)则刷新 if (now - this.data.lastRefreshTime > 30000 || this.data.lastRefreshTime === 0) { this.loadData(); this.setData({ lastRefreshTime: now }); } }, loadData: function() { // 加载数据... } }) ``` 这样,在30秒内返回页面会刷新,超过30秒则会刷新。 当然,具体是否刷新以及刷新条件可以根据业务需求调整。 另外,还有一种情况:从其他页面返回时,可能其他页面已经修改了一些数据,我们希望在返回时立即刷新。那么我们可以使用时间间隔,而是每次返回都刷新。这取决于你的应用场景。 所以,回答你的问题:使用onShow生命周期函数来刷新tabBar页面。 注意:在非tabBar页面跳转到tabBar页面时,会触发tabBar页面的onShow;同样,当从其他页面返回tabBar页面时,也会触发onShow。因此,在onShow中刷新是合适的。 但是,如果跳转是切换到另一个tabBar页面(通过点击tabBar切换),那么当前离开的tabBar页面会触发onHide,而进入的tabBar页面会触发onShow。所以,如果你希望每次点击tabBar切换到这个页面时也刷新,那么同样可以在onShow中处理。 因此,综合来看,在onShow中刷新数据是合适的。 另外,如果刷新操作是异步的(比如网络请求),需要考虑快速切换的情况,防止上一次的请求还未完成又发起了新的请求,或者页面已经销毁(虽然tabBar页面会销毁,但也要注意异步回调中可能访问到this的情况)。可以使用Promise、async/await或者标记来控制。 例如,使用一个标记来防止重复请求: ```javascript Page({ data: { list: [], isLoading: false // 是否正在加载 }, onShow: function () { this.loadData(); }, loadData: function() { if (this.data.isLoading) { return; } this.setData({ isLoading: true }); // 模拟网络请求 wx.request({ url: 'https://example.com/data', success: (res) => { this.setData({ list: res.data }); }, complete: () => { this.setData({ isLoading: false }); } }); } }) ``` 这样,在请求未完成时,再次触发loadData会发起新的请求。 综上所述,使用onShow生命周期函数来刷新tabBar页面。 </think>在微信小程序中,当用户从其他页面返回到 tabBar 页面时,可以通过 **`onShow`** 生命周期函数来实现页面刷新。tabBar 页面触发 `onLoad`(除非首次加载),但每次进入页面(包括返回)都会触发 `onShow`。 ### 解决方案: ```javascript // pages/tabPage/index.js Page({ // 页面显示/切入前台时触发 onShow() { this.refreshTabData(); // 每次进入页面时刷新数据 }, // 自定义刷新方法 refreshTabData() { console.log("刷新tabBar页面数据..."); // 这里执行数据刷新逻辑(例如重新请求接口) wx.showLoading({ title: '刷新中' }); // 模拟接口请求 setTimeout(() => { this.setData({ message: "最新数据:" + new Date().toLocaleString() }); wx.hideLoading(); }, 1000); }, // 页面数据 data: { message: "初始数据" } }) ``` ```html <!-- pages/tabPage/index.wxml --> <view class="container"> <text>{{message}}</text> <button bindtap="refreshTabData">手动刷新</button> </view> ``` ### 关键点解释: 1. **`onShow` 生命周期**: - 触发场景:页面显示时(首次进入、从其他页面返回、从后台切回前台) - 最佳实践:在此函数中执行数据刷新,确保每次用户看到页面时都是最新数据 2. **与 `onLoad` 的区别**: - `onLoad` 只触发一次(页面创建时) - `onShow` 每次页面显示时都触发 - tabBar 页面切换时会销毁页面实例,因此触发 `onLoad` 3. **优化建议**: - 添加防抖逻辑避免频繁刷新 - 结合页面参数判断是否需要强制刷新 ```javascript onShow(options) { if (options.from === 'refresh') { // 根据场景判断 this.refreshTabData(); } } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值