uni-app ios hbuilderX 3.2.9 修改子包内容热加载后 主包使用的refs this.$refs 在onReady nextTick 后调用 获取为null 报错

uni-app ios hbuilderX 3.2.9 修改子包内容热加载后 主包使用的refs this.$refs 在onReady nextTick 后调用 获取为null 报错

开发环境 版本号 项目创建方式
Mac i5

操作步骤:

<u-waterfall v-model="list" ref="uWaterfall"> <template v-slot:left="{ leftList }"> <view v-for="(item, index) in leftList" :key="index"> <wItem :info.sync="item"></wItem> </view> </template> <template v-slot:right="{ rightList }"> <view v-for="(item, index) in rightList" :key="index"> <wItem :info.sync="item"></wItem> </view> </template> </u-waterfall> onReady() { console.log(this.$refs); // 报错 } ```

预期结果:

refs 子组件加载正常; refs.xxx 为VueComponent


### 实际结果:

TypeError: Cannot read property 'selectAllComponents' of null

bug描述:

【报Bug】 ios hbuilderX 3.2.14 修改子包内容,热加载后 主包使用的refs ( this.$refs 在onReady nextTick 后调用) 获取为null 报错; 注: refs使用层级在二层;没有深层嵌套;


更多关于uni-app ios hbuilderX 3.2.9 修改子包内容热加载后 主包使用的refs this.$refs 在onReady nextTick 后调用 获取为null 报错的实战教程也可以访问 https://www.itying.com/category-93-b0.html

5 回复

refs 不在内置组件使用

更多关于uni-app ios hbuilderX 3.2.9 修改子包内容热加载后 主包使用的refs this.$refs 在onReady nextTick 后调用 获取为null 报错的实战教程也可以访问 https://www.itying.com/category-93-b0.html


vue2还是vue3?具体是怎么使用的,贴一下看看。

的确有这个问题,我也遇到了,我是win10 ,HX3.2.12 , 热加载后,$refs就报 Cannot read property ‘selectAllComponents’ of null 不用热加载,重新编译就正常了

我用的vue2,代码如下:
onShow(){
console.log(“index onShow”)
//表示等组件全部加载完毕后执行
this.$nextTick(()=>{
console.log("$nextTick")
console.log(“this.$refs:”,this.$refs) //热加载后,这里就报错,重新编译没问题
console.log(“this.$refs.uWaterfall:”,this.$refs.uWaterfall)
// this.$refs.uWaterfall.clear()
})
}

这是一个典型的 uni-app 热重载后 refs 引用失效的问题。问题核心在于热重载过程中组件实例的重新创建与 refs 引用的同步机制。

原因分析:

  1. 热重载机制差异:iOS 环境下,HBuilderX 的热重载可能触发了组件的完全重新渲染,导致 refs 引用在组件实例更新后未能正确重建关联。

  2. 生命周期时序问题onReady 在组件首次渲染完成后触发,但热重载后,组件可能经历了销毁-重建的过程,此时旧的 refs 引用已失效,而新的引用尚未建立。

  3. 子包修改的影响:修改子包内容后,主包中的组件可能因为依赖关系而重新渲染,但 refs 的绑定未能及时更新。

解决方案:

  1. 使用 $nextTick 延迟访问
onReady() {
    this.$nextTick(() => {
        console.log(this.$refs.uWaterfall); // 在下一个事件循环中访问
    });
}
  1. 添加空值判断
onReady() {
    this.$nextTick(() => {
        if (this.$refs.uWaterfall) {
            // 安全操作
            console.log(this.$refs.uWaterfall);
        }
    });
}
  1. 使用 setTimeout 作为备选方案
onReady() {
    setTimeout(() => {
        if (this.$refs.uWaterfall) {
            console.log(this.$refs.uWaterfall);
        }
    }, 100);
}
回到顶部