## 一:插槽內容
**插槽是指把任意內容插入指定的位置,而這個位置使用`<slot>`作為占位符。**
```
//父組件中
<navigation-link url="/profile">
Your Profile
</navigation-link>
```
```
//navigation-link組件
<a v-bind:href="url"class="nav-link">
<slot></slot> /`Your Profile`被渲染到這里
</a>
```
當組件渲染的時候,`<slot></slot>`將會被替換為“Your Profile”。插槽內可以包含任何模板代碼包括 `HTM`:
```
<navigation-link url="/profile">
// 添加一個 Font Awesome 圖標
<span class="fa fa-user"></span>
Your Profile
</navigation-link>
```
> 如果`<navigation-link>`組件**沒有**定義插槽,則`<navigation-link>`中的內容將不會被渲染。
## 二:編譯作用域
當你想在一個插槽中使用數據時,例如:
~~~
<child >
<p>{{name}}</p> //name是父級的數據,會被編譯為'Jack'并傳遞給子組件中的插槽
//但是在這里無法訪問子組件的數據,想要訪問子組件的數據需要使用作用域插槽:slot-scope,新語法為v-slot
</child>
export default {
data () {
return {
name: 'Jack'
}
}
}
~~~
子組件中:
```
<template>
<div class="slottwo">
<slot></slot> //會渲染出Jack
</div>
</template>
```
>[info] 父級模板里的所有內容都是在父級作用域中編譯的;子模板里的所有內容都是在子作用域中編譯的。
## 三:默認內容
**在插槽中設置默認內容**:
```
<button type="submit">
<slot>Submit</slot> //插槽中默認有Submit字符
</button>
```
如果沒有使用插槽,則默認會渲染出`Submit`:
```
<submit-button></submit-button>
```
默認渲染`Submit`字符:
```
<button type="submit">
Submit
</button>
```
## 三:具名插槽
**具名插槽就是給插槽定義一個名字即name屬性,這樣當有多個插槽時可以把指定的內容插入到指定的插槽中。**
`base-layout`組件:
```
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
```
> 一個不帶`name`的`<slot>`出口會帶有隱含的名字“default”。
```
<base-layout>
<template v-slot:header> //插入到name為header的插槽中
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p> //插入到默認插槽中
<p>And another one.</p>
<template v-slot:footer>//插入到name為footer的插槽中
<p>Here's some contact info</p>
</template>
</base-layout>
```
**具名插槽的縮寫:**
```
<base-layout>
<template #header>//等價v-slot:header
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>//等價v-slot:default
<p>And another one.</p>
<template #footer>//等價v-slot:footer
<p>Here's some contact info</p>
</template>
</base-layout>
```
## 四: [作用域插槽](https://cn.vuejs.org/v2/guide/components-slots.html#%E4%BD%9C%E7%94%A8%E5%9F%9F%E6%8F%92%E6%A7%BD "作用域插槽")
**作用域插槽是用來獲取子組件的數據。**
例如`<current-user>`組件:
~~~
<span>
<slot>{{ user.lastName }}</slot>
</span>
export default {
data () {
return {
user:{lastName :'Jack'}
}
}
}
~~~
**當父組件想要使用`user`數據,就需要使用作用域插槽。在插槽中綁定屬性傳遞數據,然后在父組件中使用`slot-scope`(即將廢棄)或者使用`v-slot:default`接收數據**
1.在子組件中綁定屬性:
```
<span>
<slot :user="user"> //綁定屬性傳遞數據
{{ user.lastName }}
</slot>
</span>
export default {
data () {
return {
user:{lastName :'Jack'}
}
}
}
```
2.在父組件中接收數據:
```
<current-user>
<template v-slot:default="slotProps"> //也可以使用slot-scope="slotProps",vue3.0將不支持此語法
{{ slotProps.user.firstName }} //變量名隨便起,此處slotProps變量代表user數據
</template>
</current-user>
```
**獨占默認插槽的縮寫語法**
>[danger] 當子組件只**提供默認插槽**時,就可以使用作用域插槽縮寫的形式,如果提供了具名插槽就無法使用縮寫形式。
```
<current-user v-slot="slotProps">//此處的v-slot="slotProps"是作用域插槽的縮寫
{{ slotProps.user.firstName }}
</current-user>
```
**如果存在具名插槽無法使用縮寫形式**
## 五:作用域插槽的解構賦值
`child`組件中,傳遞一個user對象:
```
<span>
<slot :user="user"> //綁定屬性傳遞數據
{{ user.name }}
</slot>
</span>
export default {
data () {
return {
user:{name:'張三',age:18}
}
}
}
```
父組件中:
```
<template v-slot:default="slotProps">
{{ slotProps }} //{ user:{ "name": "張三", "age": 18 }}
</template>
```
有時候我們只需要值`{ "name": "張三", "age": 18 }`,而不需要鍵名`user`,則可以使用對象的解構賦值。
```
//等價于 let {user:user} = { user:{ "name": "張三", "age": 18 }}
<template v-slot:default="{ user }">
{{ user}} //{ "name": "張三", "age": 18 }
</template>
```