跳到主要内容

useSelectorQuery

获取指定组件或标签的尺寸以及 context

何时使用

当需要获取组件相关信息时

API

const [
query,
{
querySelector,
querySelectorAll,
selectViewport,
in,
exec,
getBoundingClientRect,
getContext,
getFields,
getNode,
getScrollOffset,
}
] = useSelectorQuery();

返回值说明

返回值说明类型
querySelectorQuery对象实例SelectorQuery
querySelector在当前页面下选择第一个匹配选择器 selector 的节点SelectorQuery['select']
querySelectorAll在当前页面下选择匹配选择器 selector 的所有节点SelectorQuery['selectAll']
selectViewport选择显示区域。可用于获取显示区域的尺寸、滚动位置等信息SelectorQuery['selectViewport']
in将选择器的选取范围更改为自定义组件 component 内SelectorQuery['in']
exec执行所有的请求SelectorQuery['exec']
getBoundingClientRect添加节点的布局位置的查询请求。相对于显示区域,以像素为单位PromiseParamsAction<(selector: string, all?: boolean) => void, NodesRef.BoundingClientRectCallbackResult>
getContext添加节点的 Context 对象查询请求PromiseAction<string, NodesRef.ContextCallbackResult>
getFields获取节点的相关信息。需要获取的字段在 fields 中指定PromiseParamsAction<(selector: string, fields: NodesRef.Fields) => void, TaroGeneral.IAnyObject>
getNode获取 Node 节点实例PromiseAction<string, NodesRef.NodeCallbackResult>
getScrollOffset添加节点的滚动位置查询请求。以像素为单位。节点必须是 scroll-view 或者 viewportPromiseAction<string, NodesRef.ScrollOffsetCallbackResult>

代码演示

basic/useSelectorQuery/index
import React from 'react';
import { NodesRef, useReady } from '@tarojs/taro';
import { useRef, useState } from '@taro-hooks/core';
import { useSelectorQuery, useToast } from 'taro-hooks';
import DemoContent from '@src/components/DemoContent';
import { Cell, Tabs, Divider } from '@taroify/core';
import { View, ScrollView } from '@tarojs/components';

import './index.less';

export default () => {
const selector = '.query-demo';
const fieldsSetting = {
dataset: true,
size: true,
mark: true,
rect: true,
scrollOffset: true,
properties: ['scrollX', 'scrollY'],
computedStyle: ['margin', 'backgroundColor'],
context: true,
};
const tabValue = useRef<string>('bound');
const [bounding, setBounding] =
useState<NodesRef.BoundingClientRectCallbackResult>();
const [fields, setFields] = useState<TaroGeneral.IAnyObject>({});
const [scroll, setScroll] = useState<NodesRef.ScrollOffsetCallbackResult>();

const { show } = useToast({
title: 'useEvent',
mask: true,
duration: 500,
icon: 'none',
});
const [, { getBoundingClientRect, getFields, getScrollOffset }] =
useSelectorQuery();

const handleGetBounding = async () => {
try {
const result = await getBoundingClientRect(selector);
setBounding(result);
} catch (e) {
show({ title: e.errMsg || e.message, icon: 'error' });
}
};

const handleGetFields = async () => {
try {
const result = await getFields(selector, fieldsSetting);
setFields(result);
} catch (e) {
show({ title: e.errMsg || e.message, icon: 'error' });
}
};

const handleGetScroll = async () => {
try {
const result = await getScrollOffset(selector + '-scroll');
setScroll(result);
} catch (e) {
show({ title: e.errMsg || e.message, icon: 'error' });
}
};

useReady(() => {
handleGetBounding();
handleGetFields();
handleGetScroll();
});

return (
<DemoContent>
<Tabs sticky animated>
<Tabs.TabPane title="bound" key="bound">
<View className="query-demo"></View>
<Divider>属性</Divider>
<Cell.Group title="getBoundingClientRect">
{Object.entries(bounding ?? {}).map(([key, value]) => (
<Cell key={key} title={key} brief={JSON.stringify(value)}></Cell>
))}
</Cell.Group>
</Tabs.TabPane>
<Tabs.TabPane title="fields" key="fields">
<View className="query-demo"></View>
<Divider>属性</Divider>
<Cell.Group title="getFields">
{Object.entries(fields ?? {}).map(([key, value]) => (
<Cell key={key} title={key} brief={JSON.stringify(value)}></Cell>
))}
</Cell.Group>
</Tabs.TabPane>
<Tabs.TabPane title="scroll" key="scroll">
<ScrollView className="query-demo-scroll" scrollY scrollTop={100}>
<View className="query-demo"></View>
<View className="query-demo"></View>
<View className="query-demo"></View>
</ScrollView>
<Divider>属性</Divider>
<Cell.Group title="getScrollOffset">
{Object.entries(scroll ?? {}).map(([key, value]) => (
<Cell key={key} title={key} brief={JSON.stringify(value)}></Cell>
))}
</Cell.Group>
</Tabs.TabPane>
</Tabs>
</DemoContent>
);
};

Hook 支持度

微信小程序H5ReactNative
✔️✔️

FAQ

  • 为什么获取不到结果, 时有时无?

    官方推荐的获取时机为onReady|useReady时, 若在ready中依然有不稳定因素建议搭配nextTick来确保元素已经渲染完成.