在 uni-app 中,
uni.createSelectorQuery()
是一个功能强大的 API,用于在页面或组件中查询节点信息、获取节点尺寸和位置、获取可操作组件的上下文等。它在跨平台开发中非常重要,尤其是涉及动态布局、滚动监听或组件操作时。本文将全面讲解其使用方式、注意事项及典型场景。
1、uni.createSelectorQuery()
返回一个 SelectorQuery 对象实例。它本身相当于一个查询器,你可以在它上面链式调用.select()
、.selectAll()
、.selectViewport()
等方法来选择节点,并通过.boundingClientRect()
、.scrollOffset()
、.context()
等方法获取节点信息。
核心功能:
找到页面或组件中的节点
获取节点信息(位置、尺寸、滚动、样式等)
获取可操作组件的上下文(如 video、canvas、map、live-player)
支持批量查询
2. NodesRef 对象
SelectorQuery.select()
或SelectorQuery.selectAll()
返回 NodesRef 对象,用于获取节点的详细信息。
常用方法:
boundingClientRect(callback)
:节点的几何信息(位置、尺寸)
scrollOffset(callback)
:节点或 viewport 的滚动位置
context(callback)
:获取节点的可操作 context(VideoContext、CanvasContext 等)
fields(object, callback)
:灵活获取节点的各种属性、样式和 context
node(callback)
:获取 Node 节点实例(目前主要支持 Canvas)
二、常用方法详解
1.
.in(component)
用于指定查询范围为某个自定义组件内,否则默认查询仅限当前页面。
const query = uni.createSelectorQuery().in(this); // this 指当前组件实例 query.select('#childBox').boundingClientRect(res => { console.log(res.width, res.height, res.top); }).exec();
注意事项:
支持 App、微信小程序,但支付宝小程序不支持
.in(component)
必须在组件 mounted 或 onReady 生命周期后调用
2.
.select(selector)
和.selectAll(selector)
select(selector)
:选中 第一个匹配节点
selectAll(selector)
:选中 所有匹配节点选择器规则:
ID 选择器:
#the-id
class 选择器:
.class1.class2
子元素选择器:
.parent > .child
后代选择器:
.ancestor .descendant
跨自定义组件后代:
.ancestor >>> .descendant
(H5 暂不支持)多选择器并集:
#a, .b
3.
.selectViewport()
选择显示区域,获取页面或 scroll-view 的尺寸与滚动位置:
uni.createSelectorQuery() .selectViewport() .scrollOffset(res => { console.log("页面滚动距离", res.scrollTop); }) .exec();
4.
.boundingClientRect(callback)
获取节点几何信息,类似浏览器 DOM 的
getBoundingClientRect
:uni.createSelectorQuery() .select('#box') .boundingClientRect(res => { console.log(res.top, res.left, res.width, res.height); }) .exec();
属性 类型 说明 id String 节点 ID dataset Object 节点 dataset left, right, top, bottom Number 节点边界位置 width, height Number 节点尺寸
5.
.scrollOffset(callback)
获取节点或 viewport 的滚动信息,单位 px:
uni.createSelectorQuery() .select('#scrollView') .scrollOffset(res => { console.log(res.scrollTop, res.scrollLeft); }) .exec();
6.
.context(callback)
获取节点上下文对象,用于可操作组件(video、live-player、canvas 等):
uni.createSelectorQuery() .select('#video') .context(video => { video.play(); // 播放视频 }) .exec();
context = 节点的“遥控器”
普通
<view>
节点调用 context 一般无用
7.
.fields(object, callback)
灵活获取节点信息:
view.fields({ id: true, dataset: true, size: true, scrollOffset: true, properties: ['value'], computedStyle: ['color', 'font-size'], context: true, node: true }, data => { console.log(data); }).exec();
字段 类型 默认 说明 id Boolean false 是否返回节点 id dataset Boolean false 是否返回 dataset rect Boolean false 返回布局位置 size Boolean false 返回 width、height scrollOffset Boolean false 返回 scrollTop/scrollLeft properties Array [] 返回指定属性值 computedStyle Array [] 返回指定样式值 context Boolean false 返回节点对应 context node Boolean false 返回 Node 节点实例(主要 Canvas)
8.
.node(callback)
获取 Node 实例,目前主要支持 canvas:
uni.createSelectorQuery() .select('#myCanvas') .node(res => { const canvasNode = res.node; }) .exec();
9.
.exec(callback)
执行所有请求,按请求顺序返回数组:
const query = uni.createSelectorQuery().in(this); query.select('#box').boundingClientRect(); query.select('#btn').boundingClientRect(); query.exec(res => { console.log(res[0], res[1]); // 返回结果顺序和查询顺序一致 });
三、使用注意事项
生命周期:必须在
mounted
/onReady
后调用,否则无法获取节点信息跨组件查询:使用
.in(component)
指定查询范围平台差异:
支付宝小程序不支持
.in(component)
nvue 不支持
uni.createSelectorQuery()
,需使用weex
dom 模块节点 ID 唯一性:同页面或组件内 ID 必须唯一,否则可能选不到或选错
四、典型应用场景
动态布局:获取节点尺寸来计算元素位置,做动画或自适应布局
滚动监听:获取 scroll-view 或 viewport 的滚动位置,实现懒加载、吸顶导航
子组件操作:父组件通过
ref
+context
或.in(this)
操作子组件内部可操作组件Canvas 绘图:通过
.node()
获取 canvas Node 实例,或者.context()
获取 CanvasContext响应式 UI:结合 Vue 的
ref
或响应式数据,动态改变节点大小、颜色、位置
五、总结
uni.createSelectorQuery()
是 uni-app 中 查询节点信息和操作组件的核心 API。
节点信息:位置、尺寸、滚动、样式
上下文 context:可操作组件的方法手柄
支持批量查询:一次获取多个节点信息
平台注意事项:支付宝小程序、nvue 有些方法有限制
通俗理解:
节点 = 页面上真实存在的盒子/组件
context = 拿到盒子的遥控器
ref = Vue 给父组件的钥匙,可以访问子组件实例