目录
1. 默认插槽
父组件:
<template>
<div class="father">
<h3>父组件</h3>
<div class="container">
<Category title="今日游戏推荐">
<ul>
<li v-for="item in games" :key='item.id'>{{ item.name }}</li>
</ul>
</Category>
<Category title="今日美食城市">
<img :src="imageUrl" alt="" />
</Category>
<Category title="今日影视推荐">
<video :src="videoUrl" controls></video>
</Category>
</div>
</div>
</template>
<script setup lang="ts" name="Father">
import Category from './Category.vue'
import { ref, reactive } from 'vue'
let games = reactive([
{ id: 'asgdytsa01', name: '英雄联盟' },
{ id: 'asgdytsa02', name: '王者荣耀' },
{ id: 'asgdytsa03', name: '红色警戒' },
{ id: 'asgdytsa04', name: '斗罗大陆' }
])
let imageUrl = ref('https://img-blog.csdnimg.cn/direct/fb1e1f109889467a85eec6af0984611c.png')
let videoUrl = ref('https://media.w3.org/2010/05/sintel/trailer.mp4')
</script>
<style scoped>
.father {
background-color: pink;
padding: 20px;
}
.container {
display: flex;
justify-content: space-evenly;
}
img,
video {
width: 100%;
}
</style>
子组件:
<template>
<div class="category">
<h2>{{ title }}</h2>
<slot>默认内容</slot>
</div>
</template>
<script setup lang="ts" name="Category">
defineProps(['title'])
</script>
<style scoped>
.category {
width: 200px;
height: 300px;
background-color: aquamarine;
}
h2 {
background-color: chartreuse;
width: 100;
text-align: center;
}
</style>
2. 具名插槽
<template>
<div class="father">
<h3>父组件</h3>
<div class="container">
<Category>
<template v-slot:s2>
<ul>
<li v-for="item in games" :key='item.id'>{{ item.name }}</li>
</ul>
</template>
<template v-slot:s1>
<h2>今日游戏推荐</h2>
</template>
</Category>
<Category>
<template v-slot:s2>
<img :src="imageUrl" alt="" />
</template>
<template v-slot:s1>
<h2>今日图片推荐</h2>
</template>
</Category>
<Category>
<!-- 写法 v-slot:s2 也可以 #s2 -->
<template #s2>
<video :src="videoUrl" controls></video>
</template>
<template #s1>
<h2>今日影视推荐</h2>
</template>
</Category>
</div>
</div>
</template>
<script setup lang="ts" name="Father">
import Category from './Category.vue'
import { ref, reactive } from 'vue'
let games = reactive([
{ id: 'asgdytsa01', name: '英雄联盟' },
{ id: 'asgdytsa02', name: '王者荣耀' },
{ id: 'asgdytsa03', name: '红色警戒' },
{ id: 'asgdytsa04', name: '斗罗大陆' }
])
let imageUrl = ref('https://img-blog.csdnimg.cn/direct/fb1e1f109889467a85eec6af0984611c.png')
let videoUrl = ref('https://media.w3.org/2010/05/sintel/trailer.mp4')
</script>
<style scoped>
.father {
background-color: pink;
padding: 20px;
}
.container {
display: flex;
justify-content: space-evenly;
}
img,
video {
width: 100%;
}
h2 {
background-color: chartreuse;
width: 100;
text-align: center;
}
</style>
子组件:
<template>
<div class="category">
<h2>{{ title }}</h2>
<slot name="s1">默认内容</slot>
<slot name="s2">默认内容</slot>
</div>
</template>
<script setup lang="ts" name="Category">
defineProps(['title'])
</script>
<style scoped>
.category {
width: 200px;
height: 300px;
background-color: aquamarine;
}
</style>
3. 作用域插槽
-
理解:数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。(新闻数据在
News
组件中,但使用数据所遍历出来的结构由App
组件决定) -
具体编码:
父组件:
<template>
<div class="father">
<h3>父组件</h3>
<div class="container">
<!-- <Game v-slot:default="params"> -->
<!-- <Game #default="params"> -->
<Game v-slot="params">
<ul>
<li v-for="g in params.games" :key="g.id">{{ g.name }}</li>
</ul>
</Game>
</div>
</div>
</template>
<script setup lang="ts" name="Father">
import Game from './Game.vue'
</script>
<style scoped>
.father {
background-color: pink;
padding: 20px;
}
.container {
display: flex;
justify-content: space-evenly;
}
img,
video {
width: 100%;
}
h2 {
background-color: chartreuse;
width: 100;
text-align: center;
}
</style>
子组件:
<template>
<div class="category">
<h2>今日游戏榜单</h2>
<slot :games="games" a="哈哈"></slot>
</div>
</template>
<script setup lang="ts" name="Category">
import { reactive } from 'vue'
let games = reactive([
{ id: 'asgdytsa01', name: '英雄联盟' },
{ id: 'asgdytsa02', name: '王者荣耀' },
{ id: 'asgdytsa03', name: '红色警戒' },
{ id: 'asgdytsa04', name: '斗罗大陆' }
])
</script>
<style scoped>
.category {
width: 200px;
height: 300px;
background-color: aquamarine;
}
</style>