コンポーネント データの遅延読み込み - 基本的な使用法
目標: useIntersectionObserver を通じて新鮮な商品と人気のレコメンデーション モジュールを最適化する
電子商取引 Web サイト、特にホームページには複数のコンテンツ画面があり、すべての画面のデータをロードしてすべての画面のコンテンツをレンダリングすると、ホームページの読み込みが非常に遅くなります。
データの遅延読み込み: コンポーネントが正式に表示領域に入ると、コンポーネント内の ajax リクエストが開始されます。それ以外の場合、データはリクエストされません。
(1) 生鮮品の最適化
<script lang="ts" setup>
const {
home } = useStore()
const target = ref(null)
const {
stop } = useIntersectionObserver(target, ([{
isIntersecting }]) => {
console.log(isIntersecting)
// isIntersecting 是否进入可视区域,true是进入 false是移出
if (isIntersecting) {
home.getNewList()
stop()
}
})
</script>
<template>
<div class="home-new">
<HomePanel ref="target" title="新鲜好物" sub-title="新鲜出炉 品质靠谱">
</HomePanel>
</div>
</template>
(2) 人気レコメンデーションの最適化
<script lang="ts" setup>
const {
home } = useStore()
const target = ref(null)
const {
stop } = useIntersectionObserver(target, ([{
isIntersecting }]) => {
console.log(isIntersecting)
// isIntersecting 是否进入可视区域,true是进入 false是移出
if (isIntersecting) {
home.getHotList()
stop()
}
})
</script>
<template>
<HomePanel ref="target" title="人气推荐" sub-title="人气爆款 不容错过">
</HomePanel>
</template>
コンポーネントタイプをrefに追加
参考リンク:https://staging-cn.vuejs.org/guide/typescript/composition-api.html#typing-component-template-refs
<!-- App.vue -->
<script setup lang="ts">
import MyModal from './MyModal.vue'
const modal = ref<InstanceType<typeof MyModal> | null>(null)
const openModal = () => {
modal.value?.open()
}
</script>
コンポーネントデータの遅延読み込み - カプセル化
目標: コンポーネント データの遅延読み込みと再利用可能なロジックをカプセル化する
分析する
ホームページでは、コンポーネントデータの遅延読み込みを多くの場所で使用する必要がありますが、どのモジュールを使用しても、次のコードが繰り返し記述されます。
実際、ビジネス用途で変更される可能性がある唯一のことは、ajax インターフェイスの呼び出しです。
残りを再利用し、再利用可能なロジックに抽出します
コアコード:
(1) 一般的な遅延読み込みデータ API をカプセル化するsrc/utils/hooks.ts
// 自定义一些通用的compositions api
import {
useIntersectionObserver } from '@vueuse/core'
import {
ref } from 'vue'
// 封装通用的数据懒加载api
export function useLazyData(apiFn: () => void) {
// 通过 ref 获得组件实例
const target = ref(null)
const {
stop } = useIntersectionObserver(
// target 是观察的目标dom容器,必须是dom容器,而且是vue3.0方式绑定的dom对象
target,
// isIntersecting 是否进入可视区域,true是进入 false是移出
// observerElement 被观察的dom
([{
isIntersecting }]) => {
// 在此处可根据isIntersecting来判断,然后做业务
if (isIntersecting) {
stop()
apiFn()
}
}
)
return target
}
(2) 生鮮品の最適化
<script lang="ts" setup>
const target = useLazyData(() => {
home.getNewList()
})
</script>
<template>
<div class="home-new">
<HomePanel ref="target" title="新鲜好物" sub-title="新鲜出炉 品质靠谱">
</HomePanel>
</div>
</template>
(3) 人気レコメンデーションの最適化
<script lang="ts" setup>
const target = useLazyData(() => {
home.getHotList()
})
</script>
<template>
<HomePanel ref="target" title="人气推荐" sub-title="人气爆款 不容错过">
</HomePanel>
</template>
小さな知識を広げる: カスタム Lazyhook 型の最適化
export function useLazyApi(apiFn: () => void) {
const target = ref<MaybeElementRef | null>(null)
const {
stop} = useIntersectionObserver(target, ([{
isIntersecting}]) => {
if (isIntersecting) {
stop()
apiFn()
}
})
return target
}
ref タイプのヒントを追加しました:MaybeElementRef -> 割り当てタイプが間違っている場合、公開されたターゲットはプロンプトを表示します
では、MaybeElementRef がどのような型であるかを見てみましょう。
declare type MaybeElementRef<T extends MaybeElement = MaybeElement> = MaybeRef<T>;
declare type MaybeElement = HTMLElement | SVGElement | VueInstance | undefined | null;
declare type MaybeRef<T> = T | Ref<T>;
要約すると、MaybeElementRef 型の型は次のとおりです。
- MayElement の Ref 型
- または、MayBeElement タイプに対して直接
ホームページ本体 - 製品のスクロール読み込みのバグ
- データをロードするには、製品領域をさらにスクロールする必要があります。
- しきい値 コンテナと表示領域の比率 (入力された領域/コンテナの完全な領域) 値、0 ~ 1、デフォルトは 0 より大きいため、入力イベントをトリガーするにはさらに多くのスクロールが必要です目に見える領域。閾値(進入面積/コンテナ全面積)
const {
stop } = useIntersectionObserver(
target,
([{
isIntersecting }], observerElement) => {
if (isIntersecting) {
stop()
// 调用API获取数据
apiFn().then(data => {
result.value = data.result
})
}
},
{
threshold: 0
}
)
rElement) => {
if (isIntersecting) {
stop()
// 调用API获取数据
apiFn().then(data => {
result.value = data.result
})
}
},
{
threshold: 0
}
)