useSubscription()
非常适合让频繁变化的资源保持最新。
使用默认的轮询订阅时,必须在 Endpoint 中设置频率,否则不会生效。
提示
useLive() 是与 useSuspense() 组合使用的更简洁写法,
用法
api/Price
import { RestEndpoint, Entity } from '@data-client/rest';
export class Price extends Entity {
symbol = '';
price = '0.0';
// ...
pk() {
return this.symbol;
}
}
export const getPrice = new RestEndpoint({
urlPrefix: 'http://test.com',
path: '/price/:symbol',
schema: Price,
pollFrequency: 5000,
});
MasterPrice.vue
<script setup lang="ts">
import { useSuspense, useSubscription } from '@data-client/vue';
import { getPrice } from 'api/Price';
const props = defineProps<{ symbol: string }>();
const price = await useSuspense(getPrice, () => ({ symbol: props.symbol }));
useSubscription(getPrice, () => ({ symbol: props.symbol }));
// ...
</script>
行为
条件依赖
将 null 作为任意 Data Client hook 的第二个参数,表示“什么都不做”。
// todo could be undefined if id is undefined
const todo = useSubscription(
TodoResource.get,
computed(() => (id.value ? { id: id.value } : null)),
);
订阅会在组件 setup 时创建,在组件卸载时移除。当以 ref 形式传入的参数发生变化时,之前的订阅会被移除,并为新参数创建新的订阅。
类型
function useSubscription(
endpoint: ReadEndpoint,
...args: MaybeRefsOrGetters<Parameters<typeof endpoint>> | [null]
): void;
参数可以是普通值、refs(包括 computed),或者像 () => ({ id: props.id }) 这样的 getter
函数。像 { id: props.id } 这样的普通对象只会被读取一次,不会跟随 prop 或路由的变化,因此当参数可能变化时,请使用 getter 或 computed。
示例
仅在元素可见时订阅
MasterPrice.vue
<script setup lang="ts">
import { computed, useTemplateRef } from 'vue';
import { useElementVisibility } from '@vueuse/core';
import { useSuspense, useSubscription } from '@data-client/vue';
import { getPrice } from 'api/Price';
const props = defineProps<{ symbol: string }>();
const price = await useSuspense(getPrice, () => ({ symbol: props.symbol }));
const el = useTemplateRef('el');
const isVisible = useElementVisibility(el);
// null params means don't subscribe
useSubscription(
getPrice,
computed(() => (isVisible.value ? { symbol: props.symbol } : null)),
);
</script>
<template>
<div ref="el">{{ price.price }}</div>
</template>
当第二个参数传入 null 时,订阅会被停用。当然,如果还有其他组件在订阅,数据更新仍会继续。
VueUse 的 useElementVisibility() 使用了性能非常好的 IntersectionObserver。模板引用让我们可以访问 DOM。