插槽基本介紹 在開發中,我們會經常封裝一個個可復用的組件: 前面我們會通過props傳遞給組件一些數據,讓組件來進行展示; 但是為了讓這個組件具備更強的通用性,我們不能將組件中的內容限製為固定的div、span等等這些元素; 比如某種情況下我們使用組件,希望組件顯示的是一個按鈕,某種情況下我們使用組 ...
插槽基本介紹
在開發中,我們會經常封裝一個個可復用的組件:
- 前面我們會通過props傳遞給組件一些數據,讓組件來進行展示;
- 但是為了讓這個組件具備更強的通用性,我們不能將組件中的內容限製為固定的div、span等等這些元素;
- 比如某種情況下我們使用組件,希望組件顯示的是一個按鈕,某種情況下我們使用組件希望顯示的是一張圖片;
- 我們應該讓使用者可以決定某一塊區域到底存放什麼內容和元素;
舉個慄子:假如我們定製一個通用的導航組件 - NavBar
- 這個組件分成三塊區域:左邊-中間-右邊,每塊區域的內容是不固定;
- 左邊區域可能顯示一個菜單圖標,也可能顯示一個返回按鈕,可能什麼都不顯示;
- 中間區域可能顯示一個搜索框,也可能是一個列表,也可能是一個標題,等等;
- 右邊可能是一個文字,也可能是一個圖標,也可能什麼都不顯示;
這個時候我們就可以來定義插槽slot:
- 插槽的使用過程其實是抽取共性、預留不同;
- 我們會將共同的元素、內容依然在組件內進行封裝;
- 同時會將不同的元素使用slot作為占位,讓外部決定到底顯示什麼樣的元素;
如何使用slot呢?
- Vue中將 <slot> 元素作為承載分發內容的出口;
- 在封裝組件中,使用特殊的元素<slot>就可以為封裝組件開啟一個插槽;
- 該插槽插入什麼內容取決於父組件如何使用;
插槽基本使用
<!-- 1、在子組件中插入插槽 --> <template> <div class="show-message"> <h2>{{ title }}</h2> <!-- 使用插槽,插槽內可寫預設內容 --> <slot>
<p>我是內容1</p>
</slot> </div> </template> <!-- 2、插槽部分想要展示什麼內容由父元素進行決定,如果插槽沒有 插入東西, 那麼這個插槽會被忽略或顯示預設內容 --> <template> <div class="app"> <!-- 內容是p元素展示 --> <show-message title="哈哈哈哈"> <p>我是內容1</p> </show-message> <!-- 內容是button元素展示 --> <show-message title="呵呵呵呵"> <button>我是內容2</button> </show-message> <!-- 內容是h2元素展示 --> <show-message title="嘿嘿嘿嘿"> <h3>我是內容3</h3> </show-message> </div> </template>
具名插槽使用
// 子組件 <template> <div class="nav-bar"> <div class="left"> <slot name="left">left</slot> </div> <div class="content"> <slot name="content">content</slot> </div> <div class="right"> <slot name="right">right</slot> </div> </div> </template> // 父組件--- v-slot:left 可簡寫成 #left <template> <div class="app"> <nav-bar> <template #left> <button>返回</button> </template> <template #content> <span>內容</span> </template> <template #right> <a href="#">登錄</a> </template> </nav-bar> </div> </template>
動態插槽名稱
<!-- 可以通過 v-slot:[dynamicSlotName]方式動態綁定一個名稱 --> <template> <div class="app"> <!-- 設置動態插槽名, 插槽名稱又name這個變數動態控制 --> <nav-bar v-slot:[name]> <a href="#">註冊</a> </nav-bar> </div> </template>
作用域插槽
<!-- 子組件中在插槽中傳遞出要使用的數據 --> <template> <div show-data> <div v-for="(item, index) in titles" :key="index"> <!-- 包裹一個插槽, 通過插槽將子組件的數據傳遞給父組件 --> <!-- 可以傳遞多個數據 --> <slot :item="item" abc="abc"> <h2>{{ item }}</h2> </slot> </div> </div> </template> <!-- 父組件使用v-slot:插槽名=接收數據變數名來進行接收, 此時可以將h2元素換成其他元素進行替換 --> <template> <div class="app"> <show-data :titles="titles" > <!-- 接收傳遞過來的數據 --> <template v-slot:default="props"> <!-- 將h2元素替換為button, 並展示傳遞過來的數據 --> <button>{{ props.item }}</button> </template> </show-data> </div> </template>