项目规范

常用命名法有以下几种:

  • camelCase(小驼峰式命名法 — 首字母小写)
  • PascalCase(大驼峰式命名法 — 首字母大写)
  • kebab-case(短横线连接式命名法)
  • Snake(下划线连接式命名法)

项目名命名

全部采用[短横线命名法],字母均为小写,单词分词以短横线分隔。
具体项目名可根据部门或团队,项目或项目名等综合命名。团队名非必须。
如:[部门/团队]-[项目/产品名]-[admin/h5/mobile] 说明:

  • 项目/产品名采用短横线命名法。例如:my-project-name
  • admin 可用来表示管理端
  • h5 用来表示移动端 H5
    也可使用 mobile 表示 M 栈,app 表示原生 APP 中内嵌的 H5。

目录名命名

同样采用[短横线命名法]

  • 目录存在复数则采用复数命名。例:docs、assets、components、directives、mixins、utils、views。
  • 多词目录,采用 短横线“-” 分割词语。例:system-config

目录结构示例如下:

my-project-name/
|- .vscode        //
    |- extensions.json  //推荐VS CODE扩展安装配置
    |- launch.json      //vs code启动文件配置,可调试node_modules中文件和nodejs项目
    |- settings.json //配置项目级别的格式化等信息
|- build          // 流水线部署脚本目录
|- config         // 可配置如dev、test、prod三个环境所需的配置文件。(可选)
|- docs           // 项目文档目录(可选),可存储设计文档,需求文档,TODO.md等
|- nginx          // 部署在容器上前端项目nginx代理文件目录
|- node_modules   // 下载的依赖包
|- public         // 静态页面目录
    |- index.html // 项目入口
|- src            // 源码目录
    |- api        // http 请求目录
    |- assets     // 静态资源目录,这里的资源会被wabpack构建
        |- icons   // icon 存放目录
        |- imgs    // 图片存放目录
        |- js     // 公共 js 文件目录
        |- css   // 样式存放目录,可同事支持sass、stylus文件
            |- global.scss      // 全局公共样式,提供统一的水平,垂直居中等公共样式类库
            |- element-ui.styl  // 重写elementUI样式
            |- vant.styl        // 重写vant样式
            |- project.styl     // 定义项目级别的统一样式,如Button按钮颜色和居中,
    |- components     // 组件库(大驼峰或短横线命名方式二选其一)
      |- HeaderSearch   //头部搜索组件
        |- index.vue
      |- DynForm     //动态表单组件
        |- index.vue
    |- define         // 常量,变量的定义
        |- constant.js    //常量
        |- enums.js       //定义的枚举
        |- event.js       //定义的事件
    |- libs           // 依赖库
        |- http       // http请求库
            |- axios.js    // axios文件
            |- fetch.js   //fetch请求库
        |- utils      // 工具存放目录
            |- converter.js    // 转换器
            |- checker.js      // 类型检查器
            |- storage.js      // 存储器
    |- plugins        // 插件
    |- router         // 路由
        |- modules    // 各模块的路由定义,方便各成员编辑路由防止冲突
            |- home.js    // 首页路由
            |- xxx.js     // 其他模块路由
            |- index.js   //动态加载聚合各模块路由
        |- constant-routes.js    //固定路由,如404,nopermission等
        |- index.js   // 加载modules和constant-routes路由,聚合导出全部路由
    |- store          // 全局状态管理
    |- views          // 单页面存放目录
       |- system-config
          |- Index.vue
    |- pages          // 多页面应用存放目录
    |- App.vue        // 根组件
    |- main.js        // 入口文件
    |- tests          // 测试用例
    |- .browserslistrc// 浏览器兼容配置文件
    |- .editorconfig  // 编辑器配置文件
    |- .eslintignore  // eslint 忽略规则
    |- .eslintrc.js   // eslint 规则
    |- .gitignore     // git 忽略规则
    |- babel.config.js // babel 规则
    |- Dockerfile // Docker 部署文件
    |- jest.config.js
    |- package.json // 依赖
    |- README.md // 项目README,编写项目介绍,安装,依赖等描述文件
    |- vue.config.js // webpack 编译打包配置文件
    |- yarn.lock       // YARN生成的版本锁定文件

补充说明:

  • docs 目录:不建议存储太多文档,会影响 git 的 clone、占用过多存储空间
  • tests 目录:测试用例目录结构按照 views 中的模块页面。 建议测试用例文件也都创建在 tests 目录,而不是在开发页面统计目录创建测试用例文件。
  • 页面存储目录:单页面应用存储在 views 中,多页面应用存储到 pages 中

