Vue插槽理解
- 插槽
插槽
slot又名插槽,vue内容分发机制,组件内部的模板引擎使用slot元素作为承载分发内容的出口
插槽slot是子组件的一个模板标签元素,而这一个元素是否显示,以及怎么显示是由父组件决定的
slot分为三类:默认插槽、具名插槽、作用域插槽
- 默认插槽
父组件代码详情
<template>
<div class="parent">
<h1>这里是parent组件</h1>
<Child>
<h3>这是parent组件传递给child组件的值</h3>
</Child>
</div>
</template>
<script>
import Child from "../component/Child.vue"
</script>
子组件代码详情
<template>
<div class="child">
<h1>这里是child组件</h1>
<Child>
<h3>这是child组件</h3>
<slot></slot>
</Child>
</div>
</template>
运行结果:
又叫匿名插槽,当插槽slot没有指定name属性值的时候一个默认显示一个插槽,一个组件内只有一个匿名插槽
- 具名插槽
带有具体名字的插槽,也就是带有name属性的slot,一个组件可以出现多个具名插槽
父组件代码详情
<template>
<div class="parent">
<h1>这里是parent组件</h1>
<Child>
<div slot="header">给header内容</div>
<div slot="main">给main内容</div>
<div slot="footer">给footer内容</div>
</Child>
</div>
</template>
子组件代码详情
<template>
<div class="child">
<h1>这里是parent组件</h1>
<Child>
<div name="header">给header内容</div>
<div name="main">给main内容</div>
<div name="footer">给footer内容</div>
</Child>
</div>
</template>
运行结果:
- 作用域插槽
在子组件渲染作用域插槽时,可以将子组件内部的数据传递给父组件,让父组件根据子组件传递过来的数据如何渲染该插槽
父组件代码详情
<template>
<button @click="show">显示隐藏</button>
<div class="home" v-show="isShow">
<Dialog title="商品选择">
<!-- 匿名插槽的使用 -->
<!-- 写法一 -->
<!-- 12243 -->
<!-- 写法二 -->
<template #default>
<!-- 666666666666666666 -->
<FruitList>
<template #default="{goods}">{{ goods }}</template>
</FruitList>
</template>
<!-- 具名插槽使用 -->
<!-- 写法一 -->
<!-- <template v-slot:footer>
<Rbutton>取消</Rbutton>
<Rbutton>确认</Rbutton>
</template> -->
<!-- 写法二 -->
<template #footer>
<Rbutton style=" display: inline-block;border-radius: 5px;margin-right: 10px;">取消</Rbutton>
<Rbutton style="background-color: #1890ff; display: inline-block; border-radius: 5px;">确认</Rbutton>
</template>
</Dialog>
</div>
</template>
<script>
import Dialog from '@/components/Dialog.vue'
import Rbutton from '@/components/Rbutton.vue';
import FruitList from '@/components/FruitList.vue';
export default {
data(){
return{
isShow:false
}
},
name: 'DialogParent',
components: {
Dialog,
Rbutton,
FruitList
},
methods:{
onAddCart(gid,gname){
console.log(gid,gname);
},
show(){
this.isShow=!this.isShow
}
}
}
</script>
<style lang="scss" scoped>
.home{
// position: relative;
background-color: yellow;
}
</style>
子组件代码详情
<template>
<div class="fruit">
<table class="ftable">
<thead>
<tr>
<td>ID</td>
<td>名字</td>
<td>价格</td>
</tr>
</thead>
<tbody>
<tr v-for="f in fruits" :key="f.id" @click="onAddCart([f.id,f.name])">
<td>{{ f.id }}</td>
<td>{{ f.name }}</td>
<td>{{ f.price }}</td>
</tr>
<slot :goods="f"></slot>
</tbody>
</table>
</div>
</template>
<script>
export default {
data(){
return{
fruits:[
{
id:'01',
name:'苹果~~🍎',
price:'3.90'
},
{
id:'01',
name:'西瓜~~🍉',
price:'3.70'
},
{
id:'01',
name:'葡萄~~🍇',
price:'3.80'
},
{
id:'01',
name:'橙子~~🍊',
price:'3.50'
},
{
id:'01',
name:'香蕉~~🍌',
price:'3.30'
},
]
}
},
methods:{
onAddCart(params){
this.$emit('add-cart',...params)
}
}
}
</script>
<style lang="scss" scoped>
.fruit{
// li{
// list-style: none;
// }
width: 100%;
// height: 100%;
// background-color: plum;
table{
width: 95%;
// border-radius: 20px;
margin: 0 auto;
border: 1px bolid black;
thead{
width: 100%;
// border-radius: 20px;
// background-color: blue;
text-align: center;
}
tbody{
// border-radius: 20px;
width: 100%;
background-color: aliceblue;
text-align: center;
}
}
}
</style>
**原理:**当子组件vm实例化时,获取到父组件传入的slot标签的内容,存放在vm. s l o t 中,默认插槽为 v m . slot中,默认插槽为vm. slot中,默认插槽为vm.slot.default,具名插槽为vm. s l o t . x x x , x x x 是插槽的名字,当组件执行渲染函数时候,遇到 s l o t 标签,使用 slot.xxx,xxx是插槽的名字,当组件执行渲染函数时候,遇到slot标签,使用 slot.xxx,xxx是插槽的名字,当组件执行渲染函数时候,遇到slot标签,使用slot中的内容进行替换,此时可以为插槽传递数据,若存在数据,则就是作用域插槽