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
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的版本
下面开工改造:
- 修改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 ‘’
}
}; - 修改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 ‘’
}
}; - 修改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;
}
} - 在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)
};
}
} - 修改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)
}
})
}
} - 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栏能够正产更实用。感谢!!!
一年啦。。。感恩。。还是期待正式版


