> 文章列表 > Vue插槽理解

Vue插槽理解

Vue插槽理解

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>

运行结果:
Vue插槽理解

又叫匿名插槽,当插槽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.slot中,默认插槽为vm.slot中,默认插槽为vm.slot中,默认插槽为vm.slot.default,具名插槽为vm.slot.xxx,xxx是插槽的名字,当组件执行渲染函数时候,遇到slot标签,使用slot.xxx,xxx是插槽的名字,当组件执行渲染函数时候,遇到slot标签,使用slot.xxx,xxx是插槽的名字,当组件执行渲染函数时候,遇到slot标签,使用slot中的内容进行替换,此时可以为插槽传递数据,若存在数据,则就是作用域插槽