Vue.js前端框架系统学习(8)——slot插槽

slot插槽

下述内容引用自官网:

在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slotslot-scope 这两个目前已被废弃但未被移除且仍在文档中的 attribute。

所以我们直接来看v-slot这个API:

v-slot

  • 缩写#

  • 预期:可放置在函数参数位置的 JavaScript 表达式 (在支持的环境下可使用解构)。可选,即只需要在为插槽传入 prop 的时候使用。

  • 参数:插槽名 (可选,默认值是 default)

  • 限用于

    • <template>
    • [组件] (对于一个单独的带 prop 的默认插槽)
  • 用法

    提供具名插槽或需要接收 prop 的插槽。

具名插槽

我这里直接参照官网给出的例子:

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

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

对于这样的情况,<slot> 元素有一个特殊的 attribute:name。这个 attribute 可以用来定义额外的插槽:

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

可以看到,在模版中的slot部分添加了name属性,这种插槽便是具名插槽(也就是具备name的插槽),而像<slot></slot>这样的插槽便是匿名插槽(也成为默认插槽),即不具备name属性,但是他会有一个隐含的名字default。当我们需要多个插槽的时候就必须要指定name,因为一个匿名插槽是做不到的。所以我们在一个template中使用v-slot指令,以参数的形式为其提供name。

<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中的元素都会被传入到相应的插槽中。举个例子,咱们挖了好几个坑,插上了对应的小旗以示区别,相当于我们指定的name属性,然后别人来填坑的时候对应着小旗将土填进去.也就是对应的template中会被传入对应的元素。

作用域插槽

有时让插槽内容能够访问子组件中才有的数据是很有用的。例如,设想一个带有如下模板的 组件:

<span>
  <slot>{{ user.lastName }}</slot>
</span>

我们可能想换掉备用内容,用名而非姓来显示。如下:

<current-user>
  {{ user.firstName }}
</current-user>

然而上述代码不会正常工作,因为只有 <current-user> 组件可以访问到 user 而我们提供的内容是在父级渲染的。

这是什么意思呢?显然我们在子组件current-user中已经定义好一个值了,就像这里的user.lastName,而在父组件中我想将子组件中的user.lastName改成user.firstName,这个时候直接采用上述的代码就无法进行修改,原因很明确了:

因为只有 <current-user> 组件可以访问到 user 而我们提供的内容是在父级渲染的.

所以我们就得想法子,也就是让user在父组件中也可用,那把user作为的一个属性绑定上去,一起传给父组件不就可以了嘛,这样父组件中就可以访问user.firstName了。

<span>
  <slot v-bind:user="user">
    {{ user.lastName }}
  </slot>
    <!-- 在子组件中绑定user属性 -->
</span>

绑定在 元素上的 attribute 被称为插槽 prop。现在在父级作用域中,我们可以使用带值的 v-slot 来定义我们提供的插槽 prop 的名字:

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

在这个例子中,我们选择将包含所有插槽 prop 的对象命名为 slotProps,但你也可以使用任意你喜欢的名字。

写在后面

主要整理了具名插槽和作用域插槽,更多用法还请参考官方文档。仅供学习参考使用,有问题欢迎指出!

posted @ 2020-09-10 15:31  陆黎  阅读(290)  评论(0编辑  收藏  举报