uni-app 【紧急】uni.preloadPage 在HX3.1.4和HX3.1.6正式版打包使用出错

uni-app 【紧急】uni.preloadPage 在HX3.1.4和HX3.1.6正式版打包使用出错

操作步骤:

  • 使用uni.preloadPage预加载tabbar页面

预期结果:

  • 可以正常切换

实际结果:

  • 不能切换

bug描述:

uni.preloadPage HX3.1.4和HX3.1.6正式版打包使用出错,出现预载的底部tabbar切换后,页面无法切换问题。 使用同版本打包的自定义调试基座可以正常使用。

相关链接 :

信息类别 信息内容
产品分类 uniapp/App
PC开发环境 Windows
PC开发环境版本号 10
HBuilderX类型 正式
HBuilderX版本号 3.1.6
手机系统 Android
手机系统版本号 Android 11
手机厂商 小米
手机机型 10
页面类型 nvue
打包方式 云端
项目创建方式 HBuilderX

更多关于uni-app 【紧急】uni.preloadPage 在HX3.1.4和HX3.1.6正式版打包使用出错的实战教程也可以访问 https://www.itying.com/category-93-b0.html

15 回复

https://ask.dcloud.net.cn/question/119780 还有这个问题,都是切实存在的,咋官方就不关注呢

更多关于uni-app 【紧急】uni.preloadPage 在HX3.1.4和HX3.1.6正式版打包使用出错的实战教程也可以访问 https://www.itying.com/category-93-b0.html


测试发现是uni统计造成的。。。测试发现是uni统计造成的。。。

多亏了你的发现。。。

修复方法如下:
修改uni统计源代码 打开HBuilderX安装目录,找到 HBuilderX安装目录\plugins\uniapp-cli\node_modules[@dcloudio](/user/dcloudio)\uni-stat\dist\index.js 这个文件。需注意package.json文件中version指定的版本,我的是uni-stat 2.0.0-32920211119001这个版本。
如果你的项目不是使用HBuilderX创建的,你可能需要修改 HBuilderX安装目录\plugins\uniapp-cli\node_modules[@dcloudio](/user/dcloudio)\vue-cli-plugin-uni\packages\uni-stat\dist 文件夹下的 uni-stat.cjs.js和uni-stat.es.js这两个文件,改造方法应该和下面的相同(因为我的项目没有用到这两个js代码,所以不清楚这两个代码在什么环境下起作用)。至于怎么查看用到的是哪个目录中的uni-stat,可以通过查看项目编译后的app-service.js文件,搜索关键字“@dcloudio/uni-stat@”, 可以定位到uni-stat的版本
下面开工改造:

  1. 修改getRoute方法 const getRoute = () => {
    var pages = getCurrentPages();
    var page = pages[pages.length - 1];
    if (!page) return ‘’
    // preloadPage的nvue页面$vm为undefined
    let _self = page.$vm;
    // 为preloadPage的nvue页面尝试从$page获取route属性
    let _page = page.$page;
    if (getPlatformName() === ‘bd’ && _self) {
    return _self.$mp && _self.$mp.page.is;
    } else if (_self){
    return (_self.$scope && _self.$scope.route) || (_self.$mp && _self.$mp.page.route);
    } else if (_page){
    return _page.route
    } else {
    console.error(‘未找到路径’)
    return ‘’
    }
    };
  2. 修改getPageRoute方法 const getPageRoute = (self) => {
    var pages = getCurrentPages();
    var page = pages[pages.length - 1];
    if (!page) return ‘’
    let _self = page.$vm;
    let _page = page.$page;
    let query = self._query;
    let str = query && JSON.stringify(query) !== ‘{}’ ? ‘?’ + JSON.stringify(query) : ‘’;
    // clear
    self._query = ‘’;
    if (getPlatformName() === ‘bd’ && _self) {
    return _self.$mp && _self.$mp.page.is + str;
    } else if (_self) {
    return (_self.$scope && _self.$scope.route + str) || (_self.$mp && _self.$mp.page.route + str);
    } else if (_page){
    return _page.route
    } else {
    console.error(‘未找到路径’)
    return ‘’
    }
    };
  3. 修改class Stat的load方法 class Stat extends Util {
    …此处省略
    load(options, self) {
    if (!self.$scope && !self.$mp) {
    // 如果是preloadPage nvue页面, 则这里拿不到对应的页面(也就是nvue页面不在CurrentPages页面栈中),需要使用route判断一下正确性
    // 否则会把错误的页面赋值给self.$scope,进而引发Cannot read property ‘__call_hook’ of undefined的错误
    const page = getCurrentPages();
    const route = page[page.length - 1].route;
    if (self.$options && self.$options.route === route) {
    self.$scope = page[page.length - 1];
    }
    }
    this.self = self;
    this._query = options;
    }
    }
  4. 在lifecycle前定义函数tryinterceptShare const tryinterceptShare = function(ctx) {
    if (ctx.$scope && ctx.$scope.onShareAppMessage) {
    let oldShareAppMessage = ctx.$scope.onShareAppMessage;
    ctx.$scope.onShareAppMessage = function(options) {
    stat.interceptShare(false);
    return oldShareAppMessage.call(ctx, options)
    };
    }
    }
  5. 修改lifecycle 的 onLoad 方法 onLoad(options) {
    stat.load(options, this);
    // 重写分享,获取分享上报事件
    tryinterceptShare(this)
    // preloadPage nvue页面,$scope可能为undefined
    if (!this.$scope) {
    var $scope = undefined;
    var self = this;
    Object.defineProperty(this, ‘$scope’, {
    get() {
    return $scope
    },
    set(val) {
    $scope = val;
    setTimeout(()=>{
    tryinterceptShare(self)
    }, 0)
    }
    })
    }
    }
  6. try catch lifecycle 中的所有方法,防止uni-stat统计出错引发应用异常 在 lifecycle定义后,添加如下代码 const ERROR_PREFIX = ‘uni-stat@’ + STAT_VERSION;

// 把lifecycle的方法全都try catch起来,防止出什么错导致应用页面打不开
const tryfunc = function(func, name) {
return function() {
try {
let args = [].slice.call(arguments);
func.apply(this, args)
} catch(e) {
console.error(ERROR_PREFIX + ’ error in function '+ name);
console.error(JSON.stringify(e))
}
}
}
Object.keys(lifecycle).forEach(k=>{
lifecycle[k] = tryfunc(lifecycle[k], k)
})

至此改造完毕。因为我也不知道这么修改会不会在其它平台出现错误,所以大家还是在修改后调试一下再发布,不过目前我自己在安卓机子上测试没发现问题。

遇到同样的问题

关注 uni.preloadPage ,可以用于视频 预先加载吗

你的修复了吗?

不知道

顶顶,期待官网解决一下

确定bug ,下个版本修复

太好了,期待。希望下个版本,我们加入uni统计后 tab栏能够正产更实用。感谢!!!

HBuiderX 3.4.4+ 已经修复此问题

一年啦。。。感恩。。还是期待正式版

回到顶部