前端之道:规范指南与工具推荐

一、技术选型

新项目: Vue3 + Vite + Pinia + Naive UI + TypeScript + TailWind / Windi + Node 16

移动端: Vue3 + Vite + Pinia + Vant UI + TypeScript + TailWind + Node 16

维护项目: Vue2 + Webpack + Vuex + Element UI + JS + TailWind + Node 14

Node 工具链: pnpm + nvm + nrm + ni
选择 pnpm 的原因:

  1. 快速安装和更新依赖项: pnpm 使用硬链接技术来安装依赖项,而不是像 npm 那样将它们复制到每个项目的 node_modules 目录中。这样做可以节省磁盘空间,并且安装和更新依赖项的速度更快
  2. 磁盘空间效率: 由于使用了硬链接,多个项目共享相同的依赖项不会重复占用磁盘空间,这对于拥有多个项目的开发者来说,可以显著减少磁盘空间的占用。
  3. 网络带宽效率: pnpm 使用符号链接和压缩存储数据,这样可以减少对网络带宽的使用,尤其在安装和更新依赖项时,可以加快速度,尤其是对于那些依赖项重复的项目。
  4. 兼容性: pnpm 完全兼容 npm 的 package.json 和 node_modules 结构,这意味着你可以在现有的 npm 项目中直接切换到 pnpm 而无需修改代码。
  5. 良好的生态系统支持: pnpm 在 npm 的基础上进行了改进,并且有一个活跃的社区维护,因此你可以获得与 npm 相似的包管理生态系统支持。
  6. 版本管理: pnpm 具有版本管理功能,允许你更轻松地恢复到先前安装的依赖项版本,这对于项目的稳定性和维护性非常有帮助。

二、命名规范

❗️语义化是第一前提❗️

1.文件夹名

文件夹名应该使用 kebab-case 命名规范,例如:my-component。这样可以确保文件夹名与组件文件名相匹配,并遵循统一的命名约定

2.文件名

文件名应该使用 kebab-case (短横线连接)命名规范,例如:my-component.ts。这样可以确保在不同操作系统和版本控制系统中都能良好地工作。

3.组件名

组件名应该使用 PascalCase (大驼峰式)命名规范,例如:MyComponent。这样可以确保组件名称在模板中使用时与 HTML 元素和其他组件名称区别开来。

vue 复制代码
// 组件导入
import ButtonGroup from './components/ButtonGroup'

// 组件使用
<ButtonGroup>xxx</ButtonGroup>  //错误

<button-group>xxx</button-group> //正确

4.路由名

路由名应该使用 kebab-case 命名规范,例如:my-page。这样可以确保路由名称在 URL 中使用时易于阅读和识别。

js 复制代码
{
	 path: 'course-list',
	 name: 'courseList',
   meta: { title: '课程列表', nav: 'courseList' },
   component: () => import('@/views/home/pages/course/list/List'),
}

5.常量名

常量名、字典项应该使用大写字母和下划线 (CONSTANT CASE) 命名规范,例如:MY_CONSTANT。这样可以确保常量名称在代码中易于识别,并且不会被意外更改

js 复制代码
/* 字典项:培训方式 */
export const SUBJECT_TRAINING_MODE = [
	{ value: 0, label: '线上' },
	{ value: 1, label: '线下' },
	{ value: 2, label: '线上线下混合' },
]

// vue3 中可用 camelCase(小驼峰式)定义 const
const showAnimation = ref(false)

6.变量名

变量名应该使用 camelCase命名规范,例如:myVariable。这样可以确保变量名称在代码中易于识别,并且符合 JavaScript 的命名约定。

7.方法名

方法名应该使用 camelCase 命名规范,例如:myMethod。这样可以确保方法名称在代码中易于识别,并且符合 JavaScript 的命名约定。

8.CSS 类名

CSS 类名应该使用 kebab-case 命名规范,例如:.my-class。这样可以确保类名在 HTML 和 CSS 中使用时易于识别,并且遵循统一的命名约定

9. Prop 命名

Prop 应该采用 camelCase(驼峰命名法),例如:firstName

