vue 插槽(二)

渲染作用域

插槽内容可以访问到父组件的数据作用域,因为插槽内容本身是在父组件模板中定义的。举例来说:

html 复制代码
<span>{{ message }}</span>
<FancyButton>{{ message }}</FancyButton>

这里的两个 {``{ message }} 插值表达式渲染的内容都是一样的。

插槽内容无法访问子组件的数据。Vue 模板中的表达式只能访问其定义时所处的作用域,这和 JavaScript 的词法作用域规则是一致的。换言之:

父组件模板中的表达式只能访问父组件的作用域;子组件模板中的表达式只能访问子组件的作用域。

默认内容

在外部没有提供任何内容的情况下,可以为插槽指定默认内容。比如有这样一个 <SubmitButton> 组件:

html 复制代码
<button type="submit">
  <slot></slot>
</button>
<button type="submit">
  <slot>
    Submit <!-- 默认内容 -->
  </slot>
</button>

现在,当我们在父组件中使用 <SubmitButton> 且没有提供任何插槽内容时:

html 复制代码
<SubmitButton />

"Submit"将会被作为默认内容渲染:

html 复制代码
<button type="submit">Submit</button>

但如果我们提供了插槽内容:

html 复制代码
<SubmitButton>Save</SubmitButton>

那么被显式提供的内容会取代默认内容:

html 复制代码
<button type="submit">Save</button>

具名插槽

有时在一个组件中包含多个插槽出口是很有用的。举例来说,在一个 <BaseLayout> 组件中,有如下模板:

html 复制代码
<div class="container">
  <header>
    <!-- 标题内容放这里 -->
  </header>
  <main>
    <!-- 主要内容放这里 -->
  </main>
  <footer>
    <!-- 底部内容放这里 -->
  </footer>
</div>

对于这种场景,<slot> 元素可以有一个特殊的 attribute name,用来给各个插槽分配唯一的 ID,以确定每一处要渲染的内容:

html 复制代码
<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

这类带 name 的插槽被称为具名插槽 (named slots)。没有提供 name<slot> 出口会隐式地命名为"default"。

在父组件中使用 <BaseLayout> 时,我们需要一种方式将多个插槽内容传入到各自目标插槽的出口。此时就需要用到具名插槽了:

要为具名插槽传入内容,我们需要使用一个含 v-slot 指令的 <template> 元素,并将目标插槽的名字传给该指令:

html 复制代码
<BaseLayout>
  <template v-slot:header>
    <!-- header 插槽的内容放这里 -->
  </template>
</BaseLayout>

动态插槽名

动态指令参数v-slot 上也是有效的,即可以定义下面这样的动态插槽名:

html 复制代码
<base-layout>
  <template v-slot:[dynamicSlotName]>
    ...
  </template>

  <!-- 缩写为 -->
  <template #[dynamicSlotName]>
    ...
  </template>
</base-layout>

作用域插槽

在上面的渲染作用域中我们讨论到,插槽的内容无法访问到子组件的状态。

然而在某些场景下插槽的内容可能想要同时使用父组件域内和子组件域内的数据。要做到这一点,我们需要一种方法来让子组件在渲染时将一部分数据提供给插槽。

我们也确实有办法这么做!可以像对组件传递 props 那样,向一个插槽的出口上传递 attributes:

html 复制代码
<!-- <MyComponent> 的模板 -->
<div>
  <slot :text="greetingMessage" :count="1"></slot>
</div>
<MyComponent v-slot="slotProps">
  {{ slotProps.text }} {{ slotProps.count }}
</MyComponent>
相关推荐
爱喝水的鱼丶39 分钟前
SAP-ABAP:SAP 与 ABAP 关联逻辑与入门路径:业务×开发的协作指南
服务器·前端·数据库·学习·sap·abap
小陈的进阶之路1 小时前
Python系列课(2)——判断
java·前端·python
2301_815645381 小时前
html.
前端·html
qq_381338501 小时前
CSS @layer 级联层实战指南:从样式冲突到分层架构
前端·css
广州华水科技1 小时前
深度测评2026年好用的单北斗GNSS变形监测系统推荐,提升GNSS位移监测精度,引领智能监控新风尚
前端
花归去2 小时前
vue3中 function getText(){} 、 const getText=()=>{} ;区别在哪里,优缺点
javascript·vue.js·ecmascript
ZC跨境爬虫2 小时前
跟着 MDN 学 HTML day_33:(Attr 接口与属性节点的深入理解)
前端·javascript·ui·html·音视频·html5
神所夸赞的夏天2 小时前
如何获取多层json数据,存成dictionary,并取最大最小值
java·前端·json
红色的小鳄鱼2 小时前
前端面试js手写
开发语言·前端·javascript