组件必须带唯一data-component属性作为运行时识别信标,禁用class或DOM结构定位;<template>仅定义纯结构,禁止内联脚本/样式;<slot>须显式命名;根节点须语义化标签。

组件必须带 data-component 属性,且值唯一可查
不靠 class 名或嵌套结构定位组件,会因样式调整或 DOM 重组失效。data-component 是运行时识别的唯一信标,所有 JS 初始化、状态管理、测试断言都依赖它。
实操建议:
- 值用 kebab-case,如
data-component="user-avatar",避免空格、大写、特殊字符 - 禁止多个元素共用同一
data-component值(除非是明确的复用容器,如列表项模板) - 服务端渲染时也必须输出该属性——不能只在客户端动态加
- CI 流程中可用正则扫描 HTML 文件,校验是否遗漏或重复:
/data-component="([^"]+)"/g
<template> 标签只用于纯结构定义,禁止内联脚本或样式
把逻辑和样式塞进 <template> 里,会导致 SSR 失效、无法被构建工具提取、调试时看不到真实渲染节点。
正确做法:
立即学习“前端免费学习笔记(深入)”;
-
<template id="modal-dialog">内只含 HTML 元素、必要data-属性、占位文本(如{{title}}),不含<script>或<style> - 样式统一走外链 CSS 或
<style scoped>(若用 Vue),JS 行为由独立模块通过data-component绑定 - 若需默认状态,用
data-state="closed"这类属性,而非写style="display:none"
slot 槽位必须显式声明 name,默认槽用 name="default"
隐式默认槽(没写 name 的 <slot>)在嵌套组件或 SSR 中行为不稳定,Webpack/Vite 的预编译常误判内容归属。
关键细节:
- 所有
<slot>都要带name,包括主内容区:<slot name="default"></slot> - 父级传入时严格匹配:
<my-card><div slot="header">标题</div><div slot="default">正文</div></my-card> - 不支持
slot="xxx"和<slot name="xxx">混用——浏览器解析顺序不一致,某些版本会丢内容
组件根节点必须有明确语义化标签,禁用 <div> 包裹
用 <div> 当根节点会让无障碍阅读器跳过结构信息,也阻碍 CSS 选择器精度(比如 article > * 无法命中)。
按内容选根标签:
- 卡片类:用
<article>或<section> - 导航类:用
<nav> - 表单控件:用
<form>或<fieldset> - 纯 UI 容器(如布局栅格):允许
<div role="region">,但必须带role和aria-label
最常被忽略的是:组件库文档里写的“根元素可替换”,实际项目中没人改——结果全页面都是 <div data-component="...">,语义彻底丢失。



