vue 复制代码
<script>
export default {
  props: {
    // 使用 camelCase 命名法定义 prop
    userDetails: {
      type: Object,
      required: true
    }
  }
};
</script>

10.自定义事件命名

自定义事件名应该使用 kebab-case(短横线分隔命名法)。

vue 复制代码
// 子组件 
this.$emit('`custom-event`', data); 

// 父组件 
<my-component `@custom-event`="handleCustomEvent"></my-component>

11.文件夹结构

Vue3 项目中的文件夹结构应该根据功能组织,并尽可能保持扁平化。这样可以确保代码库易于维护,并且能够快速找到所需文件。

12.代码格式化

使用一致的代码格式化和缩进规则,例如使用 ESLintPrettier。这样可以确保代码易于阅读和维护,并且符合代码库的代码风格。

序号 所属区块 命名格式 举例
1 文件夹名 kebab-case my-components
2 文件名 kebab-case form-config.ts
3 组件名 PascalCase CustomDialog.vue
4 路由名 path:kebab-case name:camelCase path: 'course-list' name:'CourseList'
5 常量名 字典项:大写字母和下划线 vue3:camelCase 字典项:SUBJECT_TRAINING_MODE vue3:personList
6 变量名 camelCase saveStatus
7 Css类名 kebab-case .highlight-title (类名应基于元素功能而并非样式)
8 方法名 camelCase handleClickAddBtn
9 接口名 camelCase getUserList (动词开头)
10 Prop命名 camelCase personId
11 自定义事件命名 kebab-case tab-change

三、注释规范

注释如星辰璀璨,指引代码之旅,避免徒劳前行 🚀

1.方法注释

方法注释以 /** 开头,以 */ 结束,方法注释要使用注释标签说明方法的参数,返回结果等等内容。

js 复制代码
/**
  * 获取用户信息 
  * @param {Number} id 用户id 
  * @returns {Object} 返回用户对象 
  */ 

 function getUserInfo(id) {}

方法的注释标签参考JSDoc 文档文档,以下是常用的标签说明。

2.单行注释

单行注释以 // 开头,可以在代码末尾,也可以单独一行。

js 复制代码
function setId(id) {
	// 可以在代码上面注释
	this.id = id;
}

let name = "小明"; // 如果是声明变量的注释,推荐写在行尾
let birthday = "2000-10-02"; // 生日

3.多行注释

多行注释以 /* 开头,以 */ 结束。

  • /* 开头与后面内容空一格。 如果注释内容较多,需要换行注释。

  • 若以 /* xx */ 注释内容都在同一行,推荐使用 // 单行注释。

js 复制代码
/*
	注释内容1
	注释内容2
*/
setTitle();

四、代码提交规范

  • 提交信息应该简明扼要,清晰地描述本次提交的变更内容。
  • 使用动词的现在时态,如"修复"、"添加"、"更新"等。
  • 使用首字母大写(使用husky会自动把首字母变为小写),避免使用过多标点符号。
  • 不要堆积文件❗️当变更对应模块代码后,应立即提交,产生一条提交记录。

1.使用 husky

2.不使用 husky

// 注意:冒号后面有个空格

git commit -m "fix(login): 修改登录页传参问题"

五、接口请求规范

1.请求规范

(1)URL 命名和结构:
  • 使用有意义的命名,准确描述接口的用途和操作
  • 遵循 RESTful 设计原则,使用名词表示资源,避免使用动词作为路径。
  • 使用合适的路径结构,反映资源之间的关系,例如 /api/users/{userId}/orders
(2)HTTP 方法选择:
  • 使用适当的 HTTP 方法表示操作类型。常见的方法包括 GET、POST、PUT、DELETE 等。
  • 遵循 HTTP 方法的语义,GET 用于获取资源,POST 用于创建资源,PUT 用于更新资源,DELETE 用于删除资源
(3)请求参数:
  • 使用合适的参数传递方式,如路径参数、查询参数、请求体等。
  • 对于查询参数,使用键值对的形式,例如 /api/products?category=shoes&page=1
  • 对于请求体,使用适当的数据格式,如 JSON 或表单数据。
