1)插槽是父子组件之间传递数据的一种方式
2)插槽都是定义在子组件<slot></slot>,父组件在调用该子组件时,父组件即是插槽的使用者,故插槽的使用者(父组件)往(子组件的)插槽中加数据。
父组件:引用子组件,并在引用的子组件中写入要传给子组件的数据
<template>
//template包裹元素,但不生成真实的元素
<div class="contain">
// (不使用插槽使得数据传输方式) 父组件中绑定data区的数据,子组件通过props接受
// <category title="美食" :listdata="foods"></category>
// <category title="电影" :listdata="games"></category>
// <category title="游戏" :listdata="files"></category>
//默认插槽
<category title="美食" :listdata="foods"></category>
//如果页面想展示的是图片
<img src="q.png" alt="">
</category>
<category title="电影" :listdata="files"></category>
//如果页面想展示的是视频
<video controls src="111.mp4" alt=""></video>
</category>
<category title="游戏" :listdata="games"></category>
//如果页面想展示的是文字
<ul>
<li v-for="(g,item) in games" :key="item"> {{g}}</li>
</ul>
</category>
</div>
</template>
<script>
import category from "../category"
export default{
name:'app',
components:{category}
data(){
return{
foods:['火锅','奶茶','牛排'],
games:['火影','王者','吃鸡'],
files:['交付','哈哈','呵呵']
}
},
}
</script>
<style>
略
</style>
子组件(category.vue)子组件通过props接受父组件传过来的数据,并通过<slot></slot>占位,然后接收父组件传过来的数据
<template>
<div class="category">
//子组件接受具体的数据,渲染到页面
<h3>{{title}}列表</h3>
//在子组件中挖个坑,让父组件中的数据往这个坑里填
//怎么知道父组件的哪个数据填到这里呢?
//答:父组件中引用子组件的地方,将该(引用的)子组件中的内容传给子组件
<slot></slot>
<ul>
<li v-for="(item,index) in listdata" :key="index">{{item}}</li>
</ul>
</div>
</template>
<script>
export default(){
name:'category',
props:['listdata','title']
}
</script>
<style>
.category{
}
</style>
具名插槽:子组件中注册插槽时,使用name="slotname"属性指定插槽名称;父组件引用插槽时,通过slot="slotname"属性找到子组件中对应名称的插槽
父组件:
<template>
//template包裹元素,但不生成真实的元素
<div class="contain">
//具名插槽
<category title="美食" :listdata="foods"></category>
//到子组件中找到对应名称的插槽,将此处的数据填到对应名称的插槽中区
<img slot="center" src="q.png" alt="">
<a slot="footer" href="https://www/hhh.com">嘎嘎嘎</a>
</category>
<category title="电影" :listdata="files"></category>
//如果页面想展示的是视频
<video controls src="111.mp4" alt=""></video>
<a slot="footer" href="https://www/hhh.com">哈哈哈</a>
<a slot="footer" href="https://www/hhh.com">是是是</a>
</category>
<category title="游戏" :listdata="games"></category>
//如果页面想展示的是文字
<ul>
<li v-for="(g,item) in games" :key="item"> {{g}}</li>
</ul>
</category>
</div>
</template>
<script>
import category from "../category"
export default{
name:'app',
components:{category}
data(){
return{
foods:['火锅','奶茶','牛排'],
games:['火影','王者','吃鸡'],
files:['交付','哈哈','呵呵']
}
},
}
</script>
<style>
略
</style>
子组件:
<template>
<div class="category">
//子组件接受具体的数据,渲染到页面
<h3>{{title}}列表</h3>
<slot name="center">中间的内容</slot>
<slot name="footer">底部的内容</slot>
</div>
</template>
<script>
export default(){
name:'category',
props:['listdata','title']
}
</script>
<style>
.category{
}
</style>
作用域插槽
子组件:子组件定义的插槽中绑定数据,用于将数据逆向传给父组件使用
<template>
<div class="category">
<h3>{{title}}分类</h3>
<!-- 子组件中绑定的数据game,msg,逆向传给父组件 -->
<slot :game="games" msg="hello">默认内容</slot>
</div>
</template>
<script>
export default{
name:'Category',
props:['title'],
data(){
// 注意:数据写在了子组件中
return {
games:['王者','穿越火线','劲舞团','超级玛丽'],
}
},
}
</script>
父组件:通过在引用的子组件内部,通过<template scope="自定义名称">{{子组件传过来的数据}}</template>将父组件的dom和数据等插入子组件的插槽中
<template>
<div>
<Category title="游戏">
<!-- 父组件中引用子组件的位置,通过作用域插槽拿到对应子组件插槽中的数据 -->
<!--scope="atguigu"引号中的内容是自定义的 -->
<!-- atguigu===games:['王者','穿越火线','劲舞团','超级玛丽'], -->
<template scope="atguigu">
<ul>
<li v-for="(g, index) in atguigu.games" :key="index">{{ g }}</li>
</ul>
<h4>{{ atguigu.msg }}</h4>
</template>
</Category>
<Category title="游戏">
<!-- {game}是解构赋值 -->
<template scope="{game}">
<ul>
<li v-for="(g, index) in atguigu.games" :key="index">{{ g }}</li>
</ul>
</template>
</Category>
<!--新的api的写法 -->
<Category title="游戏">
<!-- {game}是解构赋值 -->
<template slot-scope="{game}">
<ul>
<li v-for="(g, index) in atguigu.games" :key="index">{{ g }}</li>
</ul>
</template>
</Category>
</div>
</template>
<script>
import category from "../category";
export default {
name: "app",
components: { category },
};
</script>
<style>
</style>
总结:
1.插槽的作用:让父组件可以向子组件指定位置插入html结构(dom元素及数据),也是一种组件通信方式,适用于父传子。
2.分类
默认插槽:子组件定义插槽,父组件在引用的子组件内部传递html结构
具名插槽:子组件定义插槽时,通过name属性指定名称,父组件引用子组件时,通过slot="name"或v-slot:name属性将dom元素等插入到子组件的指定位置
作用域插槽:数据在子组件自身,但数据根据生成的结构需要组件的使用者来决定。(game数据在Category组件中,但使用数据所遍历出来的结构由APP组件决定)