插槽可以让组件的使用者来决定组件中的某一块区域到底存放什么元素和内容。
使用插槽:
插槽的使用过程其实就是抽取共性、预留不同。将共同的元素、内容依然留在组件内进行封装;将不同的元素使用 slot 作为占位,让外部决定到底显示什么样的元素。
// App.vue
<template>
<!-- 2. 在父组件中调用子组件时,子组件开始标签和结束标签之间的内容将会被插入到子组件中插槽中 -->
<AppContent>
<button>按钮</button>
</AppContent>
<AppContent>
<a href="http:www.com">百度一下</a>
</AppContent>
</template>
<script>
import AppContent from './components/AppContent'
export default {
components: {
AppContent,
}
}
</script>
<style scoped>
</style>
// AppContent.vue
<template>
<div>
<h1>内容标题</h1>
<!-- 在子组件中预留插槽 -->
<slot></slot>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
</style>
插槽的默认内容:
<slot></slot>
元素开始标签和结束标签之间的内容会作为插槽的默认内容,插槽的默认内容只会在没有提供插入的内容时显示。
// App.vue
<template>
<!-- 在父组件中调用子组件时,不提供插槽的内容 -->
<AppContent />
</template>
<script>
import AppContent from './components/AppContent'
export default {
components: {
AppContent,
}
}
</script>
<style scoped>
</style>
// AppContent.vue
<template>
<div>
<h1>内容标题</h1>
<slot>
<!-- <slot></slot> 开始标签和结束标签之间的内容会作为插槽的默认内容显示 -->
<div>这是插槽的默认内容</div>
</slot>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
</style>
具名插槽:
具名插槽:就是给插槽命名,通过 <slot>
元素的 name 属性可以给插槽命名。这样当一个组件中有多个插槽时,就可以区分出来要插入的内容是要插入哪个插槽中。
一个不带 name 的插槽,默认隐含的名字是 default。
// App.vue
<template>
<NavBar>
<!-- 2. 在父组件中,使用 template 元素包裹要插入到插槽中的内容,通过 v-slot:插槽的名称 来决定要插入哪个插槽中 -->
<!-- v-slot:[变量名] 可以通过这种方式来动态地绑定插槽的名称 -->
<!-- v-slot 的缩写为 # -->
<template v-slot:left>
<button>返回</button>
</template>
<template v-slot:center>
<input />
</template>
<template v-slot:right>
<button>搜索</button>
</template>
</NavBar>
</template>
<script>
import NavBar from './components/NavBar'
export default {
components: {
NavBar,
}
}
</script>
<style scoped>
</style>
// NavBar.vue
<template>
<div class='navbar'>
<div class="left">
<!-- 1. 在子组件中通过 name 属性给插槽命名 -->
<slot name="left"></slot>
</div>
<div class="center">
<slot name="center"></slot>
</div>
<div class="right">
<slot name="right"></slot>
</div>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
</style
作用域插槽:
作用域插槽的核心就是能够将子组件中的数据传递给父组件的插槽来使用。
// App.vue
<template>
<AppContent>
<!-- 2. 在父组件中,使用 template 元素包裹要插入到插槽中的内容,通过 v-slot:插槽名称="slotProps" 可以获取到子组件中指定插槽传递过来的数据 -->
<template v-slot:default="slotProps">
<p>{{ slotProps.content }}</p>
</template>
</AppContent>
</template>
<script>
import AppContent from './components/AppContent'
export default {
components: {
AppContent,
}
}
</script>
<style scoped>
</style>
// AppContent.vue
<template>
<div>
<h1>子组件的标题</h1>
<!-- 1. 在子组件中,通过给 slot 元素添加属性的方式给父组件传递数据 -->
<slot content="子组件的内容"></slot>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
</style>