(4)请求头 Headers:
  • 在请求头中包含必要的信息,如授权凭证(Authorization)、内容类型(Content-Type)等。
  • 使用适当的 Accept 头部字段来指定响应的内容类型。
(5)错误处理:
  • 使用合适的 HTTP 状态码表示请求的结果,如 200 表示成功400 表示客户端错误500 表示服务器错误
  • 在返回的响应中,提供有用的错误信息,以便前端进行错误处理和展示。
(6)安全性考虑:
  • 使用 HTTPS 协议保护数据传输的安全性。
  • 对于涉及用户认证和敏感操作的接口,使用适当的身份验证机制,如 JWT(JSON Web Token)。
(7)统一错误处理和请求拦截:
  • 在前端代码中实现统一的错误处理逻辑,处理接口请求的异常情况。
  • 使用请求拦截器对请求进行预处理,例如添加认证信息、统一设置请求头等。

2.常见用法

(1)get 请求
js 复制代码
/* 获取单个课程详情 */
export function getCourseDetail(id) {
  return commonReq.get({
    url: `/course/details/${id}`,
  })
}
js 复制代码
/* 获取课程分类列表 */
export function getCourseTypeList(params) {
  return commonReq.get({
    url: '/course/classifications',
    params,
  })
}
js 复制代码
/* 检查上级分类下是否有课程 */
export function getSuperClassificationsStatus(id) {
  return commonReq.get({
    url: '/course/classifications/status',
    params: { id },
  })
}
(2)post 请求
js 复制代码
/* 添加课程 */
export function postCourse(data) {
  return commonReq.post({
    url: '/course',
    data,
  })
}
js 复制代码
/* 导出签到记录 */
export function exportSignInRecord(id) {
  return downloadReq.post({
    url: '/msg/record/export',
    responseType: 'blob',
    params: { eventId: id },
  })
}
js 复制代码
/* 提醒所有未填写人员 */
export function postRemindToAll(eventId, projectOrSubject) {
  return commonReq.post({
    url: '/msg/evaluation/questionnaire/push/all',
    data: {
      eventId,
      projectOrSubject,
    },
  })
}
(3)put 请求
js 复制代码
/* 启用管理员 */
export function openAdminAccount(id) {
  return commonReq.put({
    url: `/admin/user/lockout/${id}`,
  })
}
js 复制代码
/* 转移班级 */
export function putTransferClass(params) {
  return commonReq.put({
    url: '/training/class/transfer',
    params,
  })
}
js 复制代码
/* 修改密码 */
export function putPassword(data) {
  return commonReq.put({
    url: '/admin/user/edit',
    data,
  })
}
(4)delete 请求
js 复制代码
/* 删除课程 */
export function deleteCourse(ids) {
  return commonReq.delete({
    url: '/course',
    params: { ids },
  })
}
js 复制代码
/* 删除通知任务 */
export function deleteJobNotice(ids) {
  return commonReq.delete({
    url: '/msg/record/notify',
    params: {
      notificationsIds: ids,
    },
  })
}

六、vue相关规范

1.v-for 设置 key

在组件上总是必须用 key 配合 v-for,以便维护内部组件及其子树的状态。

vue 复制代码
<!-- 若没有唯一标识,则 key 绑定 index--> 
<template>
  <div v-for="(item, index) in list" :key="item.id">{{ item.name }}</div>
</template>

2.v-if 和 v-show 选择

v-if 和 v-show 都可以用于显示/隐藏效果,但是本质上还是有区别的。

  • v-if 是惰性的,只有条件成立时候才渲染DOM元素,适用于不经常切换的情况,因为频繁切换会增加DOM操作的开销。

  • v-show 是不管条件真假,直接就会被渲染上,但是它不会对DOM元素进行添加或移除操作,只是在DOM上设置CSS样式来显示或隐藏元素,比较适合频繁切换的场景。

3.避免 v-if 和 v-for 一起使用

vue 复制代码
<template>
  <!-- 可以列表提前通过计算属性过滤一遍 -->
  <div v-for="item in userListComputed" :key="item.id"></div>

  <!-- 也可以在最外层先包括一层,再判断 -->
  <template v-if="showUser">
    <div v-for="item in userList" :key="item.id"></div>
  </template>
