我的前端规范
base from Alibaba: https://developer.aliyun.com/article/850913
我未遵守的规范
(一)命名规范
- 项目命名:全部用小写方式,以"-"分割.
- 目录命名:全部采用小写方式,以"-"分割,有复数解构时,采用复数命名.
- **js css scss html png命名:**全部采用小写方式,以"-"分割.
- 杜绝不规范的缩写,避免望文不生义.
(二)HTML规范
-
尽量使用语义化标签.防止全文使用div p之类的.
语义化标签: <title>:页面主体内容。 <hn>:h1~h6,分级标题,<h1> 与 <title> 协调有利于搜索引擎优化。 <header>:页眉通常包括网站标志、主导航、全站链接以及搜索框。 <nav>:标记导航,仅对文档中重要的链接群使用。 <main>:页面主要内容,一个页面只能使用一次。如果是web应用,则包围其主要功能。 <section>:用于将文档分成不同的节或章节,每个<section>通常包括一个标题 <article>标签定义外部的内容,表示一个独立的、完整的文章或内容块,如新闻文章、博客帖子等 //比如来自一个外部的新闻提供者的一篇新的文章,或者来自 blog 的文本,或者是来自论坛的文本。亦或是来自其他外部源内容。 <aside>通常用于定义与页面内容相关但不属于主要内容的部分,如侧边栏或广告,标签定义 article 以外的内容 <em>:标签语义为强调 斜体 <strong>:标签语义为更强烈的强调 粗体. <ins>:标签的语义为定义已经被插入文档中的文本。 <del>标签的语义为定义文档中已被删除的文本。<ins>与 <del> 一同使用,来描述文档中的更新和修正。 <q>:标签的语义为用来标记简短的单行引用. <blockquote>:标签的语义为用来标记那些一段或者好几段的长篇引用。 <cite>:标签既可以与<q> 一起用,也可以与<blockquote>一起用,用来提供引用内容的来源地址。 <details> 标签定义元素的细节,用户可进行查看,或通过点击进行隐藏 <footer> 定义网页或页面部分的页脚,通常包括版权信息、联系方式等 <figure> 用于包含与主要文本相关的图像、表格、图表等,并通常与<figcaption>标签一起使用,以提供相关的标题 -
使用双引号而不是单引号.
(三)CSS规范
-
类名 class 用小写字母,以"-"进行分割,子元素class命名方式为父元素的class + "-" + 子元素的class特征.
-
Id 采用驼峰命名法.
-
scss中的变量 函数 混合 placeholder用驼峰命名.
-
css中选择器避免使用标签名.(div.p.span).
-
css中选择器选择直接子选择器.(.content > .children). 原因:非常消耗性能,且后面再改很麻烦.
-
尽量使用缩写属性.(font:100%/1.6 palatino);
css常用缩写属性 padding margin border-radius(顺时针旋转45°):[1个值是所有边,2个值是上下 左右, 3个值是上 左右 下,4个值是上右下左 ] border:略 background: -color, -image, -position, -size, -repeat, -origin, -attachment, -clip font: -style, -variant, -weight, -size, -height, font-family. list-style: -type. -image, -position. transition: -property, -duration, -timeFunc(easy-in-out), -delay. transform: transform 可以写多个到一个transform里面. -
css width 和 height 占一行.
(四)JS规范
-
常用函数的命名:
增更删查改: add / update / delete / detail / get 附: 函数方法常用的动词: get 获取/set 设置, add 增加/remove 删除, create 创建/destory 销毁, start 启动/stop 停止, open 打开/close 关闭, read 读取/write 写入, load 载入/save 保存, begin 开始/end 结束, backup 备份/restore 恢复, import 导入/export 导出, split 分割/merge 合并, inject 注入/extract 提取, attach 附着/detach 脱离, bind 绑定/separate 分离, view 查看/browse 浏览, edit 编辑/modify 修改, select 选取/mark 标记, copy 复制/paste 粘贴, undo 撤销/redo 重做, insert 插入/delete 移除, add 加入/append 添加, clean 清理/clear 清除, index 索引/sort 排序, find 查找/search 搜索, increase 增加/decrease 减少, play 播放/pause 暂停, launch 启动/run 运行, compile 编译/execute 执行, debug 调试/trace 跟踪, observe 观察/listen 监听, build 构建/publish 发布, input 输入/output 输出, encode 编码/decode 解码, encrypt 加密/decrypt 解密, compress 压缩/decompress 解压缩, pack 打包/unpack 解包, parse 解析/emit 生成, connect 连接/disconnect 断开, send 发送/receive 接收, download 下载/upload 上传, refresh 刷新/synchronize 同步, update 更新/revert 复原, lock 锁定/unlock 解锁, check out 签出/check in 签入, submit 提交/commit 交付, push 推/pull 拉, expand 展开/collapse 折叠, enter 进入/exit 退出, abort 放弃/quit 离开, obsolete 废弃/depreciate 废旧, collect 收集/aggregate 聚集 -
常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长
-
JS中的字符串:统一使用单引号(‘),不使用双引号(“)。这在创建 HTML 字符串非常有好处.
-
if else while for 后面必须跟大括号,即使只有一句语句.
-
undefined判断:永远不要直接对undefined进行判断,而是用typeof uu === 'undefined'
-
条件判断和循环最多写三层,能用三目运算符就用三目运算符,但是三目运算符也不宜过长,如果超过三层抽成函数,并写明注释.
-
能用return进行判断的不要用if else.如果发现if else里面用到的判断过多,可以定义枚举类,再判断.
-
总之,当if else看着难受的时候就要做出改变了.避免出现如下情景:
if (type === 1 || type === 2 || type ===3){...} //应当用如下方式进行替换 if ([1,2,3].includes(type)){...} -
对于上下文中的this,用self来命名.
(五)Vue规范
-
Vue组件名应该为多个单词,且命名规范符合KebabCase.这样做可以避免跟现有的以及未来的 HTML 元素相冲突,因为所有的 HTML 元素名称都是单个单词的。
-
Vue自定义组件的文件名应该为 pascal-case 格式.
-
基础组件文件名为 base 开头,使用完整单词而不是缩写. => base-button.vue base-table.vue
-
和父组件紧密耦合的子组件应该以父组件名为前缀. => todo-list.vue todo-list-item.vue
-
再Template中使用组件,应该使用 PascalCase 模式,非slot应该使用 自闭合组件.
-
Prop必须定义详细,包括类型与默认值,必须加上注释,表明其含义.
-
模板中应该使用简单的表达式,复杂的表达式重构为计算属性.
-
script内部标签顺序: props > data > computed > watch > filter > 钩子函数(钩子函数按其执行顺序) > methods
-
**页面跳转使用路由参数,**不要使用vuex或pinia,刷新会掉.
-
router中的path规范,必须以/开头,即使是children里面的path也要以/开头
{ path: '/file', name: 'File', component: Main, children: [ { path: '/file/file-list', name: 'FileList', //尽量使用路由懒加载,除了首页除外. component: () => import('@/views/file/file-list.vue') }, { path: '/file/file-add', name: 'FileAdd', component: () => import('@/views/file/file-add.vue') }, { path: '/file/file-update', name: 'FileUpdate', component: () => import('@/views/file/file-update.vue') } ] }
(六)TS规范
- 使用 PascalCase 为类型命名。
- 使用 PascalCase 为枚举值命名,枚举对象本身和枚举成员都使用 PascalCase 方式命名。
- 类型声明规范:在进行类型声明时应尽量依靠 TS 的自动类型推断功能,如果能够推断出正确类型尽量不要再手动声明。
- 回调函数声明规范:不要在回调函数里使用可选参数,除非这是你想要的.不要因回调函数的参数数量不同而编写不同的重载。
- 不要定义一个从来没使用过其类型参数的泛型类型。
- 子类继承父类时,如果需要重写父类方法,需要加上
override修辞符。 - 使用枚举值设置常量集合.
tsconfig 参考配置
React 项目
{ "compilerOptions": { "target": "esnext", "module": "esnext", "useDefineForClassFields": true, // 发出符合 ECMAScript 标准的类字段 "forceConsistentCasingInFileNames": true,// 区分文件导入大小写 "allowJs": true, "checkJs": true, "skipLibCheck": true, // 跳过所有 .d.ts 文件的检查,主要是跳过 node_modules 目录里的检查 "moduleResolution": "node", "lib": ["ESNext", "DOM", "DOM.Iterable"], "importHelpers": true, "jsx": "react", "allowSyntheticDefaultImports": true, // 允许 cjs 模块 default 导入 "esModuleInterop": false, // 转换 cjs 模块,添加 dedault 导入,因为不需要 tsc 编译,所以没必要开,只需要 allowSyntheticDefaultImports 做检查就行了 "sourceMap": true, "noImplicitOverride": true, // 继承类重写方法必须写 override 关键字 "strict": true, "isolatedModules": true, // 确保每个文件都有导入或导出 "resolveJsonModule": true, // 解析 json "noEmit": true, }, "exclude": ["node_modules"] }
库项目
{ "compilerOptions": { "target": "es5", "module": "CommonJS", "useDefineForClassFields": true, // 发出符合 ECMAScript 标准的类字段 "forceConsistentCasingInFileNames": true,// 区分文件导入大小写 "allowJs": true, "checkJs": true, "skipLibCheck": true, // 跳过所有 .d.ts 文件的检查,主要是跳过 node_modules 目录里的检查 "moduleResolution": "node", "lib": ["ESNext", "DOM", "DOM.Iterable"], "importHelpers": true, "allowSyntheticDefaultImports": true, // 允许 cjs 模块 default 导入 "esModuleInterop": true, // 开启 cjs 模块转换 "sourceMap": true, "noImplicitOverride": true, // 继承类重写方法必须写 override 关键字 "strict": true, "isolatedModules": true, // 确保每个文件都有导入或导出 "resolveJsonModule": true, // 解析 json "noEmit": false, "declaration": true, "declarationMap": true, "outDir": "./dist", "baseUrl": "." }, "exclude": ["node_modules"] }