动态 class 必须用双引号包裹变量并遵循 kebab-case 规范,避免非法 html 和构建/样式失效;禁止模板内拼接不可信内容,优先使用 v-bind:class;bem 结构需严格一致,建议服务端固化 block 名。

模板中 class 属性值必须用双引号包裹变量
不加引号会导致生成非法 HTML,比如 class=btn-primary 这种无引号写法在严格解析下会被视为属性名而非属性值,浏览器可能忽略或错误解析。Template Toolkit、Jinja2、EJS 等模板引擎渲染时若写成 class=[% className %],输出就是裸字符串,querySelector('.btn-primary') 会失效,jQuery 的 $('[class=btn-primary]') 也匹配不到。
实操建议:
- 始终写作
class="[% className %]"或class="{{ className }}" - 多个类名拼接时,用空格连接并整体包裹:
class="btn [% size %] [% variant %]" - 避免在模板里做条件拼接(如
class="btn [% active ? 'active' : '' %]"),改用逻辑判断块更清晰
动态 class 名必须符合 kebab-case 规范
前端运行时,el.classList.add('userProfile') 能执行,但对应 HTML 中的 class="userProfile" 在 CSS 里得写成 .userProfile,而多数构建工具(如 PostCSS、Tailwind CLI)默认只处理 kebab-case 类名,且部分 Linter 会报错。
常见错误现象:
- 开发时样式生效,上线后 CI 构建失败或样式丢失
- Git diff 显示中文类名乱码(如
class="用户列表") - Webpack 打包警告 “Non-ASCII character in class name”
正确做法:
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
- 服务端传参前统一转 kebab-case:
userProfile → user-profile,可用lodash.kebabCase或正则str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase() - 模板中直接使用已规范化的变量,不现场转换
- 禁止用拼音或混合大小写:
yonghuList、UserList、user_list全部排除
v-html 动态插入含 class 的 HTML 字符串必须先转义
直接拼接用户输入进 v-html 或 innerHTML,哪怕 class 名本身合法,也可能被注入恶意结构。例如:name = '"><script>alert(1)</script>',拼进 <div class="${name}"></div> 就会提前闭合标签并执行脚本。
关键不是“class 要怎么命名”,而是“整个字符串是否可信”。安全底线:
- 永远不用模板字符串拼接不可信内容:
`<div class="${userInput}">` ❌ <li>对用户输入调用 <code>escapeHTML()后再插入文本节点(非 innerHTML) - 若真需渲染富文本,用
DOMPurify.sanitize()过滤,而非手动 replace - Vue 场景优先用
v-bind:class绑定对象或数组,避开字符串拼接 - block 名由服务端固定传递,不参与动态拼接;元素和修饰符才用变量,如
class="[% block %]__[% element %] [% block %]__[% element %]--[% modifier %]" - 模板里不做嵌套逻辑判断,把组合逻辑提到 JS 层生成完整 class 字符串再传入
- 用 ESLint 插件
stylelint-selector-bem-pattern检查输出 HTML,比人工 review 更可靠
BEM 风格下动态元素名需保持结构一致性
当 block 名动态时(如 [% blockName %]__header),容易漏掉双下划线或混淆层级。比如渲染 card__title 时误写成 card_title 或 card__title__link,前者破坏 BEM 约定,后者语义越界(link 是 title 的一部分,不是 title 里的独立元素)。
建议做法:
最易被忽略的是:动态 class 不只是“能显示出来”,它要能在 CSS、JS、构建链路、协作沟通中全程一致——少一个连字符,就可能让三个人花两小时对不上同一个组件。










