1、插槽的基本使用
在子组件内使用特殊的 <slot> 元素就可以为这个子组件开启一个 slot(插槽);
在父组件模板里,插入在子组件标签内的所有内容将替代子组件的<slot>
子组件 Learn.vue :
<template>
<div class="container">
<slot>
<!-- 用一个 <p> 标签作为插槽的默认内容 -->
<p>如果父组件没有插入内容,我将作为默认出现</p>
</slot>
</div>
</template>
<script>
export default {
name: "Learn",
data() {
return {
}
}
}
</script>
父组件 App.vue :
<template>
<div id="app">
<Learn>
<!-- 该部分内容将替代子组件的 <slot> 标签及它的内容 -->
<template>
<div class="slot">
<p>这是分发的内容</p>
</div>
</template>
</Learn>
</div>
</template>
<script>
// 导入组件
import Learn from "./components/Learn"
export default {
name: "App",
components: {
Learn // 注入
},
data() {
return {
}
}
};
</script>

2、具名插槽的使用
<template>
<div class="container">
<div class="header">
<!-- 名称为 header 的插槽 -->
<slot name="header"></slot>
</div>
<div class="main">
<!-- 无具体名称的插槽 -->
<slot></slot>
</div>
<div class="footer">
<!-- 名称为 footer 的插槽 -->
<slot name="footer"></slot>
</div>
</div>
</template>
<script>
export default {
name: "Learn",
data() {
return {
}
}
}
</script>
父组件 App.vue :
<template>
<div id="app">
<Learn>
<!-- 分发到子组件的 header 插槽 -->
<h2 slot="header">标题</h2>
<!-- 分发到子组件无具体名称插槽 -->
<p>正文内容</p>
<p>更多正文内容</p>
<!-- 分发到子组件的 footer 插槽 -->
<div slot="footer">底部信息</div>
</Learn>
</div>
</template>
<script>
// 导入组件
import Learn from "./components/Learn"
export default {
name: "App",
components: {
Learn // 注入
},
data() {
return {
}
}
};
</script>

3、作用域插槽
作用域插槽是一种特殊的 slot,从概念上不是很好理解,直接看示例代码:
父组件 App.vue :
<template>
<div id="app">
<Learn>
<!-- props 为一个临时变量,可以随便定义,通过该变量可以访问来自子组件插槽的数据msg -->
<template slot-scope="props">
<p>来自父组件的内容</p>
<p>{{ props.msg }}</p>
</template>
</Learn>
</div>
</template>
<script>
// 导入组件
import Learn from "./components/Learn"
export default {
name: "App",
components: {
Learn // 注入
},
data() {
return {
}
}
};
</script>
子组件 Learn.vue :
<template>
<div class="container">
<slot msg="来自子组件的内容"></slot>
</div>
</template>
<script>
export default {
name: "Learn",
data() {
return {
}
}
}
</script>

一份相同的数据(子组件插槽提供数据),在不同的地方,显示出不同效果时(比如不同的父组件,使用不同的UI样式,引用的都是同一个插槽),可能就会用到作用域插槽。
在 2.5.0+,slot-scope 不再限制在 <template>
参考:
《Vue.js实战》