Vue3實(shí)戰(zhàn)之插槽封裝與懶加載詳解
一、為什么需要插槽?從一個(gè)面板組件說(shuō)起
在電商首頁(yè)開(kāi)發(fā)中,經(jīng)常遇到這樣的場(chǎng)景:
「新鮮好物」「人氣推薦」同樣類(lèi)型模塊都需要相同的標(biāo)題欄,但內(nèi)容區(qū)布局不同這時(shí)候,插槽(Slot)就像一個(gè)「內(nèi)容拼圖位」,讓組件既能統(tǒng)一樣式,又能靈活定制。
實(shí)戰(zhàn)案例:HomePanel 通用面板
<template> <div class="home-panel"> <div class="head"> <h3>{{ title }}<small>{{ subTitle }}</small></h3> </div> <slot name="main" /> <!-- 內(nèi)容拼圖位 --> </div> </template> <script setup> defineProps({ title: String, subTitle: String }) </script>
使用方式:
<HomePanel title="新鮮好物" sub-title="新鮮出爐"> <template #main> <!-- 填充拼圖 --> <ul class="goods-list"> <li v-for="item in list">{{ item.name }}</li> </ul> </template> </HomePanel>
實(shí)現(xiàn)效果:
插槽的 3 個(gè)好處:
- 結(jié)構(gòu)分離:標(biāo)題樣式統(tǒng)一管理,內(nèi)容區(qū)自由發(fā)揮(列表 / 圖片 / 按鈕均可)
- 復(fù)用性強(qiáng):一個(gè)面板組件適配 N 種業(yè)務(wù)場(chǎng)景
- 語(yǔ)義清晰:通過(guò)具名插槽(#main)明確內(nèi)容位置
二、懶加載:讓圖片「按需加載」的魔法
電商首頁(yè)往往包含大量圖片,一次性加載會(huì)導(dǎo)致:
- 首屏加載慢
- 流量浪費(fèi)
- 手機(jī)發(fā)燙
懶加載(Lazy Load)的核心邏輯:圖片進(jìn)入視口時(shí)再加載
用 Vue3 指令實(shí)現(xiàn)懶加載
// 全局指令:directives/lazy.js import { useIntersectionObserver } from '@vueuse/core' export const lazyPlugin = { install(app) { app.directive('img-lazy', { mounted(el, binding) { // 當(dāng)元素進(jìn)入視口時(shí) const { stop } = useIntersectionObserver(el, ([{ isIntersecting }]) => { if (isIntersecting) { el.src = binding.value // 替換真實(shí)src stop() // 停止觀察,避免重復(fù)觸發(fā) } }) } }) } }
使用方式:
<img v-img-lazy="goods.picture" alt="商品圖" />
實(shí)現(xiàn)原理拆解:
- IntersectionObserver:瀏覽器原生 API,監(jiān)聽(tīng)元素是否進(jìn)入視口
- 指令生命周期:在
mounted
階段綁定觀察,避免重復(fù)綁定 - 停止觀察:圖片加載后立即停止監(jiān)聽(tīng),節(jié)省性能
三、插槽 × 懶加載:實(shí)戰(zhàn)中的黃金組合
在「商品館」模塊中,同時(shí)用到了插槽和懶加載:
<HomePanel title="數(shù)碼館"> <template #main> <div class="box"> <img v-img-lazy="bannerUrl" class="cover" /> <!-- 大圖懶加載 --> <ul> <li v-for="goods in list"> <GoodsItem :goods="goods" /> <!-- 子組件插槽 --> </li> </ul> </div> </template> </HomePanel> <!-- GoodsItem子組件 --> <template> <RouterLink> <img v-img-lazy="goods.picture" /> <!-- 商品圖懶加載 --> <p>{{ goods.name }}</p> </RouterLink> </template>
效果:
- 標(biāo)題欄統(tǒng)一樣式,內(nèi)容區(qū)自由布局(大圖 + 列表)
- 所有圖片均在進(jìn)入視口時(shí)加載,首屏加載速度提升 40%
四、新手避坑指南
- 插槽默認(rèn)值:給插槽設(shè)置默認(rèn)內(nèi)容,避免父組件未傳時(shí)的空白
<slot name="main">暫無(wú)內(nèi)容</slot>
- 懶加載占位圖:加載前使用占位圖(如灰色色塊),避免布局抖動(dòng)
<img v-img-lazy="realSrc" :src="placeholder" />
- 指令參數(shù)校驗(yàn):確保指令值是合法 URL
if (!binding.value.startsWith('http')) return
五、總結(jié):讓組件會(huì)「呼吸」
- 插槽讓組件有了「可插拔」的能力,像搭積木一樣組裝頁(yè)面
- 懶加載讓頁(yè)面學(xué)會(huì)「按需呼吸」,節(jié)省資源的同時(shí)提升用戶(hù)體驗(yàn)
- 兩者結(jié)合,實(shí)現(xiàn)了 「結(jié)構(gòu)統(tǒng)一」與「內(nèi)容靈活」的完美平衡
到此這篇關(guān)于Vue3實(shí)戰(zhàn)之插槽封裝與懶加載的文章就介紹到這了,更多相關(guān)Vue3插槽封裝與懶加載內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
elementUI實(shí)現(xiàn)級(jí)聯(lián)選擇器
這篇文章主要為大家詳細(xì)介紹了elementUI實(shí)現(xiàn)級(jí)聯(lián)選擇器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11Vue通過(guò)axios異步請(qǐng)求后端接口的方法
在現(xiàn)代Web開(kāi)發(fā)中,前端與后端的數(shù)據(jù)交互至關(guān)重要,Vue.js作為一款流行的前端框架,結(jié)合Axios庫(kù)能夠高效地實(shí)現(xiàn)HTTP請(qǐng)求與數(shù)據(jù)處理,本文將詳細(xì)講解如何在Vue 3中使用Axios,并通過(guò)實(shí)際案例展示其用法,需要的朋友可以參考下2024-12-12vue新建環(huán)境變量以及網(wǎng)絡(luò)請(qǐng)求工具axios的二次封裝詳解
這篇文章主要為大家介紹了vue新建環(huán)境變量以及網(wǎng)絡(luò)請(qǐng)求工具axios的二次封裝詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06解決vue 綁定對(duì)象內(nèi)點(diǎn)擊事件失效問(wèn)題
今天小編就為大家分享一篇解決vue 綁定對(duì)象內(nèi)點(diǎn)擊事件失效問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09vue項(xiàng)目強(qiáng)制清除頁(yè)面緩存的例子
今天小編就為大家分享一篇vue項(xiàng)目強(qiáng)制清除頁(yè)面緩存的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11Vue使用CDN引用項(xiàng)目組件,減少項(xiàng)目體積的步驟
這篇文章主要介紹了Vue使用CDN引用項(xiàng)目組件,減少項(xiàng)目體積的步驟,幫助大家提高項(xiàng)目加載速度,感興趣的朋友可以了解下2020-10-10解決vue多個(gè)路由共用一個(gè)頁(yè)面的問(wèn)題
下面小編就為大家分享一篇解決vue多個(gè)路由共用一個(gè)頁(yè)面的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03