uni.createSelectorQuery().select() uni-app uniapp-x 在onReady生命周期 无法正确返回值

uni.createSelectorQuery().select() uni-app uniapp-x 在onReady生命周期 无法正确返回值

项目
产品分类 uniapp/App
PC开发环境操作系统 Windows
PC开发环境操作系统版本号 w11 (KB5094126) (26200.8655)
HBuilderX类型 Alpha
HBuilderX版本号 5.13
手机系统 全部
手机厂商 华为
页面类型 nvue
vue版本 vue3
打包方式 云端
项目创建方式 HBuilderX

测试过的手机

模拟器 vivo x100

bug描述

uni.createSelectorQuery().select() uniapp-x 在onReady生命周期 无法正确返回值

示例代码

const getFlexNodeInfo = () => {
  uni.createSelectorQuery().select('.flex-box').boundingClientRect().exec((ret) => {
    // exec 回调返回的是数组,先转为 NodeInfo[]
    const nodeInfoArray = ret as NodeInfo[]
    if (nodeInfoArray.length > 0) {
      const nodeInfo = nodeInfoArray[0]
      console.log(nodeInfo.width, nodeInfo.height)
    }
  })
}

onReady(() => {
  console.log("onReady")
  nextTick(() => {
    console.log("onReady-nextTick")
    getFlexNodeInfo()
  })
})
<view style="flex-direction: column;height:100%;">
  <view style="height:80rpx"></view>
  <view style="flex:1" class="flex-box"></view>
</view>

操作步骤

const getFlexNodeInfo = () => {
  uni.createSelectorQuery().select('.flex-box').boundingClientRect().exec((ret) => {
    // exec 回调返回的是数组,先转为 NodeInfo[]
    const nodeInfoArray = ret as NodeInfo[]
    if (nodeInfoArray.length > 0) {
      const nodeInfo = nodeInfoArray[0]
      console.log(nodeInfo.width, nodeInfo.height)
    }
  })
}

onReady(() => {
  console.log("onReady")
  nextTick(() => {
    console.log("onReady-nextTick")
    getFlexNodeInfo()
  })
})
<view style="flex-direction: column;height:100%;">
  <view style="height:80rpx"></view>
  <view style="flex:1" class="flex-box"></view>
</view>

更多关于uni.createSelectorQuery().select() uni-app uniapp-x 在onReady生命周期 无法正确返回值的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于uni.createSelectorQuery().select() uni-app uniapp-x 在onReady生命周期 无法正确返回值的实战教程也可以访问 https://www.itying.com/category-93-b0.html


需补充平台分类(安卓/鸿蒙等)、HBuilderX版本及详细报错信息。 欢迎到专业群( uni-app x技术交流群 ) 咨询,群中有相关专业的管理员和群友。

感谢你的 bug 反馈,我已经仔细审查了你提供的内容。
反馈内容评审:
反馈内容整体结构清晰,包含了问题描述、环境信息、代码示例和预期/实际结果。不过,在内容和细节上,有一些地方可以优化,以帮助我们更快地定位和解决问题:

代码示例的完整性:提供的代码示例结合了 JavaScript 和模板,逻辑上是完整的。但有一个关键点,uni.createSelectorQuery().select(’.flex-box’).boundingClientRect().exec((ret) => { … }) 这种写法,回调参数 ret 的类型在 uni-app x (UTS) 的严格类型环境下可能存在问题。你需要将 ret 断言为 NodeInfo[],然后通过索引访问,这是正确的做法。不过,如果 ret 数组为空,nodeInfoArray[0] 就会是 null,后续访问其属性就会出错。建议在访问前增加数组长度的判断。

环境信息:平台信息填写了“全部”,这不够精确。请务必明确问题是在哪个特定平台(Android、iOS、鸿蒙、Web、微信小程序)上复现的。不同平台的渲染机制不同, onReady 时机的行为也可能有差异。

HBuilderX 版本:你使用的是 5.13 Alpha 版。Alpha 版是开发中的版本,可能存在一些未修复的问题。我们建议同时验证在最新的正式版(当前为 5.07)上是否存在同样的问题,这有助于判断是 Alpha 版特有问题还是一个通用 Bug。

Bug 分析与结论:
这个 Bug 不成立。 这是一个典型的对 uni-app x (UTS) 强类型语法和 API 使用方式不熟悉导致的问题,而不是框架本身的 Bug。
根据官方文档和已知问题的处理方式,你的代码存在两个核心问题:

  1. exec 回调参数的类型处理不正确
    在 uni-app x 中,exec 方法的回调参数 ret 是一个 any 类型或需要你手动断言。你将它断言为 NodeInfo[] 是不准确的。根据官方文档 create-selector-query 示例,ret 本身是一个数组,其元素才是根据你的查询方法(如 boundingClientRect)返回的 NodeInfo 对象。正确的处理方式是:
    uni.createSelectorQuery().select(’.flex-box’).boundingClientRect().exec((ret) => {
    // ret 是所有查询结果的数组,这里我们只查询了一个,所以取 ret[0]
    // ret[0] 才是 NodeInfo 类型
    const nodeInfo = ret[0] as NodeInfo
    if (nodeInfo) {
    console.log(nodeInfo.width, nodeInfo.height)
    }
    })

本助手使用国产模型,生成代码准确率较低。强烈建议使用uni-agent生成代码

你之前的写法 const nodeInfoArray = ret as NodeInfo[] 试图将整个结果集当作 NodeInfo 数组,这导致了类型错误,并且在运行时可能无法正确访问到 width 和 height 属性。相关的 ISSUE 系统反馈(#22014)也提到了类似 rect.height 无法解析的问题,并给出了和你问题中最终采纳的类似解决方案,即通过 exec 的回调接收 ret 数组并处理。
2. onReady 生命周期与查询时机的通用问题
虽然从通用知识来看,onReady 代表页面初次渲染完成,是进行节点查询的合适时机,但在 uni-app x 中,对于一些复杂的布局(如使用了 flex:1 的元素),其最终尺寸可能需要等待下一帧布局才能确定。你在 onReady 的 nextTick 中调用,本意是等待 DOM 更新完成,这是一个好的尝试。
如果上述类型修正后,在 onReady + nextTick 中仍然获取不到正确值,可以尝试以下替代方案:

延迟执行:使用 setTimeout 添加一个短暂的延迟(如 50-100ms),以确保布局完全稳定。
onReady(() => {
setTimeout(() => {
getFlexNodeInfo()
}, 100)
})

本助手使用国产模型,生成代码准确率较低。强烈建议使用uni-agent生成代码

在特定事件后查询:如果元素的尺寸依赖于异步数据加载或用户交互,应在数据加载完毕或交互事件回调中进行查询。

总结与建议:

修正代码:请按照上述方式修正 exec 回调中访问 NodeInfo 属性的方式。
明确平台:请提供具体是哪个平台出现了问题,这有助于我们判断是否存在平台特定的渲染时序问题。
验证正式版:如果方便,请使用 HBuilderX 5.07 正式版验证问题是否依然存在。

如果你按照建议修改后问题仍然存在,并且能提供一个更完整的、可以直接运行的、能够精确描述预期与实际差异的复现工程,我们将非常乐意做进一步的深入排查。感谢你的理解和支持!

回到顶部