</template>

4.使用简写

(1) 在模板中使用属性绑定时,应该使用 : 作为 v-bind 的简写形式。

vue 复制代码
<!-- 完整写法 -->
<img v-bind:src="imageUrl" alt="测试图片">

<!-- 简写形式 -->
<img :src="imageUrl" alt="测试图片">

(2) 在模板中使用事件监听时,应该使用 @ 作为 v-on 的简写形式。

vue 复制代码
<!-- 完整写法 -->
<button v-on:click="handleClick">Click me</button>

<!-- 简写形式 -->
<button @click="handleClick">Click me</button>

七、代码规范

1.三元表达式

js 复制代码
let flag = 1;
console.log(flag == 1 ? "是" : "否");

// 甚至再多一层判断也可以
let status = 0;
console.log(status == 0 ? "代办" : status == 1 ? "已办" : "无");

2.使用 ... 扩展运算符

js 复制代码
let age = 18;
let user = {
  id: 1,
  name: "小明",
};

// 浅拷贝对象
let copy = { ...user, age };
js 复制代码
let arr1 = [1, 2];
let arr2 = [3, 4];

// 浅拷贝数组
let arr3 = [...arr1, ...arr2];

3.使用可选链 ?. 操作符

在引用为空null 或者 undefined的情况下不会引起错误,该表达式短路返回值是 undefined

js 复制代码
let user = null;
// 如果直接取 user.sex 是会报错的,用了可选链后可以不用判断直接取了
console.log(user?.sex);

3.使用空值合并 ?? 操作符

如果左操作数的值不为 null,则返回该值;否则,它会计算右操作数并返回其结果

js 复制代码
const value = "hello";
console.log(value ?? "bye");

4.避免 console.log 滥用

避免大量使用console.log,这样很影响代码执行效率。

打印日志只作用看调试内容输出,不能代码里随意到处都写,在代码调试完成之后必须要删除注释

5.img标签alt属性不能为空

html 复制代码
<img> 标签的 `alt` 属性指定了替代文本,在图像无法显示时候替代的文案显示。

<img src="http://www.xxx.com/dd.jpg" alt="加载中" />

6.使用严格等运算符(===)

使用 === 运算符可以确保比较时不仅比较值,还要比较数据类型。这样可以避免类型转换带来的意外结果,并增加代码的可读性和稳定性。

7. 括号

对于 ifelseforwhiledoswitchtrycatchfinallywith 等关键字,即使代码块的内容只有一行,也应该使用大括号将其包裹起来。这样做有助于保持代码的一致性、可读性和可维护性,并且可以避免出现由于缺少大括号而引起的错误。

js 复制代码
// 不好的写法:没有使用大括号,尽管只有一行代码
if (condition)
    console.log('条件成立');
else
    console.log('条件不成立');

// 好的写法:使用大括号将代码块包裹起来
if (condition) {
    console.log('条件成立');
} else {
    console.log('条件不成立');
}

8.表格值为空

当接口返回数据为 null 或空字符时,在表格中用短横线 - 渲染,而不是空白。这样做有助于提高表格的可读性,让用户能够清晰地知道这些数据确实是没有值,而不是因为渲染问题导致的空白。

7.组件封装

当在代码中发现超过2处使用了相同的逻辑时,考虑将这部分逻辑提取到一个可复用的组件中。

八、测试规范

前端开发者需要了解的主要有以下几种测试类型:

  • 冒烟测试 : 在对软件进行详细测试之前,对关键功能或模块进行初步验证,以确认基本功能是否正常工作。
  • 单元测试 :单元测试是针对独立的软件模块进行的测试,目的是验证每个模块的功能是否正确,确保其独立运行时的正确性。

  • UI组件测试 : UI 组件测试是验证前端界面是否还原 UI 设计稿样式要求的过程。

  • 集成测试 : 集成测试是在单元测试基础上,将模块组合起来,测试它们的组合性和协作是否正常。

  • E2E测试 : E2E(End-to-End)测试是在完整、真实的运行环境下模拟真实用户对应用进行测试。

  • 兼容性测试 : 兼容性测试是确保应用在不同浏览器和设备上都能正常运行的过程。

  • 性能测试 : 性能测试是测试和分析应用是否存在性能问题,包括加载时间、响应时间、资源占用等。

  • 安全测试 : 安全测试是验证应用是否存在安全漏洞和脆弱性的过程。针对常见的安全问题(如XSS、CSRF、SQL注入等)进行测试,并修复潜在的安全风险。

  • SEO测试: SEO(Search Engine Optimization)测试是确保应用能够被搜索引擎正确索引和排名的过程。确保网页的标题、关键词、描述等内容符合 SEO 要求,并优化网页结构和内容。

