Vue插槽原理與用法詳解
本文實(shí)例講述了Vue插槽原理與用法。分享給大家供大家參考,具體如下:
1 插槽內(nèi)容
Vue 實(shí)現(xiàn)了一套內(nèi)容分發(fā)的 API,這套 API 基于當(dāng)前的 Web Components 規(guī)范草案,將 <slot> 元素作為承載分發(fā)內(nèi)容的出口。
它允許你像這樣合成組件:
<div id="app1">
<navigation-link url="/profile">
Your Profile
</navigation-link>
</div>
然后你在 <navigation-link> 的模板中可能會(huì)寫(xiě)為:
Vue.component('navigation-link', {
template: `
<a
v-bind:href="url" rel="external nofollow"
class="nav-link"
>
<slot></slot>
</a>
`
});
當(dāng)組件渲染的時(shí)候,這個(gè) <slot> 元素將會(huì)被替換為“Your Profile”。

插槽內(nèi)可以包含任何模板代碼,包括 HTML:
<navigation-link url="/profile"> <!-- 添加一個(gè) Font Awesome 圖標(biāo) --> <span class="fa fa-user"></span> Your Profile </navigation-link>
甚至其它的組件:
<navigation-link url="/profile"> <!-- 添加一個(gè)圖標(biāo)的組件 --> <font-awesome-icon name="user"></font-awesome-icon> Your Profile </navigation-link>
如果 <navigation-link> 沒(méi)有包含一個(gè) <slot> 元素,則任何傳入它的內(nèi)容都會(huì)被拋棄。
2 具名插槽
有些時(shí)候我們需要多個(gè)插槽。例如,一個(gè)假設(shè)的 <base-layout> 組件多模板如下:
<div class="container"> <header> <!-- 我們希望把頁(yè)頭放這里 --> </header> <main> <!-- 我們希望把主要內(nèi)容放這里 --> </main> <footer> <!-- 我們希望把頁(yè)腳放這里 --> </footer> </div>
對(duì)于這樣的情況,<slot> 元素有一個(gè)特殊的特性:name。這個(gè)特性可以用來(lái)定義額外的插槽:
<div class="container"> <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </div>
在向具名插槽提供內(nèi)容的時(shí)候,我們可以在一個(gè)父組件的 <template> 元素上使用 slot 特性:
<base-layout> <template slot="header"> <h1>Here might be a page title</h1> </template> <p>A paragraph for the main content.</p> <p>And another one.</p> <template slot="footer"> <p>Here's some contact info</p> </template> </base-layout>
另一種 slot 特性的用法是直接用在一個(gè)普通的元素上:
<base-layout> <h1 slot="header">Here might be a page title</h1> <p>A paragraph for the main content.</p> <p>And another one.</p> <p slot="footer">Here's some contact info</p> </base-layout>
我們還是可以保留一個(gè)未命名插槽,這個(gè)插槽是默認(rèn)插槽,也就是說(shuō)它會(huì)作為所有未匹配到插槽的內(nèi)容的統(tǒng)一出口。上述兩個(gè)示例渲染出來(lái)的 HTML 都將會(huì)是:
<div class="container"> <header> <h1>Here might be a page title</h1> </header> <main> <p>A paragraph for the main content.</p> <p>And another one.</p> </main> <footer> <p>Here's some contact info</p> </footer> </div>
3 默認(rèn)插槽的內(nèi)容
有的時(shí)候?yàn)椴宀厶峁┠J(rèn)的內(nèi)容是很有用的。例如,一個(gè) <submit-button> 組件可能希望這個(gè)按鈕的默認(rèn)內(nèi)容是“Submit”,但是同時(shí)允許用戶(hù)覆寫(xiě)為“Save”、“Upload”或別的內(nèi)容。
你可以在 <slot> 標(biāo)簽內(nèi)部指定默認(rèn)的內(nèi)容來(lái)做到這一點(diǎn)。
<button type="submit"> <slot>Submit</slot> </button>
如果父組件為這個(gè)插槽提供了內(nèi)容,則默認(rèn)的內(nèi)容會(huì)被替換掉。
4 編譯作用域
當(dāng)你想在插槽內(nèi)使用數(shù)據(jù)時(shí),例如:
<navigation-link url="/profile">
Logged in as {{ user.name }}
</navigation-link>
該插槽可以訪問(wèn)跟這個(gè)模板的其它地方相同的實(shí)例屬性 (也就是說(shuō)“作用域”是相同的)。但這個(gè)插槽不能訪問(wèn) <navigation-link> 的作用域。例如嘗試訪問(wèn) url 是不會(huì)工作的。牢記一條準(zhǔn)則:
父組件模板的所有東西都會(huì)在父級(jí)作用域內(nèi)編譯;子組件模板的所有東西都會(huì)在子級(jí)作用域內(nèi)編譯。
5 作用域插槽
2.1.0+ 新增
有的時(shí)候你希望提供的組件帶有一個(gè)可從子組件獲取數(shù)據(jù)的可復(fù)用的插槽。例如一個(gè)簡(jiǎn)單的 <todo-list> 組件的模板可能包含了如下代碼:
Vue.component('todo-list',{
template:`
<ul>
<li
v-for="todo in todos"
v-bind:key="todo.id">
{{ todo.text }}
</li>
</ul>
`
});
但是在我們應(yīng)用的某些部分,我們希望每個(gè)獨(dú)立的待辦項(xiàng)渲染出和 todo.text 不太一樣的東西。這也是作用域插槽的用武之地。
為了讓這個(gè)特性成為可能,你需要做的全部事情就是將待辦項(xiàng)內(nèi)容包裹在一個(gè) <slot> 元素上,然后將所有和其上下文相關(guān)的數(shù)據(jù)傳遞給這個(gè)插槽:在這個(gè)例子中,這個(gè)數(shù)據(jù)是 todo 對(duì)象:
<ul>
<li
v-for="todo in todos"
v-bind:key="todo.id"
>
<!-- 我們?yōu)槊總€(gè) todo 準(zhǔn)備了一個(gè)插槽,-->
<!-- 將 `todo` 對(duì)象作為一個(gè)插槽的 prop 傳入。-->
<slot v-bind:todo="todo">
<!-- 回退的內(nèi)容 -->
{{ todo.text }}
</slot>
</li>
</ul>
現(xiàn)在當(dāng)我們使用 <todo-list> 組件的時(shí)候,我們可以選擇為待辦項(xiàng)定義一個(gè)不一樣的<template> 作為替代方案,并且可以通過(guò) slot-scope 特性從子組件獲取數(shù)據(jù):
<todo-list v-bind:todos="todos">
<!--插槽作用域的名字是 slotProps-->
<template slot-scope="slotProps">
<!-- 為指定的待辦項(xiàng)定義一個(gè)模板-->
<span v-if="slotProps.todo.isComplete">✓</span>
{{ slotProps.todo.text }}
</template>
</todo-list>
在 2.5.0+,slot-scope 不再限制在 <template> 元素上使用,而可以用在插槽內(nèi)的任何元素或組件上。
解構(gòu) slot-scope
如果一個(gè) JavaScript 表達(dá)式在一個(gè)函數(shù)定義的參數(shù)位置有效,那么這個(gè)表達(dá)式實(shí)際上就可以被 slot-scope 接受。也就是說(shuō)你可以在支持的環(huán)境下 單文件組件或現(xiàn)代瀏覽器),在這些表達(dá)式中使用 ES2015 解構(gòu)語(yǔ)法。例如:
<todo-list v-bind:todos="todos">
<template slot-scope="{ todo }">
<span v-if="todo.isComplete">✓</span>
{{ todo.text }}
</template>
</todo-list>
這會(huì)使作用域插槽變得更干凈一些。
希望本文所述對(duì)大家vue.js程序設(shè)計(jì)有所幫助。
相關(guān)文章
關(guān)于vue-cli-service:command?not?found報(bào)錯(cuò)引發(fā)的實(shí)戰(zhàn)案例
這篇文章主要給大家介紹了關(guān)于vue-cli-service:command?not?found報(bào)錯(cuò)引發(fā)的相關(guān)資料,文中通過(guò)實(shí)例代碼將解決的過(guò)程介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2023-02-02
Vue3中使用styled-components的實(shí)現(xiàn)
本文主要介紹了Vue3中使用styled-components的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-05-05
Vue2?中自定義圖片懶加載指令?v-lazy實(shí)例詳解
這篇文章主要為大家介紹了Vue2?中自定義圖片懶加載指令?v-lazy實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
從Element日期組件源碼中學(xué)到的兩個(gè)工具方法技巧
這篇文章主要介紹了從Element日期組件源碼中學(xué)到的兩個(gè)工具方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08
關(guān)于Vue?"__ob__:Observer"屬性的解決方案詳析
在操作數(shù)據(jù)的時(shí)候發(fā)現(xiàn),__ob__: Observer這個(gè)屬性出現(xiàn)之后,如果單獨(dú)拿數(shù)據(jù)的值,就會(huì)返回undefined,下面這篇文章主要給大家介紹了關(guān)于Vue?"__ob__:Observer"屬性的解決方案,需要的朋友可以參考下2022-11-11
vue?跳轉(zhuǎn)頁(yè)面$router.resolve和$router.push案例詳解
這篇文章主要介紹了vue?跳轉(zhuǎn)頁(yè)面$router.resolve和$router.push案例詳解,這樣實(shí)現(xiàn)了既跳轉(zhuǎn)了新頁(yè)面,又不會(huì)讓后端檢測(cè)到頁(yè)面鏈接不安全之類(lèi)的,需要的朋友可以參考下2023-10-10
Vue報(bào)錯(cuò):Uncaught TypeError: Cannot assign to read only propert
這篇文章主要給大家介紹了關(guān)于Vue報(bào)錯(cuò):Uncaught TypeError: Cannot assign to read only property 'exports' of object '#<Object>' 的解決方法,文中介紹的非常詳細(xì),需要的朋友們下面來(lái)一起看看吧。2017-06-06
vue中@click和@click.native.prevent的區(qū)別
這篇文章主要介紹了vue中@click和@click.native.prevent的區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04
Vue-cli3 $ is not defined錯(cuò)誤問(wèn)題及解決
這篇文章主要介紹了Vue-cli3 $ is not defined錯(cuò)誤問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07
vite項(xiàng)目配置less全局樣式的實(shí)現(xiàn)步驟
最近想實(shí)現(xiàn)個(gè)項(xiàng)目,需要配置全局less,本文主要介紹了vite項(xiàng)目配置less全局樣式的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-02-02

