11.1 代码风格与项目架构规范


文档摘要

11.1 代码风格与项目架构规范 本节摘要:规范的目标是让团队的代码像一个人写的。本节给出命名的统一语言、组件设计的四条原则(含容器与展示分离)、逻辑分层的检验法,以及按测试金字塔安排的测试投入——顺带把测试这件第 9 章欠账的事补齐。 你应当能获得的能力 阅读完本节,你应当能够: 落地一套自动化执行的代码风格约定; 用容器与展示分离的思路设计职责清晰的组件; 判断一个函数该放哪一层的三个问题; 按金字塔分配测试:组合函数多测、组件少测、端到端 sparingly。 一、风格:能自动化的都不该是人管的事 缩进引号分号这类事交给格式化工具保存时自动执行,评审时一句都不该出现。真正需要人守的约定是命名统一语言: 组件文件名大驼峰(UserCard.

11.1 代码风格与项目架构规范

本节摘要:规范的目标是让团队的代码像一个人写的。本节给出命名的统一语言、组件设计的四条原则(含容器与展示分离)、逻辑分层的检验法,以及按测试金字塔安排的测试投入——顺带把测试这件第 9 章欠账的事补齐。

你应当能获得的能力

阅读完本节,你应当能够:

  1. 落地一套自动化执行的代码风格约定;
  2. 用容器与展示分离的思路设计职责清晰的组件;
  3. 判断一个函数该放哪一层的三个问题;
  4. 按金字塔分配测试:组合函数多测、组件少测、端到端 sparingly。

一、风格:能自动化的都不该是人管的事

缩进引号分号这类事交给格式化工具保存时自动执行,评审时一句都不该出现。真正需要人守的约定是命名统一语言

  • 组件文件名大驼峰(UserCard.vue),组合函数 use 前缀小驼峰(useCart.js);
  • 组件名用"业务名词加修饰"(OrderTable 而不是 Table2、BigTable),props 用事件语义而非实现细节(is-loading 而不是 loading-flag);
  • 布尔 props 加 is/has 前缀,事件名用动词(submit、item-click);
  • 仓库的 action 用动词(fetchOrders),state 字段用名词(orderList)。

统一语言的红利在检索:想找"下单相关的代码",命名一致的项目里全局搜 order 就够,命名随意的项目要靠考古。

二、组件设计四原则

其一,容器与展示分离。 容器组件管数据(请求、仓库、路由参数),展示组件管呈现(纯 props 进、事件出)。看一对拆分:

<!-- 容器:接数据与路由 --> <script setup> import { ref, onMounted } from 'vue'; import OrderTable from './OrderTable.vue'; import { getOrders } from '../api/orders'; const orders = ref([]); const loading = ref(true); onMounted(async () => { orders.value = await getOrders(); loading.value = false; }); </script> <template> <order-table :orders="orders" :loading="loading" @retry="load" /> </template>
<!-- 展示:零数据依赖 可进组件故事书 可独立测试 --> <script setup> defineProps(['orders', 'loading']); defineEmits(['retry']); </script>

收益具体:展示组件可以被设计同学在隔离环境里调样式;容器换了数据源(接口改仓库),展示组件一行不动。不必教条到每个组件都拆一对——只拆"同一种数据要多形态呈现"或"呈现要脱离数据联调"的场景。

其二,props 纪律。 数量警报:props 超过七八个通常意味着组件职责过宽或该用对象收拢;不要传"整页上下文"式的巨型对象,传用到的字段(配合 TS 类型,接口清晰即文档);props 单向,改走事件(第 5 章红线在规范里重申)。

其三,逻辑下沉。 组件里出现三段以上"只为算出一个值"的代码,抽计算属性;出现"跨组件想要的逻辑",抽组合函数(第 10 章范式)。组件 script 区的理想密度是"装配",重活都在可测的普通函数里。

其四,出口单一。 对外暴露面(props、emits、ref 方法)按需最小化。公共组件的 API 一旦被外部依赖就很难改,宁可先窄后宽。

三、分层检验:三个问题

一个函数该放组件、组合函数、utils 还是 api 层?依次问:

  1. 用到响应式状态或生命周期吗? 用到,考虑组合函数;纯输入输出,往下走。
  2. 与业务概念绑定吗? 绑定(订单金额折扣规则),放业务模块;不绑定(日期格式化、防抖),放 utils。
  3. 发请求吗? 发,一律进 api 层,组件永远不直接操作请求库——换库、加拦截器、mock 联调都只动一层。

第 10 章的目录结构配这三问,新人入职半天就能放对代码位置。

四、测试金字塔(补上测试这门课)

前端测试的合理金字塔:

底层:组合函数与工具函数(占大头)。 组合函数是普通函数,测试不需要挂组件:

import { describe, it, expect, vi } from 'vitest'; import { useSearch } from '../composables/useSearch'; describe('useSearch', () => { it('空关键词清空结果', async () => { const fetchFn = vi.fn().mockResolvedValue([{ id: 1 }]); const { keyword, results, on_input } = useSearch(fetchFn, 0); keyword.value = 'a'; on_input('a'); await vi.waitFor(() => expect(results.value).toHaveLength(1)); on_input(''); expect(results.value).toHaveLength(0); }); });

Vitest 加模拟函数,毫秒级跑完,逻辑复用度越高这里回报越大。

中层:组件测试(适量)。 组件测试工具挂载组件、断言渲染与交互。只测"合同"(props 进出的行为),不测内部实现细节——测内部状态的测试在重构时全部报废。

顶层:端到端测试(少量)。 真浏览器跑关键路径(登录下单支付),慢而脆,只保最不能坏的流程。

投入比例建议 7 比 2 比 1。反模式点名:只写端到端(慢、定位难)与给每个组件写快照测试(快照一变全员盲批通过)。

五、协作流程的最后一公里

规范要活到流程里:格式化与类型检查挂提交钩子,不达标进不了仓库;组件文档(props 表格加用例)随组件走;接口变更先改类型定义,让类型错误标出所有受影响处。团队规范的评审清单因此变短——机器管的与人对管的各归其位,评审只剩设计取舍值得争。

本节要点回顾

  • 命名统一语言:机器管不了的命名一致,是可检索性的地基;
  • 容器展示分离:数据与呈现解耦,按需拆不教条;
  • 三问分层:响应式吗、绑定业务吗、发请求吗,答案决定归属;
  • 测试金字塔:组合函数七成、组件两成、端到端一成,测合同不测实现;
  • 流程托底:钩子挡不合格提交,类型变更先于代码变更。

代码写整齐了,最后一节面对的是外部世界——安全。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U