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>
相关推荐
zd8451015003 小时前
基于 HTML 与 Modbus TCP 构建设备仪器上位机:可行性分析与代码结构设计
前端·tcp/ip·html
顽疲3 小时前
Java vue 养老系统源码详解:入住核算单 live-check 缴费入账与预交金收据实践
java·vue.js·python·java 养老·springboot 养老·vue养老
Amumu121383 小时前
NodeJs介绍
前端·node.js
咧咧小侠4 小时前
Windows Codex 连接 Chrome 失败:一次 nodeRepl.fetch 报错排查记录
前端·chrome
Eider19984 小时前
大模型输出格式幻觉解决思路
开发语言·前端·javascript
广州智造4 小时前
Radioss时间步长(Time Step)
前端·设计·cad·建模·cae·radioss
志尊宝4 小时前
Vue3 零基础每日笔记(085):项目上线前 Checklist——环境变量、报错监控、安全自查
前端·javascript·笔记·安全·信息可视化·echarts
朱涛的自习室4 小时前
我让 Gemini 4 当高管、DeepSeek 当员工,开了一家软件公司(Day 1)
android·前端·人工智能
志尊宝4 小时前
Vue3 零基础每日笔记(088·完结):从零到一——一个完整 Vue3 项目的成长复盘
前端·javascript·vue.js·笔记·ecmascript·#vue.js
deli0074 小时前
加一台机器,为什么只有 1/N 的 key 要搬家?一致性哈希实测
前端