如何理解Vue.js的组件中的slot?

官方文档中这一节看不太懂,是否可以解释一下?slot应用场景在哪里?

阅读 21.4k
8 个回答

文档很清楚,这里给个最浅显的例子。

比如你自己做了个一个button组件,在根组件里注册为vButton,从而复用。
那么各个button上的文字肯定是不同的,但是这些文字大部分情况下也是不需要动态更新的,那么就不必用props之类的方法从根组件向子组件传递文字,直接用slot即可。

button组件假如是这样:

<template>
  <button>
    <slot></slot>
  </button>
</template>

根组件就可以这样用它:

<v-button>按钮文字</v-button>

这是最简单的一个用法示例。

slot之前我们先来说一般组件,通常我们自定义一个组件,期待用户这样使用它们:

<自定义组件 :参数="variable" @事件="handler"></自定义组件>

这种组件产生的样式都在自定义组件的内部,使用者是无法对其进行调整的,或者说没办法通过传入一些html进行调整

现在假设我们有这样一个名片组件的需求,该名片组件的除了标题外还希望提供使用者便利可以自行调整主体内容的格式,设计的结果是这样:

<名片 :url="名片地址">
    <h1>我是我</h1>
    <strong>我就是不一样的烟火!!!</strong>
    <img src="我的头像在这里"></img>
</名片>

OK,看到了需求,用户希望你的组件可以这样使用,你怎么办?这就是slot出现的背景,最后上文档,方便理解

图片描述

简单点说就是,能够在组件内写其他内容,举个例子:
我们有一个组件 app, 然后在页面中使用这个组件的时候:

<div>
  <app></app>
</div>

这个时候我们的app是已经定义好了内容的,那如果我想在app里再加入点其他内容呢,像这样:

<div>
  <app>
    <p>新添加的p标签</p>
  </app>
</div>

如果没有slot那上面这样写就会报错,如果我们在app组件内有一个slot那这样写就是可以的~

主要是让组件的可扩展性更强。
1.匿名slot使用

//定义组件my-component
<div class="myComponent">
  <slot></slot>
</div>
//使用方法
<my-component>
  <p>我就是slot的替代内容,这里可以放任何标签元素,即使是一长串ul>li列表</p>
</my-component>

2.具名slot使用

//定义组件my-component
<div class="myComponent">
  <slot name="mySlot"></slot>
</div>
//使用方法
<my-component>
  <p slot="mySlot">我就是这个叫mySlot的slot替代内容,这里可以放任何标签元素,即使是一长串ul>li列表,但是我是一个有名字的宝宝,所以你必须给我加上slot="mySlot",不然我就报错给你看!</p>
</my-component>

如果不在有slot的组件里加入任何标签,slot什么都不会显示的。

新手上路,请多包涵

vue.js入门与提高(地址:http://xc.hubwiz.com/course/5...

中这样写道:

槽/slot是组件在模板中为调用者预留的位置,使用<slot>元素声明一个 槽。在最终的视图中,调用者模板中被调用组件的内容,将填充<slot>元素 占据的位置,形成最终的模板 —— 很形象,对吧:

clipboard.png

可以将槽视为组件模板延迟实现的一种手段 —— 当组件的开发者希望为调用方 预留一部分模板定义的能力时,就使用槽来预留插入点。

例如,对于一个面板组件EzPanel,内容区域应该预留给调用者来填充:

clipboard.png

组件模板:声明槽位

我们在定义EzPanel的模板时,使用<slot>元素来预留插入点:

<div class="ez-panel">
<div class="header">Panel Title</div>
<div class="content">

<slot></slot> <!--预留的插入点-->

</div>
</div>
你看,EzPanel的模板定义了一个框架,通过槽为调用者预留了内容插入的位置。

调用者模板:提供槽内容

在调用者的模板中,被调用组件的内容(后代元素),将在渲染时被填充到被调用组件模板中 所声明的槽位:

<ez-panel>
<!--ez-panel的内容将被插入ez-panel的槽位-->
<p>paragraph 1</p>
<p>paragraph 2</p>
</ez-panel>
因此,最终我们得到的视图,是EzPanel的模板和调用者所提供槽内容的结合:

<div class="ez-panel">
<div class="header">Panel Title</div>
<div class="content">

<p>paragraph 1</p>
<p>paragraph 2</p>

</div>
</div>

slot文档给的解释是插槽。刚开始看到这个名词也不是特别的理解。然后文档上写着说Angulartransclusion概念差不多。

wiki上有这样一句话解释:

transclusion在计算机科学中指的是讲一个文档或者一个文档的某部分在另一个文档中引用

所以你再去看文档和给个示例,那么应该有点感觉了。

它主要的作用就是父组件中自定义的内容插入到子组件所提供的匿名/具名插槽当中

所以你可以在父组件中定义好额外的模板内容,

    <div class="parent">
        <child>
            <div>This child slot</div>   //需要插入到子组件的模板内容
        </child>
    </div>

child组件:

    <div class="child">
        <slot>This init child slot</slot>   //父组件插入的位置, 如果父组件中不提供需要插入的内容,那么就会显示子组件slot中默认的内容
    </div>

官网其实已经解释得很清楚了 内容分发 简单点就是 一个组件的一部分 你不满足默认的内容太过简单 那么你可以将这部分定义成slot这个里面放默认的内容 当用户需要自定义这部分内容的时候就可以使用这个特性去定义自己更加高级 更加复杂的内容 使用方法文档都有 手机码字 我就不贴地址了

通常情况下,子组件的内容只能在子组件中定义。

但是通过 slot,父组件定的内容可以传到子组件中去。

  1. 普通用法

//父组件中
<my-cmp></mycmp>

//子组件中
balabala

//渲染结果
 balabala 

2.slot 用法(这并不是必要的,视需求而定)

//父组件中
<my-cmp>
  biubiubiu
</my-cmp>

//子组件中
balabala
<slot></slot>

//渲染结果
balabala
biubiubiu
推荐问题
宣传栏