九、工具推荐

序号 名称 作用 网址
1 tinify 图片压缩 tinify.cn/
2 squoosh 图片压缩 squoosh.app/
3 caniuse 兼容性查询 caniuse.com/
4 regulex 正则表达式可视化验证 jex.im/regulex/
5 ioDraw 在线画图 www.iodraw.com/
6 convertio 文件类型转换(图像、文件、音频、视频等) convertio.co/zh/
7 isqqw Echarts 示例 www.isqqw.com/
8 transform 各种类型转换(json to TS 等) transform.tools/
9 xicons 图标库 www.xicons.org/#/
10 iconfont 阿里图标库 www.iconfont.cn/
11 gps 经纬度查询 www.toolnb.com/tools/gps.h...
12 菜鸟工具 工具集合导航 c.runoob.com/
13 fontmin 字体原子化工具,提取相应文字字体,实现字体压缩 ecomfe.github.io/fontmin/
14 Jsont Json 格式化工具 www.jsont.run/
15 codepen 单文件在线编辑器 codepen.io/
16 codesandbox 项目级在线编辑器 codesandbox.io/
17 草料二维码 二维码生成器 cli.im/

欢迎补充~

十、插件推荐

配置文件优先级:独立配置文件 > VS Code 工作区配置 > VS Code 用户配置

(1)独立配置文件(项目级): 在项目的根目录下有一个 .prettierrc 文件,用于配置代码格式化规则。

js 复制代码
// .prettierrc (项目级配置)
{
  "tabWidth": 2,
  "singleQuote": true,
  "trailingComma": "all"
}

(2)VS Code 工作区配置:.vscode/settings.json 文件中配置工作区级别的 Prettier 规则。

js 复制代码
// .vscode/settings.json (工作区配置)
{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.formatOnSave": true
  }
}

(3)VS Code 用户配置: 打开 VS Code,点击菜单栏中的 "文件" -> "首选项" -> "设置",然后在右侧的设置面板中进行设置。

js 复制代码
// 用户配置(全局设置)
{
  "editor.tabSize": 4,
  "editor.formatOnSave": false
}

如上所示,根据配置文件的优先级,代码格式化规则将遵循项目级配置(.prettierrc)中的设置。如果项目级配置没有定义特定的规则,那么工作区配置将生效,如果工作区配置也没有定义规则,则最后使用全局用户配置。

1. Volar

