005.组件插槽

Posted Ruovan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了005.组件插槽相关的知识,希望对你有一定的参考价值。


前情提要:

  • 组件插槽需要使用<slot>标签来预留位置
    • 【注意】:如果没有<slot>标签,那么插槽内容无效

(1)匿名插槽

  • 当子组件的插槽<slot>没有name属性,或者name属性为default时,即为匿名插槽

    • 没有name属性的<slot>标签具有隐含的name属性,即name=default
    • 没有绑定名字的内容都会被传入默认插槽(匿名插槽)中
    • 一个组件只能有一个该类插槽
    // 子组件
    <div>
    	<slot>
        	<!-- 父组件里的 子组件标签之间 的内容会被插入到这里 -->
        </slot>    
    <div>
        
    // 父组件
    <son>
        这里的内容会被插入到子组件里的 slot 标签里
    	如果子组件没有  slot ,那么这里的内容失效    
    </son>
    

(2)具名插槽

  • 即具有名字的插槽,需要使用<slot>中的 name属性来绑定元素,从而在指定了名字的插槽中插入内容

    • 向具名插槽传入内容的时候,需要在 <template> 元素上使用 v-slot 指令
    • v-slot可以简写为#,但后面必须有参数,如:#header#default
    • 具名插槽的渲染顺序,完全取决于【模板】的顺序,而不是取决于父组件中元素的顺序
    // 子组件
    <div>
        <slot>
        	<!-- 没有命名的插槽内容将会显示在这个地方 -->
        </slot>
        <slot name="content">
        	<!-- 设置了名字的插槽则会显示在对应插槽名下 -->
        </slot>
    </div>
    
    // 父组件
    <son>
        <!-- 默认插槽用 default 做参数 -->
        <template v-slot:default>
    		默认插槽,会显示在没有命名的插槽中
        </template>
        <!-- 具名插槽用插槽名做参数 -->
        <template v-slot:content>
        	会显示在对应插槽名下的插槽中
    		如果没有匹配的插槽名,则会显示在默认插槽中
        </template>
        <!--也可以用slot属性来指定,即 slot="...",已废弃 -->
        <template slot="content">
        	使用这种方式也可以
        </template>
    </son>
    

    注:

    • 使用slot="xxx"的形式,可以在任意元素标签上
    • 使用v-slot:xxx的形式,只能定义在template元素上

(3)动态插槽

  • 该动态值来源于data属性中的属性

    // 子组件
    <div>
        <slot name="header"></slot>
        <slot name="footer"></slot>
    </div>
    
    // 父组件
    <son>
    	<template v-slot:[attributeName]>
        	这里是动态插槽,插槽名根据 attributeName 的值动态改变
        </template>
    </son>
    <script>
    export default {
        data(){
            return {
                attributeName: 'header',
            }
        }
    }
    </script>
    

(4)作用域插槽

  • 在父组件里对子组件加工处理,让插槽内容访问子组件的数据

    • 就是带数据的插槽、带参数的插槽,是子组件提供给父组件的参数,该参数仅限于该插槽中使用
    • 父组件可以根据子组件传递的插槽数据,进行不同的方式展现和填充插槽内容
    • 这样既可以复用子组件的slot,又可以使slot内容不一致
    // 子组件
    <!-- 
        在子组件模板中,<slot>元素上有一个类似props传递数据给组件的写法  :msg="xxx",
        这样,在使用组件时的html页面内,即父组件中,也可以访问到这个item数据
        插槽可以提供一个默认内容,如果父组件没有为这个插槽提供内容,会显示默认的内容。
        如果父组件为这个插槽提供了内容,则默认的内容会被替换掉
    -->
    <div>
        <!-- infomation、message 都是子组件的data中已经有的数据 -->
        <slot :info='infomation'>
            {{ infomation.name }}
        </slot>
        <slot name="header" :msg="message">
        	{{ message.title }}
        </slot>
    </div>
        
    // 父组件
    <son>
        <!-- 
            父组件中,在<template>元素上,使用v-slot指令传递数据,v-slot:default="slotProps",
            slotProps在这里只是临时变量,以接收子组件在插槽上传递过来的数据,可以是任意值
    		这里的 slotProps 接收的是子组件标签 slot 上属性数据的集合
            这里是子组件上的 info 数据传入父组件中,存储在 slotProps 对象中
        --> 	
        <template v-slot:default='slotProps'>
    		{{ slotProps.info.name }}
        </template>
        <template #header="slotProps">
        	{{ slotProps.msg.title }}
        </template>
        
        <!-- 或者,使用slot-scope="scope" -->
        <template slot-scope="scope">
        	{{ scope.info.name }}
        </template>
        <tempalte slot="header" slot-scope="scope">
            {{ scope.msg.title }}
        </tempalte>
    </son>
    

以上是关于005.组件插槽的主要内容,如果未能解决你的问题,请参考以下文章

在 @html 中使用插槽

react-插槽(Portals)

vue插槽

插槽slot

VueJS - 将插槽和作用域插槽向下传递给子模板中的组件

Vue插槽理解