useSelectorQuery
获取指定组件或标签的尺寸以及 context
何时使用
当需要获取组件相关信息时
API
const [
query,
{
querySelector,
querySelectorAll,
selectViewport,
in,
exec,
getBoundingClientRect,
getContext,
getFields,
getNode,
getScrollOffset,
}
] = useSelectorQuery();
返回值说明
返回值 | 说明 | 类型 |
---|---|---|
query | SelectorQuery 对象实例 | 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 或者 viewport | PromiseAction<string, NodesRef.ScrollOffsetCallbackResult> |
代码演示
- React
- Vue
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>
);
};
basic/useSelectorQuery/index
<template>
<demo-content>
<nut-tabs :auto-height="true" v-model="tabValue.current">
<nut-tabpane title="bound" pane-key="bound">
<view class="query-demo"></view>
<nut-divider>属性</nut-divider>
<nut-cell-group title="getBoundingClientRect">
<nut-cell
v-for="(value, key) in bounding ?? {}"
:key="key"
:title="key"
:sub-title="$filters.stringify(value)"
></nut-cell>
</nut-cell-group>
</nut-tabpane>
<nut-tabpane title="fields" pane-key="fields">
<view class="query-demo"></view>
<nut-divider>属性</nut-divider>
<nut-cell-group title="getFields">
<nut-cell
v-for="(value, key) in fields"
:key="key"
:title="key"
:sub-title="$filters.stringify(value)"
></nut-cell>
</nut-cell-group>
</nut-tabpane>
<nut-tabpane title="scroll" pane-key="scroll">
<scroll-view
class="query-demo-scroll"
:scroll-y="true"
:scrollTop="100"
>
<view class="query-demo"></view>
<view class="query-demo"></view>
<view class="query-demo"></view>
</scroll-view>
<nut-divider>属性</nut-divider>
<nut-cell-group title="getScrollOffset">
<nut-cell
v-for="(value, key) in scroll ?? {}"
:key="key"
:title="key"
:sub-title="$filters.stringify(value)"
></nut-cell>
</nut-cell-group>
</nut-tabpane>
</nut-tabs>
</demo-content>
</template>
<script setup lang="ts">
import { NodesRef, useReady } from '@tarojs/taro';
import { useRef, useState } from '@taro-hooks/core';
import { useSelectorQuery, useToast } from 'taro-hooks';
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();
});
</script>
<style>
.query-demo,
.query-demo-scroll {
width: 100%;
height: 200px;
background-color: #a773ed;
}
</style>
Hook 支持度
微信小程序 | H5 | ReactNative |
---|---|---|
✔️ | ✔️ |
FAQ
为什么获取不到结果, 时有时无?
官方推荐的获取时机为
onReady|useReady
时, 若在ready
中依然有不稳定因素建议搭配nextTick
来确保元素已经渲染完成.