組件的相互嵌套slot內容分發


前面講了非父子組件

slot內容分發:為了讓組件可以組合,我們需要一種方式來混合父組件的內容與子組件自己的模板。

比如我們遇到組件需要相互嵌套這樣的情況:
App.vue 文件

<template> <div class="app"> <Hello> <World></World> <Vue></Vue> </Hello> </div> </template> 

Hello.vue 文件

<template> <div class="hello"> <h3>我是 hello 組件</h3> </div> </template> 

那這么直接寫是肯定只顯示 <Hello> 組件的內容

 
 

 

所以就需要用到 slot 插口,否則該組件標簽中的內容將會被丟棄

一、 單個插槽

只需要在 Hello.vue 文件內寫入 <solt></slot> 標簽

<template> <div class="hello"> <h3>我是 hello 組件</h3> <slot>此處可自定義內容,如果該組件的標簽內沒有內容,則顯示此內容</slot> </div> </template> 
 
 

注意:<solt></slot> 標簽內是可以自定義內容的,如果在調用的 <Hello></Hello> 標簽內沒有寫入任何內容,則顯示 <solt></slot> 標簽內的自定義內容,否則顯示在調用的 <Hello></Hello> 標簽內寫入的內容

二、多個插槽

假如我們想要改變 <Hello></Hello> 組件內 <World></World><Vue></Vue> 的顯示位置,就可以用到一個特殊的特性 name 來進一步配置如何分發內容,多個插槽可以有不同的名字。具名插槽將匹配內容片段中有對應 slot 特性的元素。仍然可以有一個匿名插槽,它是默認插槽,作為找不到匹配的內容片段的備用插槽。如果沒有默認插槽,這些找不到匹配的內容片段將被拋棄。

App.vue 文件

<template> <div class="app"> <Hello> <World slot="world"></World> <h5>我是備用插槽內部顯示的內容</h5> <Vue slot="vue"></Vue> </Hello> </div> </template> 

Hello.vue 文件

<template> <div class="hello"> <slot name="vue"></slot> <h3>我是 hello 組件</h3> <slot name="world"></slot> <slot></slot> </div> </template> 

最后渲染顯示為


 
 
三、作用域插槽
1. 作用域插槽是一種特殊類型的插槽,用作一個 (能被傳遞數據的) 可重用模板,來代替已經渲染好的元素。

在子組件中,slot 插槽還可以用作傳遞數據,類似於用 prop 來傳遞數據

在子組件 Hello.vue 中,只需要將需要傳遞的內容寫入插槽中

<template> <div class="hello"> <h3>我是 hello 組件</h3> <!-- text 和 text1 是自定義的,可以隨便寫 --> <slot text="我是hello" text1="組件的數據"></slot> </div> </template> 

<slot text="我是hello" text1="組件的數據"></slot> 相當於被渲染為

{
    text:'我是hello', text1:'組件的數據' } 

在 App.vue 中調用 Hello 組件時,通過在 template 中寫入 slot-scope 特殊屬性來獲取數據

<template> <div class="app"> <Hello> <!-- template 是該作用域插槽的模版, slot-scope是一個特殊屬性,用來接收 hello 組件中插槽傳過來的值 --> <template slot-scope="hello"> <!-- 通過訪問一個 json 的方式訪問 hello 中 slot 傳過來的值 --> <span>{{hello.text}} + {{hello.text1}}</span> </template> </Hello> </div> </template> 

注意:在 vue 2.5.0以上版本,就不需要用到 template 模板了,slot-scope 可以作用在任意元素中

被渲染的結果為:


 
 

 
 
2. 更典型的用例是在列表組件中,允許使用者自定義如何渲染列表的每一項

在 App.vue 組件內

<template> <div class="app"> <!-- 在子組件綁定 items 把父組件的數據傳給子組件 --> <Hello :items="items"> <li slot="item" slot-scope="bbb"> {{ bbb.text }} </li> </Hello> </div> </template> <script> // 引入 Hello 組件 import Hello from './assets/components/Hello.vue' export default { data(){ return { items:[ {text:'aaaaaa'}, {text:'bbbbb'} ] } }, // 注冊 Hello 組件 components:{ Hello } } </script> 

在 Hello.vue 組件中

<template> <div class="hello"> <ul> <!-- 此處的 items 為父組件傳過來的數據 --> <!-- text 為 item 內的對應數據,因為 items 是一個對象,所以要用到綁定,否則頁面上直接渲染出來的內容為 item.text --> <slot name="item" v-for="item in items" text="item.text"></slot> </ul> </div> </template> <script> export default { // 接收父組件傳過來的 items 數據 props: ['items'], } </script> 

渲染結果為:


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM