自定义元素名必须含短横线,如quark-button;Shadow DOM mode须为open;attributeChangedCallback仅响应observedAttributes声明的属性变更;跨框架需手动适配事件并同步属性更新。

自定义元素名必须带短横线,否则会报错
浏览器强制要求自定义元素名包含至少一个短横线(-),否则调用 customElements.define 时直接抛出错误:Failed to execute 'define' on 'CustomElementRegistry': The name "mybutton" is not a valid custom element name。
常见无效写法包括:mybutton(无短横线)、-my-btn(开头连字符)、my-btn-(结尾连字符)、123(纯数字)、abc(纯字母)。合法命名惯例是全小写 + 短横线分隔,比如 quark-button、user-card、data-input-field。
大小写不敏感,但混用大小写(如 MyButton)不仅违反惯例,还可能在某些构建流程中引发路径或注册冲突。
Shadow DOM mode 必须选 open,closed 基本不可用
attachShadow({ mode: 'open' }) 是绝大多数场景的唯一合理选择。它让 el.shadowRoot 可访问,支持 DevTools 查看结构、Jest 测试中查询内部节点、Puppeteer 自动化定位元素——这些是工程化落地的基础能力。
立即学习“前端免费学习笔记(深入)”;
mode: 'closed' 会让 shadowRoot 返回 null,导致:
- 无法在浏览器开发者工具中展开 Shadow DOM 节点
-
querySelector或shadowRoot.querySelector失效 - 所有依赖影子树探测的测试/调试/集成工具链中断
除非你明确需要防样式劫持(如金融类组件),否则 closed 不是“更安全”,而是“不可维护”。且 attachShadow 只能调用一次,重复调用会报错:This element already has a shadow root。
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
attributeChangedCallback 不触发?先检查 observedAttributes
这个回调只响应你在 static get observedAttributes() 中显式声明的属性,并且仅对以下三种方式生效:el.setAttribute('loading', 'true')、el.removeAttribute('loading')、或 HTML 标签内写死 <my-button loading></my-button>。JS 直接赋值 el.loading = true 不会触发。
排查要点:
-
observedAttributes必须返回字符串数组,例如return ['loading', 'disabled'],不能是对象或单个字符串 - 属性名严格匹配:写成
'Loading'或'LOADING'都不会监听到loading - 不要在
constructor中就设置属性值,此时connectedCallback尚未执行,回调不会立即运行
如果想监听布尔属性(如 loading),HTML 中必须用存在即真语义:<my-button loading></my-button>,而不是 <my-button loading="true"></my-button> —— 后者会被当作字符串值处理。
跨框架使用时,事件需手动适配 React/Vue
Web Components 发出的事件(如 new CustomEvent('click'))默认是冒泡的,但在 React 中不会自动映射为 onClick,Vue 中也不会绑定为 @click。必须显式处理:
- React:用
ref获取原生元素后,调用addEventListener;或封装一层 wrapper 组件做事件代理 - Vue:使用
v-on的修饰符@click.native(Vue 2)或@click.capture(Vue 3),或通过defineCustomElement工具链生成适配器
Quark Design 提供了 packages/quark-reactify 这类工具库,本质就是把 quark-button 的 click 事件转成 React 的合成事件流。裸用 Web Components 时,这部分适配必须自己补上,否则交互逻辑会静默失效。
真正容易被忽略的是:组件内部状态变更(比如按钮点击后切换 loading 状态)必须同步更新属性,并触发 attributeChangedCallback,否则父框架无法感知变化——这不像 React/Vue 的响应式系统会自动同步。


