文件命名

文件名命名单词都应为名词,非动词。
如:推荐:logger.service.js,不推荐:log.service.js

单词较长可采用简写,如 message 可简写 msg 等,变量命令可通过CODELFopen in new window检索确定,VS Code 也可以搜 Codelf 插件。

  • 文件夹采用 [短横线],全部字母小写
    views 下交易页面文件夹 ,例:user-settings (重点)
    因为 npm 包的命名规范是短横线,所以也建议约定目录命名规范也是短横线,便于统一共识。

  • JavaScript 文件采用 [短横线],全字母小写
    例:event-bus.js
    具有不同角色功能模块可通过**.[模块名称].[js/ts] 符号分割区分。
    例:message.service.jsmessage.controller.tsmessage.provider.ts

  • css 文件采用 [短横线],全字母小写
    例:element-ui.jsdate-picker.js

  • html 文件采用 [下划线] 连接,全字母小写
    例:error_message.html

  • 图片等资源文件采用 [下划线] 连接,全字母小写
    例:banner-head.jpgcard-bg.png
    切记:不要使用中文,不要使用中文,不要使用中文。
    容易导致部署后图片显示不出来,发现很多项目中居然一直有使用中文命名。

  • Vue 文件采用 [大驼峰]
    例:Layout.vueMyComponent.vue

代码规范

代码规范主要目标:

  • 代码整洁,提高可阅读和可维护性。
    建议参阅《代码整洁之道》,了解如何编写整洁代码。
  • 提高应用的健壮性
    避免踩坑,避免隐藏 bug

代码编写过程中如有未完成,可通过//TODO:[待做事项]标记
VS Code 可安装【Todo Tree】插件,查看所有待做事项。 标记 TODO 的优点主要体现在,在编程过程中,可先编写主流程代码(类似伪代码),通过处理分线事项标记 TODO 事项即可。这样逻辑主线清晰,分线任务后续再详细实现细节。这样开发效率高、功能稳定可靠。

变量函数命名

  • 常量命名:单词全部大写,分词使用下划线
    例如:MAX_COUNT=100
  • 变量命名:
    私有变量,建议采用以下划线 _ 为前缀,例:let _dataType=0 ES12 新特性的私有变量采用#,如下
    class Student {
      get #Age() {
        return 18;
      }
      get publicAge() {
        return this.#Age;
      }
    }
    
    建议未使用 ES12 新特性时,使用**_**作为私有变量标记。
  • 公共变量:建议采用 [小驼峰],例:dataType=0
  • 函数命名采用 [小驼峰],动词 + 名词形式 例:goPage(){}getOrderList()commitFormData()
    常用动词:can、has、is、get、set、commit、post、open、show
  • 事件命名
    采用 [小驼峰],以on为前缀,即:[on]+[名称(可选)]+[动词] 例:onButtonClick(){}

路由命名

  • 路由 path 命名采用 [短横线],全字母小写 例:/route-path,因为浏览器只能识别短横线 -
  • 命名符合 RESTful API
    可参考阮一峰大神的文章 RESTful API 最佳实践open in new window,概括如下: 1. 动词 + 宾语 命令是动词(如 GET),path 是宾语如:/articles 2. 动词的覆盖 服务器必须接受 POST 模拟其他三个方法(PUT、PATCH、DELETE) 3. 宾语必须是名词 例如:/articles,/getAllCars是错误的 4. 复数 URL
    比如GET /articles/2要好于GET /article/2
    5. 避免多级 URL
    推荐:GET /authors/12?categories=2
    不推荐:GET /authors/12/categories/2

编码规范

先对比两种写法:
写法一

async function submit() {
  if (!elForm) return;
  loading.value=true;
  await elForm.validate((valid, fields) =>{
      if (valid) {
       serviceApi.submit().then((res)=>{
         if(res.code===200){ //业务代码code=200,表示业务处理成功
           //处理数据,如:tableComponent.data=res.data
           loading.value=false;
         }else if (res.code===210){
          //业务有特定分支,需要执行不同逻辑,则执行不同代码。
         } else  {
          loading.value=false;
          //业务类型错误
          //通常情况无特定业务执行逻辑,则可以都返回错误信息即可
          ElMessage.error(res?.message)
         }
       })
      }.catch(err=>{
        //主要是通信类型的错误,如404,405等
        loading.value=true;
        ElMessage.error(res?.message)
      })
    }
  }); 

写法二(推荐)

