subNvue的创建
subNvue作为vue或nvue页面的原生子窗体,当其父页面创建时,subNvue也随之创建,且仅创建一次,其生命周期也只会触发一次(包括onShow)。
subNvue的销毁
官方只提供了隐藏方法,并未提供销毁方法,目前看只有在退出APP即杀死应用的时候,才会跟着APP进程一并消失。
结合上面两条规律,一旦你对某个包含subNvue的页面进行了多次创建(如uni.reLaunch),那个页面包含的subNvue也会随之多次创建,并保留在内存里。
通过调用 plus.webview.all()方法,在返回的webview列表里,你可以看到多个id相同但是 __uniapp_origin_id(父页面的id)不同的subNvue,这也就导致了几个问题:
- 当你想要通过getSubNVueById方法获取子窗体实例时,你获取到的可能并不是最新的实例,一旦你的子窗体有动态元素,最终渲染出的窗口也大概率是旧内容。
- 当你想要隐藏某个窗口时,情况也差不多,你无法精准拿到目前在界面上显示的子窗口实例,hide方法虽然执行了,但具体是哪个实例在执行,你也不知道。
- 所有旧的subNvue都会保存在内存里,即使父页面销毁也依然存留,无疑会增加性能消耗。
所幸,webview提供了close方法,我们可以筛选出id重复的subNvue,通过__uniapp_origin_id进行排序(新创建的页面,其id是递增的),之后手动清理即可。
const clearOldSubNvue = (id) => {
const webview = plus.webview
.all()
.filter((view) => view.id === id)
.sort((a, b) => +a.__uniapp_origin_id - +b.__uniapp_origin_id);
if (webview.length <= 1) return;
webview.forEach((view, index) => {
if (index < webview.length - 1) {
view.close();
}
});
};
值得注意的是,如果我们在父页面销毁前统一销毁子窗口,之后再打开任意subNvue,都会导致navigateBack连续触发两次的bug,因此建议在父页面的onLoad方法里调用清理函数,麻烦,但好在管用。
0 个评论
要回复文章请先登录或注册