描述:Vue3 语法支持(在Vue2 项目中需要禁用 Vetur

2. Vetur

描述:Vue2 语法支持(在Vue3 项目中需要禁用 Volar

3. Where Am I

描述:左下角显示你目前在哪个项目中

4. Project Manager

描述:在多个项目之间轻松切换

配置:使用该插件需要在 setting.json 中 配置包含 Git项目 根文件夹的绝对路径

json 复制代码
 "projectManager.git.baseFolders": [
    // windows
    "C:\\Work",
    "C:\\Study",
    // Mac
    "~/work",
    "~/study"
  ],

5. CodeSnap

描述:生成一张漂亮的代码截图

使用:选中一段代码,右键选择:CodesSnap 即可生成代码截图,选中截图右键即可复制

6. Prettier

描述:代码格式化插件,侧重点:代码格式

prettier 推崇的是无配置,如需自定义配置在根目录新增配置文件:.prettierrc 文件,举例如下

js 复制代码
{
  "printWidth": 80,   // 每行代码最大字符数
  "semi": false,      // 是否在代码末尾添加分号
  "singleQuote": true, // 否使用单引号来包裹字符串
  "trailingComma": "es5", // 是否在对象和数组字面量的最后一个元素后添加逗号(在 ES5 中添加逗号)
  "endOfLine": "lf", // 指定换行符的类型
  "bracketSpacing": true, // 是否在对象字面量中的括号前后添加空格
  "tabWidth": 2 // 指定一个制表符的宽度
}

Prettier 默认会格式化项目中的所有支持的文件类型,可通过在根目录新增配置文件:.prettierignore 文件,忽略不想格式化的文件(类似 .gitignore ),举例如下:

js 复制代码
// 在 .prettierignore 忽略以下文件
node_modules
public
dist
.vscode
.husky

7. ESLint

描述:代码规范检查,侧重点:代码质量

假设你已经配置好了 Eslint 语法规范,其中一段配置为:

js 复制代码
// 禁止console.log,可以自定义一个Console类,判断当前是否在开发环境,再输出
'no-console': ['error', { allow: ['warn', 'error'] }],

此时我在代码中在输入 console.log,那代码是会报错的,配合 Error Lens 插件即可让报错信息高亮显示,如下所示:

8. Error Lens

描述:提供对错误、警告和其它语法诊断的高亮显示

9. EditorConfig

描述:用.editorconfig文件中的设置覆盖用户/工作区设置,配置文件优先级请查阅上文

使用:使用此插件可使同一项目的多个开发人员保持一致的编码风格,在根目录下新建.editorconfig文件,配置举例:

js 复制代码
root = true

[*] # 表示所有文件适用
charset = utf-8 # 设置文件字符集为 utf-8
indent_style = space # 缩进风格(tab | space)
indent_size = 2 # 缩进大小
end_of_line = lf # 控制换行类型(lf | cr | crlf)
trim_trailing_whitespace = true # 去除行首的任意空白字符
insert_final_newline = true # 始终在文件末尾插入一个新行

10. Code Spell Checker

描述:捕获常见的拼写错误

假如我想创建一个名为 black 的响应式变量,但输入成了 blaok,此时就会给出我相应的提示

11. Tailwind CSS IntelliSense

描述:为用户提供自动完成、语法高亮和检查等高级功能,增强了 Tailwind 开发体验。

12. Better Comments

描述:通过使用警告、信息、TODO 等注释来改进代码注释

13. Color Highlight

描述:在编辑器中突出显示网页颜色

14. Image Preview

描述:在边栏和鼠标悬浮时显示图像预览

15. SVG

描述:SVG编码,缩放,美化,预览集合

16. Turbo Console Log

描述:自动插入消息日志

使用:选中要打印的变量,使用快捷键:command + shift + L 即可自动插入(Windows:ctrl + shift + L)
前端领域是一个不断发展和变化的领域,总有新的技术、工具和最佳实践出现,但规范是死的,人是活的,相信每个开发团队都有自己的一套开发规范,如果此文能为您带来一丢丢帮助,那便已足矣,欢迎批评指正😁

相关推荐
乘风gg1 分钟前
还在养虾吗?虾王已诞生:微信龙虾 ClawBot
前端·ai编程·claude
小小小小宇17 分钟前
LLM 长期记忆构建
前端
lichenyang45329 分钟前
从 Express 老项目到 NestJS + Docker:一次车辆管理系统的渐进式重构
前端
Momo__2 小时前
VueUse createReusableTemplate —— 单文件组件内的模板复用神器
前端·vue.js
程序员小富2 小时前
我开源了一个开发者专属的智能 JSON 工具,得到了媳妇高度认可
前端·vue.js·后端
小小小小宇2 小时前
程序员如何给 LLM 装工具以及看懂推理过程
前端
写代码的皮筏艇2 小时前
React中的forwardRef
前端·react.js·面试
Flynt2 小时前
装上TypeScript 7.0 RC之后,最让我意外不是10倍提速
typescript·visual studio code
槑有老呆2 小时前
花三个月工资请了个 AI 程序员,结果它连青岛啤酒股价都查不了
前端
风骏时光牛马2 小时前
Verilog开发常见问题汇总解析
前端