2020-08-19-Vue中的插槽总结

本文深入解析Vue中的插槽概念,包括默认插槽、具名插槽及作用域插槽的使用方法,阐述如何通过插槽实现父组件向子组件传递内容,以及如何利用作用域插槽实现数据绑定。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Vue中的插槽 -----具名插槽、作用域插槽

定义:插槽就是在子组件中的提供给父组件使用的一个占位符,用<slot></slot> 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的<slot></slot> 标签。

举例:主机上的usb插孔 就是子组件中使用的插槽<slot></slot> ,而u盘既是父组件在这个usb插孔上需要填充的任何模板代码 (最直接的是u盘 [ 模板代码 ] 随时可以插入,但插槽的存在决定着填充的内容是否渲染)

使用插槽的原因:当我们在父组件中给子组件标签内定义内容时,该内容是不会被渲染的

1、默认插槽:

描述:默认插槽就是指没有名字的插槽,子组件未定义名字的插槽,父级将会把 未指定插槽的填充的内容填充到默认插槽中

<div id="app">
         <child>插入的内容不会被渲染</child>
    </div>
    <script src="../vue.js"></script>
    <script>
        const Child = {
            template:  `
                <div class="child">
                    子组件渲染的内容
                </div>
            `
        }
        Vue.component("child",Child)
        var vm = new Vue({
            el: '#app',
        });
    </script>

结果:(在父组件中添加的内容不显示,而是显示了子组件的内容,)

在这里插入图片描述

使用插槽:

 <div id="app">
        <!-- 使用插槽 -->
        <!-- <child>插入的内容不会被渲染</child> -->
        
        <p class="split_line"></p>
        
        <!-- 使用插槽插入内容 -->
        <child>这是使用插槽插入的内容</child>
        
    </div>

    <script src="../vue.js"></script>
    <script>
        const Child = {
            template:  `
                <div class="child">
                    <h3>子组件渲染的内容</h3>
                    <slot></solt> <!-- 使用插槽 -->
                </div>
            `
        }
        Vue.component("child",Child)
        var vm = new Vue({
            el: '#app',
        });
    </script>

结果:

在这里插入图片描述

2、具名插槽
说明:具名插槽就是给插槽取个名字。一个子组件可以放多个插槽,而且可以放在不同的地方,而父组件填充内容时,可以根据这个名字把内容填充到对应插槽中。

(写法一)示例代码:

 <div id="app">
        <child>
         	<!--向插槽名字before插入内容  -->
            <p slot="before">在p元素之前</p>
            
            <!--向插槽名字after插入内容  -->
            <p slot="after">在p元素之前</p>
        </child>
       
    </div>

    <script src="../vue.js"></script>
    <script>
        const Child = {
            template:  `
                <div>
                    <slot name="before"></slot>   <!--使用插槽并定义名字  -->
                    <h3>子组件渲染的内容</h3>
                    <slot name="after"></slot>    <!--使用插槽并定义名字  -->
                </div>
            `
        }
        Vue.component("child",Child)
        var vm = new Vue({
            el: '#app',
        });
    </script>

(写法二)示例代码:
v-slot:插槽名 可以简写成#插槽名

  • 注意:v-slot:插槽名仅仅适用于

1、<template>
2、组件 (对于一个单独的带 prop 的默认插槽)

<div id="app">
        <child>
            <!-- 
            <template v-slot:before>
                <p>在h3元素之前</p>
            </template>
            <template v-slot:after>
                <p>在h3元素之后</p>
            </template>
             -->
            <!-- 上面写法等同于 -->
             <template #before>
                <p>在h3元素之前</p>
            </template>
            <template #after>
                <p>在h3元素之后</p>
            </template>
        </child>
       <!--  -->
    </div>

    <script src="../vue.js"></script>
    <script>
        const Child = {
            template:  `
                <div>
                    <slot name="before"></slot>
                    <h3>h3标签:子组件渲染的内容</h3>
                    <slot name="after"></slot> 
                </div>
            `
        }
        Vue.component("child",Child)
        var vm = new Vue({
            el: '#app',
        });
    </script>

上述结果:

在这里插入图片描述

总结上述:

(1). 父级的填充内容如果指定到子组件的没有对应名字插槽,那么该内容是不会被填充到默认插槽中。

(2). 如果子组件没有默认插槽,而父级的填充内容指定到默认插槽中,那么该内容就“不会”填充到子组件的任何一个插槽中。

(3). 如果子组件有多个默认插槽,而父组件所有指定到默认插槽的填充内容,将“会” “全都”填充到子组件的每个默认插槽中。

3、作用域插槽

说明:作用域插槽其实就是带数据的插槽,即带参数的插槽,简单的来说就是子组件提供给父组件的参数,该参数仅限于插槽中使用,父组件可根据子组件传过来的插槽数据来进行不同的方式展现和填充插槽内容。

常用场景:

  • 如果子组件中的某一部分的数据,每个父组件都会有自己的一套对该数据的不同的呈现方式,这时就需要用到作用域插槽。

对比案例代码:

 <div id="app">
        <child :list="list"></child>
        <child :list="list"></child>
    </div>
    <script src="../vue.js"></script>
    <script>
        const Child = {
            template: `<div>
                            <ul>
                                <li v-for="(item,index) in list" :key="index">
                                     元素:{{item}} ---- 下标:{{index}}
                                </li>
                            </ul>
                        </div>`,
            props:{
                list:Array
            }
        }
        const vm = new Vue({
            el: '#app',
            // 注册组件
            components: {
                Child
            },
            data() {
                return {
                    list: [1, 2, 3]
                }
            },
        })
    </script>

结果:

在这里插入图片描述

说明:通过调用两次 ``子组件,但是调用了同一个子组件,因此打印结果相同,

使用作用域插槽 案例代码:

 <div id="app">
        <!-- 作用域插槽 -->
       <cmp-two :list="list">
           <template v-slot="{item,index}">
               <li>元素内容{{item}} - 下标{{index}}</li>
           </template>
       </cmp-two>
       <cmp-two :list="list">
           <template v-slot="{item,index}">
               <li>下标{{index}} - 元素内容{{item}}</li>
           </template>
       </cmp-two>
    </div>
    <script src="../vue.js"></script>
    <script>
        const cmpTwo = {
          
            template: 
                `<div>
                   <ul>
                      <slot v-for="(item,index) in list" :item="item" :index="index"></slot>
                   </ul>
                </div>`,
            props:{
                list:Array
            },
        }
        const vm = new Vue({
            el: '#app',
            // 注册组件
            components: {
                cmpTwo
            },
            data() {
                return {
                    list: [1, 2, 3]
                }
            },
          
        })
    </script>

结果:

在这里插入图片描述

说明:通过调用两次 ``子组件,调用同一个子组件,但两次渲染结果不同。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值