具名插槽
// input.vue input组件
<template>
<slot name="left"></slot>
<input type="text" />
<slot name="right"></slot>
</template>
// home.vue
<template>
<input>
<div #left>我是左边的插槽</div>
<div #right>我是右边的插槽</div>
</input>
</template>
<script>
// 导入组件
import input from '@/components/input'
export default {
components: { input }
}
</script>
作用域插槽
把子组件的值传递到父组件使用
// 子组件
<template>
<slot name="header" :user='user'></slot>
</template>
<script>
export default {
data () {
return {
user: {
name: 'jack'
}
}
}
}
</script>
// 父组件
<template>
// #header='{ user }' 这里使用了es6的解构赋值
<div #header='{ user }'>
{{ user.name }}
</div>
</template>
动态创建插槽
根据父组件传入的插槽数量来动态创建
about.vue 子组件页面
<template>
<div class="about">
<h1>This is an about page</h1>
<div>
<slot v-for="(item,name) in slots" :name="name" :postData="postData"></slot>
</div>
</div>
</template>
<script setup>
import { getCurrentInstance, onMounted, reactive, ref } from 'vue'
let app = getCurrentInstance()
const props = defineProps({
age:Number
})
let slots = reactive(app.slots)
let postData = reactive({
name: '张三',
age: 18
})
onMounted(() => {
console.log(11111, app.attrs)
console.log(22222, app.slots)
})
</script>
<style>
@media (min-width: 1024px) {
.about {
min-height: 100vh;
display: flex;
align-items: center;
}
}
</style>
home.vue 父组件页面
<script setup lang="ts"></script>
<template>
<main>
<about-view title="我是动态传入的" :age="18">
<template #header="{postData}">
<div class="list">
我是插槽header
{{postData.name}}
{{postData.age}}
</div>
</template>
<template v-slot:footer="{postData}">
<div>
我是插槽footer
{{postData.name}}
{{postData.age}}
</div>
</template>
</about-view>
<detail>
<template #header>
<div class="list">
我是插槽detail header
</div>
</template>
</detail>
</main>
</template>
<script setup>
import AboutView from './AboutView.vue'
import detail from './detai.vue'
</script>
<style>
.list{
color: red;
}
</style>
使用getCurrentInstance 来获取vue全局实例,利用上面的slots属性来动态渲染插槽