async function submit() {
  //el-form组件执行表单支持promise,直接执行validate校验即可。
  //不需要放到try catch中捕获表单校验异常,因为此异常已表现在表单界面上
  await elForm?.validate();
  loading.value = true;
  try {
    const res = await serviceApi.submit();
    //处理数据,如:tableComponent.data=res?.data?.list || []
    //执行其他js操作
  } catch (err) {
    if (err?.code === 210) {
      //业务有特定分支,需要执行不同逻辑代码。通常不回执行
    } else {
      //建议错误信息字段为message
      //因为trycatch可以报错“执行其他js操作”时的js错误,js Error的错误信息字段是message
      //使用message可以在同时捕捉js错误和业务异常时提示错误信息,
      ElMessage.error(err?.message);
    }
  } finally {
    loading.value = false;
  }
}

对比写法一和写法二,可以看出差异。好的代码编写方式和约定可以使程序较少异常,更加稳定。

项目的约定如下
1. 参照“写法二”。逻辑代码要采用try catch方式判断异常并提示消息。
原因如下:

  • 省去了大部分请求写判断 res.code!=200的代码
  • try catch中有非请求的其他逻辑代码时 也可以捕获到异常信息并弹出错误。
  • 因为JS的Error对象的错误信息属性是message,后台返回的是msg ,所以统一返回了message,这样try catch捕获js错误和后台错误都可以统一弹出message作为错误消息

2. 使用对象属性时,尽量不使用解构对象。
因为 const obj={name:'名称'}; 使用获取name属性 { name }=obj;

const obj={name:'名称'};
const  { name }=obj;  //使用解构时,当obj=null/undefined时,则js就会报错。
//不如直接 obj?.name 获取属性值更直观方便

3. 对象属性类型要写可选链,即问号

  • 如 获取用户名称 = data?.userinfo?.name || '用户名' 可选链?为了避免对象属性中有任何一个字段为null都不会报错,并且若值为空,则给默认值。
  • 并且vue的中绑定字段也要判断每个属性空值,否则会白屏,并且无任何报错。如下:(若userinfo为空,则白屏不会报错)
<template>
  <div>{{data.userinfo.name}}</div> 
</template>

正确做法 vue3+volar插件,可以支持dom绑定可选链

<template>
  <div>{{data?.userinfo?.name}}</div> 
</template>

4. API的参数要定义类型。
API接口定义类型是为了跟后台服务API接口规范保持一致,比如必填非必填,字段类型。 和后台服务接口保持一致,则开发和编译阶段就能快速报错类型或必填错误,避免遗漏或者API参数错误导致接口异常。

updateUser(data: { username: string; nickName?: string,phone?:string }) {
    return Http({ method: 'POST', data, url: BaseURL + '/user/update' })
},

5. Typescript编写,则可定义类型(如 interface,function 等)

  • 若需要多出使用或公共数据模型,则定义到/types目录下,并配置tsconfig.json中的include包"types/**/*.d.ts"。
  • 定义Typescript类型,可以多使用Typescript继承的Partial、Required、Record、Pick、Omit等类型
  • 引入的第三方模块,若提示找不到模块,如可以在types/index.d.ts进行声明
    declare module '3th-module'
    

注释

函数命名可一看知其意,则不建议添加注释。
添加注释主要标注以下几方面:

  • 说明业务注意点
  • 业务逻辑实现是如何考虑
  • 附上引用第三方 API 的链接地址,方便维护者再次查看

项目 UI/UE

产品和设计的风格要保持统一,约定好同类型页面如何布局等。 也建议开发团队给团队人员指定好基准页面,让项目成员参照开发。

  • 请求数据地方都要加 loading
    • 页面数据加载建议使用骨架屏
    • 提交按钮上加 loading 效果
  • 表格要添加斑马线
  • 提示或异常消息,统一提示文案的结尾没有叹号等标点

项目约定

  1. 有主题皮肤颜色设置的。 适配主题主题空间都无需设置背景颜色,字体颜色等。 针对主题颜色功能,编辑UI时尽量使用组件库,若组件库主题色没生效反馈负责人,若必须自定义的则使用变量$theme-color即可
  • 按钮都建议使用el-button,否则需要使用$theme-color变量同步主题颜色
  • el-button 需要显示主题的则使用 type="primary"类型按钮,无需再设置颜色。
  • div 实现的按钮,则 class 添加 $theme-color
  1. 引入资源Icon时,尽量使用svg格式的, 图片如果UI可以导出svg,也优先使用svg,只有图片的图片上传到cdn。
  • vite可以使用vite-plugin-svg-icons插件
  • vue-cli脚手架可以使用svg-sprite-loader插件
  1. 图片需要使用el-image,设置预览属性preview-src-list和initial-index 默认打开的图片索引

参考或引用