Vue組件懶加載的操作代碼
在當今快節(jié)奏的數字世界中,網站性能對于吸引用戶和取得成功至關重要。然而,對于像首頁這樣的頁面,在不影響功能的前提下優(yōu)化性能就成了一項挑戰(zhàn)。
這就是 Vue 組件懶加載的用武之地。通過將非必要元素的加載推遲到可見時進行,開發(fā)人員可以增強用戶體驗,同時確保登陸頁面的快速加載。
懶加載是一種優(yōu)先加載關鍵內容,同時推遲加載次要元素的技術。這種方法不僅能縮短頁面的初始加載時間,還能節(jié)約網絡資源,從而使用戶界面更輕量、反應更靈敏。
在本文中,我將向你展示一種簡單的機制,使用 Intersection Observer API 在 Vue 組件可見時對其進行懶加載。
Intersection Observer API
Intersection Observer API 是一種功能強大的工具,它允許開發(fā)人員有效地跟蹤和響應瀏覽器視口中元素可見性的變化。
它提供了一種異步觀察元素與其父元素之間或元素與視口之間交集的方法。它為檢測元素何時可見或隱藏提供了性能優(yōu)越的優(yōu)化解決方案,減少了對低效滾動事件監(jiān)聽器的需求,使開發(fā)人員能夠在必要時有選擇地加載或操作內容,從而增強用戶體驗。
它通常用于實現(xiàn)諸如無限滾動和圖片懶加載等功能。
異步組件
Vue 3 提供了 defineAsyncComponent,用于僅在需要時異步加載組件。
它返回一個組件定義的 Promise:
import { defineAsyncComponent } from 'vue'
const AsyncComp = defineAsyncComponent(() => {
return new Promise((resolve, reject) => {
// ...load component from server
resolve(/* loaded component */)
})
})還可以處理錯誤和加載狀態(tài):
const AsyncComp = defineAsyncComponent({
// the loader function
loader: () => import('./Foo.vue'),
// A component to use while the async component is loading
loadingComponent: LoadingComponent,
// Delay before showing the loading component. Default: 200ms.
delay: 200,
// A component to use if the load fails
errorComponent: ErrorComponent,
// The error component will be displayed if a timeout is
// provided and exceeded. Default: Infinity.
timeout: 3000
})當組件可見時,我們將使用該功能異步加載組件。
懶加載組件
現(xiàn)在,讓我們結合 Intersection Observer API 和 defineAsyncComponent 函數,在組件可見時異步加載它們:
import {
h,
defineAsyncComponent,
defineComponent,
ref,
onMounted,
AsyncComponentLoader,
Component,
} from 'vue';
type ComponentResolver = (component: Component) => void
export const lazyLoadComponentIfVisible = ({
componentLoader,
loadingComponent,
errorComponent,
delay,
timeout
}: {
componentLoader: AsyncComponentLoader;
loadingComponent: Component;
errorComponent?: Component;
delay?: number;
timeout?: number;
}) => {
let resolveComponent: ComponentResolver;
return defineAsyncComponent({
// the loader function
loader: () => {
return new Promise((resolve) => {
// We assign the resolve function to a variable
// that we can call later inside the loadingComponent
// when the component becomes visible
resolveComponent = resolve as ComponentResolver;
});
},
// A component to use while the async component is loading
loadingComponent: defineComponent({
setup() {
// We create a ref to the root element of
// the loading component
const elRef = ref();
async function loadComponent() {
// `resolveComponent()` receives the
// the result of the dynamic `import()`
// that is returned from `componentLoader()`
const component = await componentLoader()
resolveComponent(component)
}
onMounted(async() => {
// We immediately load the component if
// IntersectionObserver is not supported
if (!('IntersectionObserver' in window)) {
await loadComponent();
return;
}
const observer = new IntersectionObserver((entries) => {
if (!entries[0].isIntersecting) {
return;
}
// We cleanup the observer when the
// component is not visible anymore
observer.unobserve(elRef.value);
await loadComponent();
});
// We observe the root of the
// mounted loading component to detect
// when it becomes visible
observer.observe(elRef.value);
});
return () => {
return h('div', { ref: elRef }, loadingComponent);
};
},
}),
// Delay before showing the loading component. Default: 200ms.
delay,
// A component to use if the load fails
errorComponent,
// The error component will be displayed if a timeout is
// provided and exceeded. Default: Infinity.
timeout,
});
};讓我們分解一下上面的代碼:
我們創(chuàng)建一個 lazyLoadComponentIfVisible 函數,該函數接受以下參數:
componentLoader:返回一個解析為組件定義的 Promise 的函數loadingComponent:異步組件加載時使用的組件。errorComponent:加載失敗時使用的組件。delay:顯示加載組件前的延遲。默認值:200 毫秒。timeout:如果提供了超時時間,則將顯示錯誤組件。默認值:Infinity。
函數返回 defineAsyncComponent,其中包含在組件可見時異步加載組件的邏輯。
主要邏輯發(fā)生在 defineAsyncComponent 內部的 loadingComponent 中:
我們使用 defineComponent 創(chuàng)建一個新組件,該組件包含一個渲染函數,用于在傳遞給 lazyLoadComponentIfVisible 的 div中渲染 loadingComponent。該渲染函數包含一個指向加載組件根元素的模板ref。
在 onMounted 中,我們會檢查 IntersectionObserver 是否受支持。如果不支持,我們將立即加載組件。否則,我們將創(chuàng)建一個 IntersectionObserver,用于觀察已加載組件的根元素,以檢測它何時變得可見。當組件變?yōu)榭梢姇r,我們會清理觀察者并加載組件。
現(xiàn)在,你可以使用該函數在組件可見時對其進行懶加載:
<script setup lang="ts">
import Loading from './components/Loading.vue';
import { lazyLoadComponentIfVisible } from './utils';
const LazyLoaded = lazyLoadComponentIfVisible({
componentLoader: () => import('./components/HelloWorld.vue'),
loadingComponent: Loading,
});
</script>
<template>
<LazyLoaded />
</template>總結
在本文中,我們學習了如何使用 Intersection Observer API 和 defineAsyncComponent 函數在 Vue 組件可見時對其進行懶加載。如果有一個包含許多組件的首頁,并希望改善應用程序的初始加載時間,這將非常有用。
到此這篇關于Vue組件懶加載的文章就介紹到這了,更多相關Vue組件懶加載內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue3.0搭配.net core實現(xiàn)文件上傳組件
這篇文章主要介紹了vue3.0搭配.net core實現(xiàn)文件上傳組件,幫助大家開發(fā)Web應用程序,完成需求,感興趣的朋友可以了解下2020-10-10
vue中手機號,郵箱正則驗證以及60s發(fā)送驗證碼的實例
下面小編就為大家分享一篇vue中手機號,郵箱正則驗證以及60s發(fā)送驗證碼的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03
vue采用EventBus實現(xiàn)跨組件通信及注意事項小結
EventBus是一種發(fā)布/訂閱事件設計模式的實踐。這篇文章主要介紹了vue采用EventBus實現(xiàn)跨組件通信及注意事項,需要的朋友可以參考下2018-06-06
element中TimePicker時間選擇器禁用部分時間(顯示禁用到分鐘)
這篇文章主要介紹了element中TimePicker時間選擇器禁用部分時間(顯示禁用到分鐘),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-03-03

