大部分场景其实不需要 Slot,但是如果你想实现一个 UI 库,似乎绕不开它。

简单来说,我们给组件传数据是非常自由的,可以传各种类型的数据,但是如果你想传 DOM,现有的机制是做不到的。

因此,我们设计了一套比较灵活的传 DOM 机制,而它是专门为组件服务的。

<Component>
   text
</Component>

在上面的例子中,我们仅仅给组件传了一个字符串。

如果你希望字符串旁边加个图标,可以这么做:

<Component>
    <i class="icon-info"></i>
    text
</Component>

在组件的模板中,你希望获取外部传入的这个 DOM,可以这么取:

<button>
   <slot name="children" />
</button>

这里出现了一个模式的 slot 标签,不要惊慌,这个标签的作用仅仅是用来取外部传入的 DOM(不然你发明一个更自然的语法来看看啊)。

至于这个 slot 的 name 为啥叫做 children,没办法,如果你没取名字,默认就叫做 children

下面讲解怎么给 slot 取名字。

有时候,你希望传入多个 DOM,比如左边一个图标,右边一个图标:

<Component>
    <template slot="left">
        <i class="icon-left"></i>
    </template>
    <template slot="right">
        <i class="icon-right"></i>
    </template>
    text
</Component>

这里的重点是 template 标签,它的作用仅仅是声明一个 slot,并用 slot 属性取名字,方便在组件内部引用。

为什么要单独用一个 template 标签呢?主要考虑可能传入多个元素。

此外,大家可能注意到这里还有个孤零零的 text,它并非是多余的,我们的初衷是,如果组件标签内部定义的模板没有名字,那它统统属于 children

我们知道了 slot 的命名机制,在实际使用中,通常还需要判断是否存在该 slot,换句话说,父组件是否往下传了该 slot 呢?

为此,我们添加了一个全局过滤器,使用方式如下:

<div>
    {{#if hasSlot('slot 的名字')}}
        存在
    {{else}}
        不存在
    {{/if}}
</div>

results matching ""

    No results matching ""