插槽(Slots)是 Vue.js 框架中的一个功能,允许在组件内部预留一些可替换的内容。通过插槽,可以给父组件填充模板代码,让父组件向子组件传递自定义的内容,以便在子组件中进行展示或处理。
1. 匿名插槽
Son.vue
<template><div><header class="header"></header><main class="main"><slot></slot></main><footer class="footer"></footer></div>
</template><script setup lang="ts"></script><style scoped>
.header {height: 200px;background-color: red;color: white;
}.main {height: 300px;background-color: blue;color: white;
}.footer {height: 200px;background-color: green;color: white;
}
</style>
App.vue
<template><div class="content"><Son><template v-slot><div>插入中间</div></template></Son></div>
</template><script setup lang="ts">
import Son from './components/Son.vue'
</script><style scoped></style>
2. 具名插槽
Son.vue
<template><div><header class="header"><slot name="header"></slot></header><main class="main"><slot></slot></main><footer class="footer"><slot name="footer"></slot></footer></div>
</template><script setup lang="ts"></script><style scoped>
.header {height: 200px;background-color: red;color: white;
}.main {height: 300px;background-color: blue;color: white;
}.footer {height: 200px;background-color: green;color: white;
}
</style>
App.vue
<template><div class="content"><Son><template v-slot:header><div>插入上面</div></template><template v-slot><div>插入中间</div></template><template v-slot:footer><div>插入下面</div></template></Son></div>
</template><script setup lang="ts">
import Son from './components/Son.vue'
</script><style scoped></style>
3. 插槽作用域
Son.vue
<template><div><header class="header"><slot name="header"></slot></header><main class="main"><div v-for="(item,index) in data"><slot :index="index" :data="item"></slot></div></main><footer class="footer"><slot name="footer"></slot></footer></div></template><script setup lang="ts">
import { reactive } from 'vue';
type names = {name: string,age: number
}
const data = reactive<names[]>([{name: '张三', age: 18},{name: '李四',age: 19},{name: '王五',age: 20}
])</script><style scoped>
.header {height: 200px;background-color: red;color: white;
}.main {height: 300px;background-color: blue;color: white;
}.footer {height: 200px;background-color: green;color: white;
}
</style>
App.vue
<template><div class="content"><Son><template v-slot:header><!-- 简写为:#header --><div>插入上面</div></template><!-- 直接解构出 data index --><template v-slot="{ data, index }"><!-- 匿名插槽简写为:#default="{ data, index }" --><div>{{ data.name }}--{{ data.age }}--{{ index }}</div></template><template v-slot:footer><div>插入下面</div></template></Son></div>
</template><script setup lang="ts">
import Son from './components/Son.vue'
</script><style scoped></style>
4. 动态插槽
App.vue
<template><div class="content"><Son><template v-slot:[name]><!-- 或者简写为:#[name] --><div>我在哪儿?</div></template></Son></div>
</template><script setup lang="ts">
import { ref } from 'vue'
import Son from './components/Son.vue'
let name = ref('footer')
// let name = ref('deault') // 插入中间的匿名插槽
</script><style scoped></style>