47、插槽 slot的原理和作用

slot具有“占坑”的作用,在子组件占好了位置,那父组件使用该子组件标签时,新添加的DOM元素就会自动填到这个坑里面。

slot又分三类,默认插槽,具名插槽和作用域插槽。

1、默认插槽(单个插槽,没有指定name)

又名匿名插槽,当slot没有指定name属性值的时候一个默认显示插槽,一个组件内只有一个匿名插槽。

注意:

  • 如果有多个DOM元素,会一起插入到<slot></slot>这个标签内;
  • 插槽可以提供一个默认内容,如果父组件没有为这个插槽提供内容,会显示默认的内容。如果父组件为这个插槽提供了内容,则默认的内容会被替换掉。<slot>defalut value</slot>。

例如: 给child组件添加slot插槽,那么父组件的添加的DOM元素就填充到这个slot插槽里面了。

因为插槽放在了子组件的最后,所以<span>我是魔鬼</span> 会插入到 <h1>我是子组件</h1>的后面。

<div id="app">  
  <children>  
    <span>我是魔鬼</span>  
    <!--上面这行会显示在 “我是子组件” 数据后面-->  
  </children>  
</div>  
<script>  
  var vm = new Vue({  
      el: '#app',  
      components: {  
         children: {   
         template: "<h1>我是子组件</h1><slot></slot>"  
       }  
     }  
  });  
</script>  

2、具名插槽(添加了name属性)

为插槽添加了name属性,可以添加多个聚名插槽

当我们需要将父组件添加的HTML标签 放在子组件里的不同位置使用具名插槽实现

  1. 先在子组件的slot标签里,分别添加name=”name名” 属性:<slot name="header"></slot>
  2. 其次父组件在要分发的标签里添加 slot=”name名” 属性,然后就会将对应的标签放在对应的位置了:<span slot="header">我是header</span>

简单理解就是:给子组件占的每一个坑取名将父组件添加的HTML元素添加到指定名字的坑,就实现了分发内容在不同位置显示

【Child组件模板】:<slot name="header"></slot>

<template>
  <div>
    <slot name="header"></slot>
    <h1>我是子组件</h1>
    <slot name="footer"></slot>
  </div>
</template>

【父组件引用Child组件】:<span slot="header">我是header</span>

<Child>
  <span slot="header">我是header</span>
  <span slot="footer">我是footer</span>
</Child>

 3、作用域插槽

  • 有的时候你希望提供的组件带有一个可从子组件获取数据可复用的插槽 
  • 作用域插槽的关键之处就在于,父组件能接收来自子组件的slot传递过来的参数 
  • 作用域插槽必须放在template里面(父组件中)
  • template标签中的属性slot-scope="props"声明从子组件传递的数据都放一个自定义属性内。

例:

<div id="root">
        <child>
           <!--1.作用域插槽必须必须放在template标签内--->
           <!--2.slot-scope="props"声明从子组件传递的数据都放在props里-->
            <template slot-scope="props">
                <li>{{props.value}}</li>
            </template>
        </child>

</div>
<script>
        Vue.component('child',{
            data: function(){
                return {
                    list:[1,2,3,4]
                }
            },
            template: `<div>
                            <ul>
                <!--我们为list中的每个元素准备了一个插槽,将value对象作为一个插槽的prop传入-->
                                <slot v-for="value in list" :value=value>//使用slot占位
                                </slot>
                            </ul>
                        </div>`
        })
        var vm=new Vue({
            el: '#root'
        })
</script>

4、插槽实现原理:

当子组件vm实例化时,获取到父组件传入slot标签的内容存放在vm.$slot,默认插槽为vm.$slot.default,具名插槽为vm.$slot.xxx,xxx 为插槽名,当组件执行渲染函数时候,遇到slot标签,使用$slot(父组件传入slot标签的内容中的内容进行替换此时可以为插槽传递数据,若存在数据,则可称该插槽为作用域插槽。

 

 

  • 7
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue的插槽slot)是一种用于在组件中承载内容的机制。在Vue中,插槽原理可以通过源码来解析。 首先,在Vue的组件中使用插槽的地方,会被编译成一个函数调用,具体代码是`_renderSlot(_ctx.$slots, "default", {count: _ctx.count})`。这个函数名叫`_renderSlot`。 `_renderSlot`函数的定义是这样的: ``` export function renderSlot( slots: Slots, name: string, props: Data = {}, fallback?: () => VNodeArrayChildren, noSlotted?: boolean ): VNode { // ... // 函数内部的实现逻辑 // ... return rendered } ``` 在这个函数内部,会先对插槽进行处理,保证插槽的内容是一个有效的VNode节点。然后,使用`createBlock`函数创建一个包含插槽内容的VNode节点。最后,将这个节点返回。 所以,Vue的插槽原理就是,在编译时将插槽内容包装成一个函数,并使用`createBlock`函数创建一个包含插槽内容的VNode节点。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [vue插槽slot的简单理解与用法实例分析](https://download.csdn.net/download/weixin_38630853/12927251)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Vue slot 详解](https://blog.csdn.net/huangyilinnuli/article/details/119272944)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [vue slot原理](https://blog.csdn.net/qq_36262295/article/details/116203390)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值