slot分发

注意:其实就是父组件要改变子组件中的dom元素,比如增加div,p等等,可是是不允许的,因为子组件已经写好了,是不允许直接在子组件里面加dom元素的,

但是通过slot就可以了,在父组件中加dom元素,<div slot=“head”>你好</div>,这是一个父组件要往子组件里面加的 内容,也可以直接<div>你好</div>,

但是两者是有区别的,子组件接收的方式不一样,第一种:子组件接收用<slot name="head"></slot>接收对应name的差值,第二种:<slot></slot>没有那么属性的slot标签负责

接收没有slot属性的dom元素差值


用组件时,我们常常要像这样组合它们:

     
     
<app>
<app-header> </app-header>
<app-footer> </app-footer>
</app>

注意两点:

  1. <app> 组件不知道它的挂载点会有什么内容。挂载点的内容是由<app>的父组件决定的。

  2. <app> 组件很可能有它自己的模版。

为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板。这个过程被称为 内容分发 (或 “transclusion” 如果你熟悉 Angular)。Vue.js 实现了一个内容分发 API ,参照了当前Web 组件规范草案,使用特殊的 <slot> 元素作为原始内容的插槽。

编译作用域

在深入内容分发 API 之前,我们先明确内容在哪个作用域里编译。假定模板为:

     
     
<child-component>
{{ message }}
</child-component>

message 应该绑定到父组件的数据,还是绑定到子组件的数据?答案是父组件。组件作用域简单地说是:

父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译。

一个常见错误是试图在父组件模板内将一个指令绑定到子组件的属性/方法:

     
     
<!-- 无效 -->
<child-component v-show="someChildProperty"> </child-component>

假定 someChildProperty 是子组件的属性,上例不会如预期那样工作。父组件模板不应该知道子组件的状态。

如果要绑定作用域内的指令到一个组件的根节点,你应当在组件自己的模板上做:

     
     
Vue.component( 'child-component', {
  // 有效,因为是在正确的作用域内
template: '<div v-show="someChildProperty">Child</div>',
data: function () {
return {
someChildProperty: true
}
}
})

类似地,分发内容是在父作用域内编译。

单个 Slot

除非子组件模板包含至少一个 <slot> 插口,否则父组件的内容将会被丢弃。当子组件模板只有一个没有属性的 slot 时,父组件整个内容片段将插入到 slot 所在的 DOM 位置,并替换掉 slot 标签本身。

最初在 <slot> 标签中的任何内容都被视为备用内容。备用内容在子组件的作用域内编译,并且只有在宿主元素为空,且没有要插入的内容时才显示备用内容。

假定 my-component 组件有下面模板:

     
     
<div>
<h2>我是子组件的标题 </h2>
<slot>
只有在没有要分发的内容时才会显示。
</slot>
</div>

父组件模版:

     
     
<div>
<h1>我是父组件的标题 </h1>
<my-component>
<p>这是一些初始内容 </p>
<p>这是更多的初始内容 </p>
</my-component>
</div>

渲染结果:

     
     
<div>
<h1>我是父组件的标题 </h1>
<div>
<h2>我是子组件的标题 </h2>
<p>这是一些初始内容 </p>
<p>这是更多的初始内容 </p>
</div>
</div>

具名 Slot

<slot> 元素可以用一个特殊的属性 name 来配置如何分发内容。多个 slot 可以有不同的名字。具名 slot 将匹配内容片段中有对应slot 特性的元素。

仍然可以有一个匿名 slot ,它是默认 slot ,作为找不到匹配的内容片段的备用插槽。如果没有默认的 slot ,这些找不到匹配的内容片段将被抛弃。

例如,假定我们有一个 app-layout 组件,它的模板为:

     
     
<div class="container">
<header>
<slot name="header"> </slot>
</header>
<main>
<slot> </slot>
</main>
<footer>
<slot name="footer"> </slot>
</footer>
</div>

父组件模版:

     
     
