Stencil组件需将HTML拆分为结构(JSX render函数)和行为(TypeScript类),用@Component装饰,标签转小驼峰、属性按JSX规则(如className),样式移入styleUrl或styles,事件绑定改用onClick等标准DOM事件处理器。

HTML 文件怎么变成 Stencil 组件
Stencil 不吃纯 HTML 文件,它只认 @Component 装饰的 TypeScript 类。直接扔一个 index.html 进去,stencil build 会完全无视——它不是静态站点生成器,而是 Web Component 编译器。
实操上必须把 HTML 拆成「结构 + 行为」两部分:用 render() 函数返回 JSX(本质是 JS 对象),把原 HTML 标签转成小驼峰写法(如 <my-button></my-button> → MyButton),属性也得按 JSX 规则来(class → className,for → htmlFor)。
- 别在
render()里写字符串模板,比如return `<div>${this.name}</div>`—— Stencil 不解析 HTML 字符串,会原样输出 - 原 HTML 中的内联样式、
<style></style>标签要挪到组件的styleUrl或styles属性里,否则不生效 - 如果有多个页面级 HTML,别试图塞进一个组件;按功能拆,比如
header.html→MyHeader,product-card.html→MyProductCard
如何复用已有 HTML 的 CSS 和结构
Stencil 支持 styleUrl 加载外部 CSS,但注意:它只支持相对路径,且编译时会把样式 scope 到组件内部(加随机属性选择器)。如果你原来 HTML 依赖全局类名(比如 .btn-primary),这些样式不会自动穿透进来。
- 把原有 CSS 拷贝进
src/components/my-component/my-component.css,然后在组件定义里写styleUrl: 'my-component.css' - 若需保留全局样式影响(不推荐),改用
styles属性并手动加:host { }或:host ::slotted(*),但会破坏封装性 - 原 HTML 中带
id的元素(如<div id="modal-root">)在组件里失效——Web Component 影子 DOM 隔离了 ID 查找,得用 <code>document.getElementById在 shadowRoot 外调用,或改用 class +this.el.shadowRoot.querySelectorHTML 表单、事件和交互怎么迁移
原 HTML 里的
onclick="doSomething()"、onsubmit等内联事件绑定,在 Stencil 里必须转成 JSX 事件处理器,且函数需定义在组件类中。Stencil 使用标准 DOM 事件名(小写,无on前缀),比如onClick→click。
Wechat Article Html下载将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
立即学习“前端免费学习笔记(深入)”;
-
<button onclick="alert(1)"></button>→<button onclick="{()"> alert(1)}></button>,但更推荐提成方法:<button onclick="{this.handleClick}"></button>,并在类里定义handleClick = () => { ... } - 表单提交要阻止默认行为:
event.preventDefault()不能少,否则页面刷新;Stencil 不自动处理这个 - 原 HTML 用
document.querySelector拿元素?在组件里得用this.el.shadowRoot.querySelector(如果用了 Shadow DOM),或者this.el.querySelector(如果shadow: false) -
input的双向绑定不存在——Stencil 没有v-model或ngModel,得手动监听input事件 + 更新@State变量
构建后怎么让组件在普通 HTML 页面里用
运行
stencil build后,产物在dist/下,关键文件是my-component/my-component.js(ES module)和my-component/my-component.esm.js(现代浏览器用)。你不能直接<script src="dist/my-component.js"></script>就完事——它导出的是模块,不是全局变量。- 必须用
<script type="module"></script>加载,或通过构建工具(Vite/Webpack)导入 - 如果要在传统 HTML 里快速验证,得启用 Stencil 的
www输出目标,在stencil.config.ts里加{ type: 'www' },然后npm run build会生成可直接打开的index.html - 自定义元素名必须含短横线(
-),比如my-button合法,mybutton会报CustomElementRegistry.define: "mybutton" is not a valid custom element name
最常被跳过的一步:忘了在 HTML 中先加载组件 bundle,再写
<my-button></my-button>。顺序错了,标签就只是普通未知元素,不会升级为组件。 -


















