ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Svelte 自定义元素中如何用 $host 向外部应用发送自定义事件

2026/9/11 19:18:57 拓冰建站 浏览量
Svelte 自定义元素中如何用 $host 向外部应用发送自定义事件 Svelte 自定义元素中如何用 $host 向外部应用发送自定义事件【免费下载链接】svelteweb development for the rest of us项目地址: https://gitcode.com/GitHub_Trending/sv/svelte如果你把一个 Svelte 组件编译成自定义元素custom element / web component提供给非 Svelte 的应用使用组件内部就需要一种向宿主元素外部通信的方式。Svelte 的$hostrune 就是为此设计的在编译为自定义元素的组件中$host()返回宿主元素对它调用dispatchEvent派发CustomEvent外部消费方就能通过标准 DOM 事件 API 收到。下面按官方文档中的计数器示例走一遍完整路径。前提条件使用 Svelte 5runes 模式示例中的$state、$props、$host均为 rune。该组件需要以自定义元素方式编译。文档给出两种写法组件级svelte:options customElementmy-stepper /传字符串时它被当作tag选项使用设置后该组件被导入时对应标签名会注册进文档的customElements注册表或编译时开启customElement: true编译器选项再用customElements.define手动注册见下文可选手动注册标签名。第一步组件内用 $host 派发事件按文档示例写Stepper.svelte/// file: Stepper.svelte svelte:options customElementmy-stepper / script function dispatch(type) { $host().dispatchEvent(new CustomEvent(type)); } /script button onclick{() dispatch(decrement)}decrement/button button onclick{() dispatch(increment)}increment/button要点svelte:options customElementmy-stepper /声明本组件编译为标签名my-stepper的自定义元素dispatch(type)中$host()取到的是自定义元素的宿主 DOM 节点dispatchEvent(new CustomEvent(type))在该宿主节点上派发事件事件名由调用方决定这里是decrement/increment。第二步消费方监听事件官方示例中的 Svelte 消费方App.svelte如下文档原例/// file: App.svelte script import ./Stepper.svelte; let count $state(0); /script my-stepper ondecrement{() count - 1} onincrement{() count 1} /my-stepper pcount: {count}/pimport ./Stepper.svelte这一步同时完成了标签注册因此App.svelte里可以直接写my-stepper并用on 事件名的属性形式挂接两个自定义事件。对于非 Svelte 的外部应用自定义元素可以像普通 DOM 元素一样使用文档原话监听逻辑就是标准的 DOM 事件绑定。以下为非 Svelte 场景的示例写法示例基于文档中document.body.innerHTMLquerySelector的用法import ./Stepper.svelte; // 导入即注册 my-stepper 标签 document.body.innerHTML my-stepper/my-stepper; document.querySelector(my-stepper).addEventListener(increment, () { // 处理 increment 事件 });验证结果文档示例的验证点是pcount: {count}/p点击decrement/increment按钮后$host派发的decrement/increment事件被App.svelte上的处理器收到count相应增减并显示出来。外部应用中则表现为addEventListener的回调被触发。如果需要让事件携带数据文档主体示例没有展示负载写法Svelte 的 v5 迁移指南提到事件负载通过事件的.detail属性在对端获取即CustomEvent的detail字段模式可按标准CustomEventAPI 在派发时传入。可选手动注册标签名内部不想暴露标签名的组件可以省略customElement消费方拿到静态element属性包含自定义元素构造函数在customElement编译器选项为true时可用后自行注册import MyElement from ./MyElement.svelte; customElements.define(my-element, MyElement.element);坑与限制以下均来自 自定义元素文档 的说明直接决定外部应用能否正确消费你的组件props 必须显式列出。let props $props()整体解构时Svelte 不知道哪些 props 要暴露为 DOM 元素属性必须逐个声明如let { name world } $props();外部才能通过el.name这样的方式读写。不要声明以on开头的属性或属性名。Svelte 会把它当作事件监听器custom-element oneworld{true}等价于customElement.addEventListener(eworld, true)而不是给oneyword属性赋值。事件名与 prop 命名冲突时会被静默误解。生命周期是下一 tick语义元素创建后内部 Svelte 组件在connectedCallback之后的下一 tick 才创建插入 DOM 前赋给元素的属性会暂存、在组件创建时应用但在挂载前调用导出的函数无效shadow DOM 对属性更新也是下一 tick 才反映以此实现更新批处理。不适用于服务端渲染shadow DOM 在 JavaScript 加载前不可见自定义元素一般不适合 SSR。样式是封装而非作用域除非shadow: noneglobal.css之类的外部样式不会作用于自定义元素内部:global(...)选择器同样不生效。context 不能跨自定义元素可以在同一个自定义元素内部的普通 Svelte 组件之间用 context但无法在父、子两个自定义元素之间用setContext/getContext传递。参考文档$host rune 文档$host的定义与派发CustomEvent的完整示例Custom elements 文档编译选项、生命周期、组件选项与限制svelte:options文档customElement选项的说明【免费下载链接】svelteweb development for the rest of us项目地址: https://gitcode.com/GitHub_Trending/sv/svelte创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考