<app-layout>
<h1 slot="header">这里可能是一个页面标题 </h1>
<p>主要内容的一个段落。 </p>
<p>另一个主要段落。 </p>
<p slot="footer">这里有一些联系信息 </p>
</app-layout>

渲染结果为:

     
     
<div class="container">
<header>
<h1>这里可能是一个页面标题 </h1>
</header>
<main>
<p>主要内容的一个段落。 </p>
<p>另一个主要段落。 </p>
</main>
<footer>
<p>这里有一些联系信息 </p>
</footer>
</div>

在组合组件时,内容分发 API 是非常有用的机制。

作用域插槽

2.1.0 新增

                         1.父组件中包含子组件

                                           子组件在写模板的时候,就写了<slot>标签,里面有各种属性,这写属性全部添加在props对象上,然后传递给新增模板

                         2.父组件中要改变子组件的dom并且用模板的形式,那么这个模板肯定写在子组件中,那么这个模板就有一下作用:

                                            a.替换所有的子组件中的<slot>标签

                                            b.拥有scope属性,这个scope属性用来接收子组件传递出来的props对象

                                            c.然后这个模板中可以用props这个对象做数据渲染




         

     
     
<div class="child">
<slot text="hello from child"> </slot>
</div>

在父级中,具有特殊属性 scope<template> 元素,表示它是作用域插槽的模板。scope 的值对应一个临时变量名,此变量接收从子组件中传递的 prop 对象:

     
     
<div class="parent">
<child>
<template scope="props">
<span>hello from parent </span>
<span>{{ props.text }} </span>
</template>
</child>
</div>

如果我们渲染以上结果,得到的输出会是:

     
     
<div class="parent">
<div class="child">
<span>hello from parent </span>
<span>hello from child </span>
</div>
</div>

作用域插槽更具代表性的用例是列表组件,允许组件自定义应该如何渲染列表每一项:

     
     
<my-awesome-list :items="items">
  <!-- 作用域插槽也可以是具名的 -->
<template slot="item" scope="props">
<li class="my-fancy-item">{{ props.text }} </li>
</template>
</my-awesome-list>

列表组件的模板:

 
 
<ul>
<slot name="item"
v-for= "item in items"
:text= "item.text">
    <!-- 这里写入备用内容 -->
</slot>
</ul>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue中的插槽(Slots)是一种在父组件中将子组件的内容进行分发的机制。通过插槽,我们可以在父组件中定义一些占位符,然后在子组件中填充具体的内容。 在Vue中,插槽有两种类型:具名插槽和默认插槽。 具名插槽允许我们在父组件中使用多个不同的插槽,并且可以根据需要进行分发和填充。我们可以使用`<slot>`元素和`name`属性来定义具名插槽。例如: ```html <!-- 父组件 --> <template> <div> <slot name="header"></slot> <slot></slot> <slot name="footer"></slot> </div> </template> <!-- 子组件 --> <template> <div> <slot name="header"> <!-- 默认插槽内容 --> <h1>默认标题</h1> </slot> <p>子组件内容</p> <slot name="footer"> <!-- 默认插槽内容 --> <p>默认页脚</p> </slot> </div> </template> ``` 在上面的例子中,父组件定义了三个插槽:`header`、默认插槽和`footer`。子组件可以根据需要填充这些插槽,并且如果没有提供相应的内容,那么会显示插槽中的默认内容。 默认插槽是没有名字的插槽,如果在父组件中没有定义具名插槽的话,子组件的内容会被分发到默认插槽中。 除了使用`<slot>`元素和`name`属性来定义插槽,我们还可以使用`<template>`元素和`v-slot`指令来定义和填充插槽。例如: ```html <!-- 父组件 --> <template> <div> <template v-slot:header> <!-- 插槽内容 --> </template> <!-- 默认插槽内容 --> <template v-slot:default> <!-- 插槽内容 --> </template> <template v-slot:footer> <!-- 插槽内容 --> </template> </div> </template> ``` 使用插槽可以使我们的组件更具灵活性,可以根据需要在父组件中定制子组件的部分内容。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值