Vue3插槽(slot)使用方法詳解
前言-認(rèn)識(shí)slot
我們經(jīng)常會(huì)有封裝組件的需求, 組件需要的往往不只有數(shù)據(jù), 有時(shí)候我們要給一個(gè)模塊做內(nèi)容方面的可自定義, 比如我封裝了一個(gè)黑板, 但是我有時(shí)希望上面是字, 又有時(shí)希望上面是圖畫, 這就要用到插槽了.
感謝你浪費(fèi)一分鐘生命讀完了這段廢話.
一、簡(jiǎn)單插槽
就是普通插槽, 也叫默認(rèn)插槽.
只要你在子組件里寫一個(gè)< slot></ slot>就可以從父組件向內(nèi)部填充了.
雖然簡(jiǎn)單但是不寫slot也是不能直接從父組件插內(nèi)容的.
子組件:
<template> <div class="sy-page"> <slot></slot> </div> </template>
父組件:
<template> <sy-turning>BaiX</sy-turning> </template>
缺點(diǎn)就是不能規(guī)定父組件填充內(nèi)容所指向的插槽, 父組件內(nèi)填充的所有內(nèi)容, 會(huì)填充到每個(gè)子組件內(nèi)的插槽中:
子組件:
<template> <div class="sy-page"> <slot></slot> <a href=""><slot></slot></a> </div> </template>
父組件:
<template> <sy-turning>BaiX</sy-turning> </template>
要解決這個(gè)問(wèn)題 就需要具名插槽了.
二、具名插槽
特點(diǎn)是帶有name屬性:
<slot name="xxx"></slot>
有時(shí)我們會(huì)需要在子組件某處寫一堆的插槽,又需要在父組件各處分別使用這些插槽.
某些方面計(jì)算機(jī)是很笨的,它不會(huì)看得出哪個(gè)插槽該填什么東西,也不知道你在這里填的東西是要給哪個(gè)插槽, 你得告訴她該怎么做.
只要有使用多個(gè)插槽的需求, 那就用具名插槽吧.
先來(lái)看看子組件:
<!--子組件 --> <div class="tab-bar-item"> <slot name="item-icon"></slot> <slot name="item-text"></slot> <!-- 插槽slot最終會(huì)被父組件里傳入的html元素替換, 在插槽上寫樣式類的東西不會(huì)生效,可以用div來(lái)包裹slot, 利用樣式繼承性來(lái)完成樣式修改 -->
父組件
< template>來(lái)包裹要向插槽里填充的東西, 在template標(biāo)簽的v-slot屬性后面寫上對(duì)應(yīng)插槽的name值.
v-slot:可以簡(jiǎn)寫為"#"
<!--父組件 --> <tab-bar-item> <template v-slot:item-icon> <div>插槽item-icon內(nèi)容<img src="#" /></div> </template> <template #item-text> <div>插槽item-text內(nèi)容</div> </template> </tab-bar-item>
這樣所有在template包裹下的填充內(nèi)容都會(huì)被填入對(duì)應(yīng)的插槽,但如果沒(méi)有被template包裹呢?
那樣就相當(dāng)于寫了個(gè)這:
<template> <!--隱含的名字“default”(默認(rèn)) --> <p>我會(huì)被填入子組件的每個(gè)插槽</p> </template>
Vue官方文檔: 沒(méi)有被包裹在帶有 v-slot: 的 < template> 中的內(nèi)容都會(huì)被視為默認(rèn)插槽內(nèi)容.
具名插槽擴(kuò)展-動(dòng)態(tài)插槽名
從 2.6.0 開(kāi)始,可以用方括號(hào)括起來(lái)的JS表達(dá)式作為一個(gè)指令(v-bind啥的)的參數(shù),比如在此例中
//隨便定義一個(gè)方法randomName, 使用這個(gè)方法的返回值; <a v-bind:[randomName]="user"> ... </a>
其實(shí)這個(gè)東西最常見(jiàn)的是在封裝組件時(shí), 我們用computed里的方法返回值來(lái)控制:class和:style:
<button :class="[theme, isBorder]" ></button>
computed: { theme() { return this.type ? `sy-button-${this.type}` : ""; }, isBorder() { return this.border ? "is-border" : ""; }, }
在2.6版本新增的內(nèi)容中, 這種用法(動(dòng)態(tài)指令參數(shù))也可以用在具名插槽上定義動(dòng)態(tài)的插槽名, 這其實(shí)是具名插槽的擴(kuò)展用法, 你可以先看看具名插槽.
<base-layout> <template v-slot:[動(dòng)態(tài)指令參數(shù)]> 動(dòng)態(tài)決定插入哪個(gè)插槽 </template> </base-layout>
三、作用域插槽
父組件內(nèi)需要訪問(wèn)子組件中的數(shù)據(jù)以正常工作, 可以作用域插槽.
作用域插槽的渲染是在子組件完成, 所以我們也需要子組件的數(shù)據(jù).
在子組件的slot上利用v-bind / v-for之類綁定上父組件需要的各種數(shù)據(jù), 渲染時(shí)就可以從子組件拿數(shù)據(jù)來(lái)渲染.
綁定在 < slot> 上的屬性被Vue官方稱為"slotProps"(這并不重要);
子組件:
<span class="current-user"> <slot :user="data.user"></slot> </span> <!-- 或者 --> <span v-for="item in data.someThing" :key="item"> <slot :num="item.num" :awsl="item.id"></slot> </span>
在父組件內(nèi)使用v-slot屬性接收子組件數(shù)據(jù);
父組件
<current-user> <template v-slot="{ user, name }"> <!--其實(shí)這里寫的參數(shù)是什么真的無(wú)所謂, 比如我子組件傳出item, 父組件要接收item.id, 寫v-slot="awsl.id"接收也可以--> </template> </current-user> <!--或者 --> <current-user> <template v-slot="num"> <!-- 只傳一個(gè)時(shí)不要加大括號(hào). --> </template> </current-user>
作用域插槽會(huì)被解析為一個(gè)傳入了slotProps作參的函數(shù):
function (slotProps) { // 插槽內(nèi)容 }
所以, 父組件中v-slot: 的值實(shí)際上可以是任何 [能作為函數(shù)的參數(shù)來(lái)傳入] 的東西;
作用域插槽實(shí)例
我現(xiàn)在二次封裝一個(gè)el-tabs, 實(shí)現(xiàn)傳入數(shù)據(jù)數(shù)組自動(dòng)生成:
子組件:
<div class="sy_tabs"> <el-tabs> <el-tab-pane v-for="item in sy_tab_data" :key="item" :label="item.label" :name="item.name" > <slot :item="item"></slot> <!--然后我們直接在這里吧item傳出去,傳作"item" </el-tab-pane> </el-tabs> </div>
//我想了一下還是不要用props接收了, 我們直接把標(biāo)簽頁(yè)數(shù)據(jù)寫死吧... export default { setup() { const sy_tab_data = [ { label: "推薦", name: "first", id: 0 }, { label: "熱門", name: "second", id: 1 }, { label: "關(guān)注", name: "third", id: 2 }, ], } }
這樣我們有三個(gè)標(biāo)簽頁(yè)了:
父組件:
為了根據(jù)不同標(biāo)簽頁(yè)顯示不同的內(nèi)容, 這里我們要拿到tab標(biāo)簽頁(yè)的id, 來(lái)決定 “在id為幾的標(biāo)簽頁(yè)顯示article_content的哪個(gè)子數(shù)組”
<sy-tabs> <template v-slot="slotProps"> <!--然后你可以看到, 我們?cè)谶@里用slotProps來(lái)接收item, 沒(méi)有任何問(wèn)題, 也能拿到里面的id屬性(見(jiàn)下); --> <ul> <li v-for="i in data.article_content[slotProps.item.id]" :key="i" > <!--這樣把a(bǔ)rticle_content的序號(hào)和tab的序號(hào)對(duì)應(yīng)起來(lái), 實(shí)現(xiàn)第2頁(yè)顯示第2個(gè)數(shù)組, 第3頁(yè)顯示第3個(gè)數(shù)組 --> </li> </ul> </template> </sy-tabs>
let data = reactive({ article_content: [ [xxx, xxx], //詳細(xì)數(shù)據(jù)略 [xxx, xxx], [xxx, xxx], ] })
就可以正常呈現(xiàn)了:
總結(jié)
注意 v-slot 只能添加在 < template> 上, 不然會(huì)標(biāo)紅;
我為什么要把這些玩意兒寫在插槽里, 這么麻煩為什么不直接寫那些標(biāo)簽?
是,我一開(kāi)始也在問(wèn)我自己, 為什么不直接寫標(biāo)簽而要寫插槽.
(現(xiàn)在是22年4月22, 我剛做完我的個(gè)人網(wǎng)站, 回來(lái)說(shuō)一句, 不封裝實(shí)在是——太亂了代碼很多,就算復(fù)制粘貼下來(lái)到別處還要改屬性改參數(shù)改樣式,主要是還要改樣式,老天!做了三個(gè)頁(yè)面我就開(kāi)始封裝了。)
到此這篇關(guān)于Vue3插槽(slot)使用方法的文章就介紹到這了,更多相關(guān)Vue3插槽使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue中PC端使用高德地圖實(shí)現(xiàn)搜索定位、地址標(biāo)記、彈窗顯示定位詳情(完整實(shí)例)
這篇文章主要介紹了vue中PC端使用高德地圖實(shí)現(xiàn)搜索定位、地址標(biāo)記、彈窗顯示定位詳情,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07vue項(xiàng)目開(kāi)發(fā)環(huán)境工具node搭建過(guò)程
最近在開(kāi)始接觸做vue框架的前端項(xiàng)目,以前用的前端比如html,js,css等都是比較原生的,寫好后直接瀏覽器打開(kāi)就行,今天就先記錄一下vue的開(kāi)發(fā)運(yùn)行搭建過(guò)程,感興趣的朋友一起看看吧2023-09-09淺談vue單頁(yè)面中有多個(gè)echarts圖表時(shí)的公用代碼寫法
這篇文章主要介紹了淺談vue單頁(yè)面中有多個(gè)echarts圖表時(shí)的公用代碼寫法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07實(shí)現(xiàn)vuex與組件data之間的數(shù)據(jù)同步更新方式
今天小編就為大家分享一篇實(shí)現(xiàn)vuex與組件data之間的數(shù)據(jù)同步更新方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11vue中datepicker的使用教程實(shí)例代碼詳解
這篇文章主要介紹了vue-datepicker的使用,本文通過(guò)實(shí)例代碼大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07vite build vue3項(xiàng)目配置開(kāi)啟sourcemap方式
這篇文章主要介紹了vite build vue3項(xiàng)目配置開(kāi)啟sourcemap方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06vue實(shí)現(xiàn)列表滾動(dòng)的過(guò)渡動(dòng)畫
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)列表滾動(dòng)的過(guò)渡動(dòng)畫,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06