vue 插槽slot

本文是对官网内容的整理 https://cn.vuejs.org/v2/guide/components.html#编译作用域

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

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

注意两点:

  1. <app> 组件不知道它会收到什么内容。这是由使用 <app> 的父组件决定的。

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

为了让组件可以结合,我们需要一种方式来混合父组件的内容和子组件自己的模板,这个过程叫内容分发,Vue.js 实现了一个内容分发 API,使用特殊的 <slot> 元素作为原始内容的插槽。

单个插槽

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

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

具名插槽

<slot> 元素可以用一个特殊的特性 name 来进一步配置如何分发内容。多个插槽可以有不同的名字。具名插槽将匹配内容片段中有对应 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 新增)

作用域插槽是一种特殊类型的插槽,用作一个 (能被传递数据的) 可重用模板,来代替已经渲染好的元素。

在子组件中,只需将数据传递到插槽,就像你将 prop 传递给组件一样:

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

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

<div class="parent">
    <child>
        <template slot-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>

在Vue 2.5.0+,slot-scope 能被用在任意元素或组件中而不再局限于 <template>

作用域插槽更典型的用例是在列表组件中,允许使用者自定义如何渲染列表的每一项:

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

列表组件的模板:

<ul>
    <slot name="item"
        v-for="item in items"
        :text="item.text">
       <!-- 这里写入备用内容 -->
    </slot>
</ul>

解构

slot-scope 的值实际上是一个可以出现在函数签名参数位置的合法的 JavaScript 表达式。这意味着在受支持的环境 (单文件组件或现代浏览器) 中,您还可以在表达式中使用 ES2015 解构:

<child>
<span slot-scope="{ text }">{{ text }}</span>
</child>
原文地址:https://www.cnblogs.com/fanlinqiang/p/7756636.html