# Vue 核心代码规范 ## 目录 - 技术风格与版本适配 - 命名与文件 - SFC 结构 - Props、Emits、Slots 与组件 API - 响应式状态 - 模板 - TypeScript - 异步与副作用 - 样式 - 注释与日志 - 官方依据 ## 技术风格与版本适配 - 新建现代 Vue 3 SFC 时,优先使用 Composition API 与 ` ``` - 服从项目的 block 顺序和 import 排序规则。 - 仅在模板或组件逻辑实际需要时创建变量;不要为了分区制造空注释。 - 组件私有样式优先 `scoped` 或项目 CSS Modules 方案;主题、reset、tokens 和工具类保持全局。 - 避免使用 `:deep()` 穿透第三方或子组件内部;无法通过公开 API 定制时,记录耦合原因。 ## Props、Emits、Slots 与组件 API - 用类型声明组件契约,为可选 props 明确默认行为。 - props 名表示数据或状态;emits 名表示已发生的业务动作,例如 `submit`、`update:modelValue`。 - 不以 emit 冒充命令式调用;父组件需要控制子组件时,优先 props 和状态驱动。 - 仅在确有命令式能力时使用 `defineExpose`,并保持暴露面最小。 - 为有双向语义的表单值使用 `v-model`/`defineModel`;普通业务数据继续使用 props + emits。 - 不直接解构会丢失响应性的对象。解构 Pinia 状态时使用 `storeToRefs`;解构一般响应式对象时按需使用 `toRefs`。 - 为 slots 定义清晰语义;不要让父组件依赖子组件内部 DOM 结构。 - 可变对象或数组默认值必须保证实例隔离,并符合当前 Vue 版本支持的写法。 ## 响应式状态 - 对基本类型和可整体替换的值使用 `ref`。 - 对语义内聚且主要按属性更新的对象使用 `reactive`;不要创建巨大、无边界的响应式对象。 - 使用 `computed` 表达派生值,不将可推导数据复制进 state。 - 不在 `computed` 中发送请求、写 store、修改其他 state 或触发日志等副作用。 - 监听明确来源,避免无边界 deep watch;大型对象优先监听必要字段或规范化后的签名。 - 在 watcher 中处理异步时,取消或忽略过期结果,防止旧请求覆盖新状态。 - 对第三方实例、大型不可变结构或不需要深层代理的数据,评估 `shallowRef`/`markRaw`,但先用性能证据证明需要。 - composable 返回值需保持稳定且易解构;需要保护写入口时向外暴露 readonly state 与显式 mutation 函数。 ## 模板 - 保持模板表达式简短且无副作用。 - 为 `v-for` 提供稳定业务键;只有完全静态、永不重排的展示列表才可评估使用索引。 - 不在同一元素上组合 `v-if` 与 `v-for`;先计算筛选结果或使用外层 `