ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Stencil 嵌套 slot 组件实战:以 slot-parent-cmp 为例解析插槽转发、默认插槽与自动文档生成

Stencil 嵌套 slot 组件实战:以 slot-parent-cmp 为例解析插槽转发、默认插槽与自动文档生成 开发工具前端前端构建【免费下载链接】stencilA toolchain for building scalable, enterprise-ready component systems on top of TypeScript and Web Component standards. Stencil components can be distributed natively to React, Angular, Vue, ( more) and traditional web applications from a single, framework-agnostic codebase.项目地址https://gitcode.com/gh_mirrors/st/stencil点击查看免费下载导读本文以 Stencil 仓库 test/end-to-end 端到端测试套件中的 slot-parent-cmp 组件为实例系统讲解 Stencil 组件中slot插槽的声明方式、嵌套转发机制、默认插槽的透传以及docs-readme输出目标如何自动生成组件 API 文档与依赖关系图。读完本文你将掌握 Stencil 中「组件声明slot /→ 上层组件转发子内容 → Shadow DOM 渲染 → e2e 断言验证」的完整链路并能读懂仓库中任意组件自动生成的readme.md。说明test/end-to-end/src/slot-parent-cmp/readme.md是 Stencil 通过docs-readme输出目标自动生成的组件文档属于组件 API 快照其信息完全来源于组件源码元数据因此本文以该自动文档为骨架结合源码、运行时实现与 e2e 测试展开解读。一、自动生成的组件文档readme.md 里有什么slot-parent-cmp的 readme.md 由编译器自动生成包含四个固定小节Properties属性、Slots插槽、Dependencies依赖关系、以及依赖图Mermaid。这类文档的生成逻辑位于 src/compiler/docs/readme 目录例如 markdown-slots.ts 会把组件元数据中的插槽信息渲染成## Slots表格表头固定为Slot | Description默认插槽name为空字符串在表格中表现为空白的 Slot 单元格具名插槽则会以name的形式输出。也就是说本文档中 The default slot 这一行正是编译器从 slot-parent-cmp.tsx 源码中提取出的插槽声明生成的。readme.md第一行的# slot-parent-cmp标题也来自组件tag。Properties组件公开属性一览文档的 Properties 表格如下PropertyAttributeDescriptionTypeDefaultlabellabelstringundefined这对应源码中的一行声明Prop() label: string;Property与Attribute同列展示说明该 Prop 未显式配置attribute别名因此默认使用与属性同名的 HTML 属性label。类型string与默认值undefined均来自 Stencil 的静态类型分析。该属性在渲染中被直接输出到组件根节点render() { return ( Host {this.label} ... /Host ); }即当使用者写入slot-parent-cmp labelOne /时组件根元素内会渲染出文本节点One随后才是插槽内容。这为下文要讲的插槽顺序问题埋下了伏笔。二、组件源码一次完整的插槽转发示例slot-parent-cmp.tsx 的全部实现只有十几行但完整演示了 Stencil 插槽的核心用法import { Component, Host, Prop, h } from stencil/core; Component({ tag: slot-parent-cmp, }) export class SlotParentCmp { Prop() label: string; render() { return ( Host {this.label} slot-cmp slot / /slot-cmp /Host ); } }要点拆解slot /声明默认插槽在 JSX 中直接书写slot /表示该组件接收并渲染父级传入的子内容light DOM。由于未指定name它接收的是默认插槽内容。插槽转发slot forwardingslot /被包裹在slot-cmp内部也就是说slot-parent-cmp把接收到的子内容作为slot-cmp的默认插槽内容继续向下传递。这就是文档 Dependencies 中slot-parent-cmp -- slot-cmp这条边对应的运行时行为。Host根节点承载文本{this.label}渲染在Host内、slot-cmp之前是插槽之外的内容。这一插槽再插槽的嵌套结构正是仓库中 nested-slot-forwarding.spec.tsx 所覆盖的运行时场景——Stencil 的虚拟 DOM 渲染器会把最内层slot /的内容投影到最终落点而不是在中间组件处卡住。三、上下游组件插槽在真实使用中的位置3.1 上游slot-cmp-container如何投喂插槽内容slot-parent-cmp的唯一使用者是 slot-cmp-container后者是一个shadow: true的 Shadow DOM 组件渲染结构如下Host slot-cmp slot-parent-cmp labelOne / /slot-cmp slot-cmp slot-parent-cmp labelTwo / /slot-cmp slot-cmp slot-parent-cmp labelThree / /slot-cmp /Host这里形成了双层传递slot-cmp-container把slot-parent-cmp元素作为slot-cmp的默认插槽内容而每个slot-parent-cmp又会把自身收到的子内容继续转给它的slot-cmp子组件。componentDidLoad中还会执行一次forceUpdate(this.host)用于验证强制刷新后插槽投影依然保持正确顺序。3.2 下游slot-cmp是插槽的最终落点slot-cmp.tsx 是最底层的容器仅声明了一个默认插槽Component({ tag: slot-cmp, styles: slot-cmp { display: inline-block; }, }) export class SlotCmp { render() { return ( Host slot / /Host ); } }整条链路可以概括为slot-cmp-containershadow └─ slot-cmp内含 slot/ └─ slot-parent-cmp内含 slot/ 转发给下一层 └─ slot-cmp内含 slot/最终落点标签文本One/Two/Three来自labelProp与插槽内容最终都会渲染到最内层slot-cmp的默认插槽位置。四、依赖关系与 Mermaid 依赖图slot-parent-cmp的自动文档给出了完整的依赖信息Used byslot-cmp-container即谁在模板中使用了该组件Depends onslot-cmp即该组件的模板引用了哪些自定义元素Graph由上述两个方向合并而成的 Mermaid 依赖图这张图与 slot-cmp-container/readme.md 中的依赖图互为印证容器同时依赖slot-cmp与slot-parent-cmp而slot-parent-cmp依赖slot-cmp因此容器文档的图中有slot-cmp-container -- slot-cmp与slot-cmp-container -- slot-parent-cmp两条边。style行只是 Markdown 生成器的视觉标记用于高亮当前文档所属组件节点。依赖图的生成逻辑可追溯至 src/compiler/docs/readme/markdown-dependencies.tsDependencies 小节与 Mermaid 图它依赖编译期收集的组件依赖元数据——即编译器在分析 JSX 模板时为每个组件记录下它引用的其他自定义元素集合。五、插槽顺序的正确性验证e2e 测试自动文档不会告诉你插槽是否正确渲染这由 e2e 测试保证。slot-cmp-container.e2e.ts 用 Stencil 测试运行时newE2EPage起了一个真实浏览器页面import { newE2EPage } from stencil/core/testing; describe(Slots, () { it(should render the slots in the correct order, async () { const page await newE2EPage({ html: slot-cmp-container/slot-cmp-container }); const element await page.find(slot-cmp-container); expect(element.shadowRoot.textContent).toContain(OneTwoThree); }); });断言textContent包含连续的OneTwoThree这同时验证了三件事三个slot-parent-cmp的label文本按文档顺序渲染每层slot /转发没有丢失或乱序内容Shadow DOM 的插槽分配slot assignment在组件树嵌套后依然正确。这正是仓库中大量 wdio 插槽测试如 slot-basic、slot-nested-order、slot-reorder 等所覆盖主题的 e2e 侧缩影。若想深入底层机制可继续阅读 dom-extras.ts其中包含针对 slotted 节点在 scoped 组件中的prepend/append/insertAdjacent*等方法的修补实现以及 vdom-render.ts 中的插槽投影逻辑。六、如何在自己的组件库中复现这套自动文档 插槽6.1 开启 docs-readme 输出自动生成readme.md依赖 Stencil 配置中的docs-readme输出目标。仓库 test/end-to-end/stencil.config.ts 即为端到端测试项目启用了该输出目标组件源码目录下的readme.md头部注释!-- Auto Generated Below --就是其产物标记。运行stencil build时编译器会扫描所有组件并刷新对应文档。6.2 撰写插槽时遵循的实践默认插槽直接写slot /文档 Slots 表格中 Slot 列为空白Description 可写 The default slot描述文本来自源码中 JSX 注释或默认约定具体以你配置的文档生成行为为准具名插槽写slot namexxx /文档中会以xxx形式呈现见 markdown-slots.ts 的处理逻辑插槽转发中间层组件不要吞掉子内容而是把slot /继续传给目标子组件如上文slot-parent-cmp所示验证仿照 slot-cmp-container.e2e.ts 编写 e2e 断言用shadowRoot.textContent或page.find校验最终渲染文本与顺序。七、小结slot-parent-cmp的自动文档虽小却完整映射出一个 Stencil 插槽嵌套组件的全部关键事实Prop属性声明与默认值、默认插槽的声明与转发、组件间依赖关系与可视化依赖图、以及 e2e 对渲染顺序的验证。理解它就等于理解了 Stencil 文档生成器src/compiler/docs/readme如何从源码元数据产出 API 文档也掌握了编写可转发插槽组件时的标准姿势。后续可继续阅读 test/wdio 下 slot 系列目录如 slot-nested-order、slot-forwarded-slot 相关用例与 nested-slot-forwarding.spec.tsx进一步探索更复杂的插槽投影边界情况。赞分享开发工具前端前端构建【免费下载链接】stencilA toolchain for building scalable, enterprise-ready component systems on top of TypeScript and Web Component standards. Stencil components can be distributed natively to React, Angular, Vue, ( more) and traditional web applications from a single, framework-agnostic codebase.项目地址https://gitcode.com/gh_mirrors/st/stencil点击查看免费下载相关推荐Stencil 组件插槽实战解析从 slot-cmp 组件读懂默认 Slot、依赖图与自动生成文档Stencil 组件插槽实战解析从 slot cmp 组件读懂默认 Slot、依赖图与自动生成文档 slot cmp 是 Stencil 官方端到端end开发工具前端前端构建Stencil 组件 Slot 嵌套组合与自动生成文档实战以 slot-cmp-container 为例Stencil 组件 Slot 嵌套组合与自动生成文档实战以 slot cmp container 为例 在 Stencil 的端到端测试工程 test/en开发工具前端前端构建Nuxt Content 组件插槽(Slot)机制深度解析Nuxt Content 组件插槽 Slot 机制深度解析 什么是组件插槽 在 Nuxt Content 项目中组件插槽 Slot 是一种强大的内容注入机制前端CMS创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表