插槽

注意:本篇笔记为方便兼容Vue3,均采用了比较新的v-slot写法,而未采用老式的slot和slot-scope

  • 插槽(slot)是 vue 为组件的封装者提供的能力。允许开发者在封装组件时,把不确定的、希望由用户指定的部分定义为插槽,可以把插槽认为是组件封装期间,为用户预留的内容的占位符。

  • 插槽常用于父组件向子组件指定位置插入html结构,也是一种组件间通信方式,适用于父组件→子组件

  • $slots是组件插槽集,是组件所有默认插槽、具名插槽的集合,可以用来获取当前组件的插槽集

1. 默认插槽

  • 父组件:

    <template>
    	<div class="container">
            <!--默认插槽-->
            <!--写在标签上的是父组件以props形式向子组件传递的属性,与插槽无关-->
            <Category title="美食" :listDate="foods">
                <!--希望向子组件中插入的内容-->
        		<img src="img1.jpg">
        	</Category>
        </div>
    </template>
    
    <script>
    	import Category from './components/Category'
        export default{
            name:'App',
            components:{Category}
        }
    </script>
    
  • 子组件:

    <template>
    	<div class="category">
            <slot></slot>
        </div>
    </template>
    <script>
        export default{
            name:'Category'
        }
    </script>
    
  • 解析:

    在父组件调用 子组件Category 时,额外附加了一段代码<img src="img1.jpg">。添加这段代码后,vue会在Category中自动寻找可以插入的地方。

    若Category中定义了插槽<slot></slot>,则这段代码会被替换为<img src="img1.jpg">;若没有,则父组件传入的代码会被自动抛弃

    如果在<slot></slot>之间写入代码,则该段代码将会作为后备内容。即,若父组件没有传入附加代码,该段代码会作为默认值自动渲染

  • 注意:

    • 若父组件需要传入不同的代码,并在子组件不同地方渲染,默认插槽会失效,此时需使用具名插槽

    • 默认插槽是特殊的具名插槽,它具有隐藏的name="default"

    • 默认插槽无法让父组件获取子组件中的变量和值

      <navigation-link url="/profile">
        Logged in as {{ user.name }}
      </navigation-link>
      

      此处user.name在子组件中为undefined。因为插槽会先渲染然后再传递到子组件中,而user.name在父组件中不存在,即便子组件中具有user.name,也不会获取到该变量

      如果要让父组件获取子组件中的变量和值,可以使用作用域插槽

2. 具名插槽

有时候会同时需要多个插槽,并将其渲染到不同的位置上,此时就需要使用具名插槽

  • 父组件:

    <template>
    	<div class="container">
            
            <Category title="美食" :listDate="foods">
                <!--添加名称-->
                <template v-slot:center>
        			<img src="img1.jpg">
      			</template>
                <!--添加名称-->
    			<template v-slot:footer>
        			<a href="www.baidu.com">百度</a>
      			</template>
        	</Category>
            
        </div>
    </template>
    
    <script>
    	import Category from './components/Category'
        export default{
            name:'App',
            components:{Category}
        }
    </script>
    
  • 子组件:

    <template>
    	<div class="category">
            <!--指定名称-->
            <slot name="center"></slot>
            <!--指定名称-->
            <slot name="footer"></slot>
        </div>
    </template>
    <script>
        export default{
            name:'Category'
        }
    </script>
    
  • 解析:指定的代码会渲染到对应名称的slot上

3. 作用域插槽

当数据在组件的自身,而根据数据生成的结构需要组件的使用者来决定时,就要用作用域插槽

假设子组件<current-user>具有user对象数据,此时有如下代码

  • 父组件:

    <current-user>
      {{ user.firstName }}
    </current-user>
    
  • 子组件:

    <span>
      <slot></slot>
    </span>
    

以上代码不会正常工作,因为只有 <current-user> 组件可以访问到 user,而提供的内容是在父级渲染的

此时需要使用作用域插槽

  • 父组件:

    <current-user>
        <template v-slot:default="ScopeData">
    		{{ ScopeData.user.firstName }}
        </template>
    </current-user>
    
    
  • 子组件:

    <span>
      <slot :user="user"></slot>
    </span>
    
  • 解析:

    仔细看看和普通插槽相比,父子组件在使用作用域插槽时分别产生了哪些改变:

    • 父组件

      传统的v-slot:default后添加了="slotScope"

      而这个”slotScope”在插入内容中,用{{ ScopeData.user.firstName }}替代了 {{ user.firstName }}

    • 子组件

      子组件额外添加了一个:user="user"

    • 原理

      实际上在这里,父组件对子组件进行了一次传参,只不过传参与参数的接受仅仅局限于插槽之间

      绑定在 <slot> 元素上的 attribute 被称为插槽 prop,而在这个例子中,我们选择将包含所有插槽 prop 的对象命名为 slotProps

      也就是说,子组件用:user="user"user对象绑定在了slotProps上,然后传递了过去,父组件则用slotProps.user.firstName的方式接收到了。

      注意,这并不意味着作用域插槽可以用于子组件→父组件传递数据,实际逻辑为父组件→(需求子组件数据)→(发送请求)→(子组件绑定数据传输到父组件)→(父组件渲染)→(插入到子组件)→子组件。整体仍然是父组件传递数据到子组件

原文地址:http://www.cnblogs.com/Solitary-Rhyme/p/16910208.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性