美文网首页
关于插槽 slot

关于插槽 slot

作者: 爆发吧小宇宙 | 来源:发表于2019-06-24 21:05 被阅读0次

    本篇(可能此系列会包含很多篇)纯属从Vue官方文档找来的内容,也可能会根据自身的知识情况扩展、延伸、归纳,进行个性化总结排版,方便自己记录和查阅。

    在Vue2.6.0中具名插槽和作用域插槽引入了新的统一的语法(v-slot指令)。它取代了 slot 和slot-scope两个特性。

    插槽作用域

    当父级模板里的内容编译时只会在父级作用域里生效;子模板里的所有内容都是在子作用域里编译。
    例子:

    # <navigation-link> 组件
    <a
      v-bind:href="url"
      class="nav-link"
    >
      <slot></slot>
    </a>
    

    该插槽跟模板的其它地方一样可以访问相同的实例属性 (也就是相同的“作用域”),而不能访问 <navigation-link> 的作用域。例如 url 是访问不到的:

    <navigation-link url="/profile">
      Clicking here will send you to: {{ url }}
      <!--
      这里的 `url` 会是 undefined,因为 "/profile" 是
      _传递给_ <navigation-link> 的而不是
      在 <navigation-link> 组件*内部*定义的。
      -->
    </navigation-link>
    

    具名插槽

    有时我们需要多个插槽。例如对于一个带有如下模板的 <base-layout> 组件:

    <div class="container">
      <header>
        <!-- 我们希望把页头放这里 -->
      </header>
      <main>
        <!-- 我们希望把主要内容放这里 -->
      </main>
      <footer>
        <!-- 我们希望把页脚放这里 -->
      </footer>
    </div>
    

    <slot> 元素有一个特殊的特性:name。这个特性可以用来定义额外的插槽:

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

    一个不带 name 的 <slot> 出口会带有隐含的名字“default”。

    在向具名插槽提供内容的时候,我们可以在一个 <template> 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称:

    <base-layout>
      <template v-slot:header>
        <h1>Here might be a page title</h1>
      </template>
    
      <p>A paragraph for the main content.</p>
      <p>And another one.</p>
    
      <template v-slot:footer>
        <p>Here's some contact info</p>
      </template>
    </base-layout>
    

    现在 <template> 元素中的所有内容都将会被传入相应的插槽。任何没有被包裹在带有 v-slot 的 <template> 中的内容都会被视为默认插槽的内容。
    如果想更明确一些,仍然可以在一个 <template> 中包裹默认插槽的内容:

    <base-layout>
      <template v-slot:header>
        <h1>Here might be a page title</h1>
      </template>
    
      <template v-slot:default>
        <p>A paragraph for the main content.</p>
        <p>And another one.</p>
      </template>
    
      <template v-slot:footer>
        <p>Here's some contact info</p>
      </template>
    </base-layout>
    

    任何一种写法都会渲染出:

    <div class="container">
      <header>
        <h1>Here might be a page title</h1>
      </header>
      <main>
        <p>A paragraph for the main content.</p>
        <p>And another one.</p>
      </main>
      <footer>
        <p>Here's some contact info</p>
      </footer>
    </div>
    

    注意 v-slot 只能添加在一个 <template> 上, 只有一种例外情况:

    当被提供的内容只有默认插槽时,组件的标签才可以被当作插槽的模板来使用。这样我们就可以把 v-slot 直接用在组件上:

    <current-user v-slot:default="slotProps">
      {{ slotProps.user.firstName }}
    </current-user>
    

    这种写法还可以更简单。就像假定未指明的内容对应默认插槽一样,不带参数的 v-slot 被假定对应默认插槽:

    <current-user v-slot="slotProps">
      {{ slotProps.user.firstName }}
    </current-user>
    

    注意默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确:

    <!-- 无效,会导致警告 -->
    <current-user v-slot="slotProps">
      {{ slotProps.user.firstName }}
      <template v-slot:other="otherSlotProps">
        slotProps is NOT available here
      </template>
    </current-user>
    

    只要出现多个插槽,请始终为所有的插槽使用完整的基于 <template> 的语法:

    <current-user>
      <template v-slot:default="slotProps">
        {{ slotProps.user.firstName }}
      </template>
    
      <template v-slot:other="otherSlotProps">
        ...
      </template>
    </current-user>
    

    动态插槽

    动态指令参数也可以使用在 v-slot 上,来定义动态的插槽名:

    <base-layout>
      <template v-slot:[dynamicSlotName]>
        ...
      </template>
    </base-layout>
    

    具名插槽的缩写

    跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header 可以被重写为 #header:

    <base-layout>
      <template #header>
        <h1>Here might be a page title</h1>
      </template>
    
      <p>A paragraph for the main content.</p>
      <p>And another one.</p>
    
      <template #footer>
        <p>Here's some contact info</p>
      </template>
    </base-layout>
    

    然而,和其它指令一样,该缩写只在其有参数的时候才可用。这意味着以下语法是无效的:

    <!-- 这样会触发一个警告 -->
    <current-user #="{ user }">
      {{ user.firstName }}
    </current-user>
    

    如果你希望使用缩写的话,你必须始终以明确插槽名取而代之:

    <current-user #default="{ user }">
      {{ user.firstName }}
    </current-user>
    

    相关文章

      网友评论

          本文标题:关于插槽 slot

          本文链接:https://www.haomeiwen.com/subject/gssaqctx.html