组件模板必须用 slot 而非 v-html 渲染插槽内容,所有外部传入内容应走标准 slot 机制;布尔属性需绑定布尔值而非字符串;slot 接口须用 defineslots 显式声明;样式必须收敛至 css 变量或原子类。

组件模板必须用 slot 而非 v-html 渲染插槽内容
直接拼接 HTML 字符串会绕过框架的响应式追踪和安全校验,v-html 在组件模板里属于危险信号。Vue 或 Web Components 场景下,所有外部传入内容都应走标准 slot 机制——它天然支持作用域、响应更新和 SSR 友好。
- 使用
<slot name="header"></slot>替代<div v-html="props.header"></div> - 若需 fallback 内容,写成
<slot name="footer">默认页脚</slot>,不要用v-if判断后手动插入 DOM - 动态 slot 名要用
#[name]语法(Vue 3),避免用字符串拼接slot="{{ type + '-content' }}"—— 这种写法在编译期无法静态分析
HTML 属性必须严格区分 boolean 和 string 类型
像 disabled、required、hidden 这类布尔属性,只要存在即为 true,不能写成 disabled="false" 或 disabled="{{ isDisabled }}"。否则浏览器会把它当字符串值处理,导致逻辑翻车。
- 正确:
<button :disabled="isPending">提交</button>(绑定布尔值) - 错误:
<button disabled>提交</button>(字符串值永远触发禁用) - 自定义属性如
data-id、aria-label必须带引号且为字符串,data-id="123"合法,data-id=123在某些解析器里会丢空格或截断
结构约束靠 template 标签 + defineSlots 显式声明
不声明 slot 接口,就等于放弃类型安全和 IDE 自动补全。Vue 3 的 defineSlots 是唯一能提前约束插槽形状的方式,比运行时 $slots 检查更早拦截问题。
- 在
<script setup></script>中加一行:defineSlots any; icon?: (props: { size: string }) => any }>(); - 这样 TS 能校验使用者是否传了
icon插槽,以及是否传了size参数 - 不声明时,
<my-button><template><svg></svg></template></my-button>看似能跑,但漏传size不报错,运行时才出问题
禁止在模板中出现内联样式或硬编码 class
组件模板里写 style="margin-left: 8px" 或 class="text-sm text-gray-600" 会让样式逻辑散落各处,破坏设计系统的一致性管控能力。所有视觉表现必须收敛到 CSS 变量或原子类。
- 用
:class绑定预设类名,例如:class="['btn', sizeClasses[size], variantClasses[variant]]" - 颜色/间距/圆角等数值全部来自 CSS 自定义属性,如
style="--btn-padding: var(--spacing-xs);" - 如果真要条件样式,提取成计算属性:
const buttonStyle = computed(() => ({ '--btn-bg': props.variant === 'primary' ? '#007bff' : '#6c757d' }))
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











