公司Web代码设计规范
版本说明
| 版本号 | 撰写人 | 审批人 | 提交日期 | 版本说明 |
|---|---|---|---|---|
| V1.0 | cbb | * | 2022.2.16 | 初版,面向公司前端Coder |
| V1.1 | cbb | * | 2022.2.17 | 增加禁用说明,加入便捷开发推荐、代码提交规范 |
注意
本篇代码设计规范针对公司目前前端框架设立,不涉及前端框架搭建部分,vue部分针对2.x版本,对3.x版本不适用。
一、命名规范
1.文件目录
- HTML文件夹 pages || views
- JS文件夹 js
- CSS文件夹 style
- 路由文件夹 router
- API文件夹 api
- 三方库 plugins
- 公用方法 utils
- 说明文档 lib
- 自定义组件 components
- 静态文件 assets
- 图片及SVG文件夹 img
- 字体图标文件夹 icon
- 三方字体文件夹 fonts
2.文件命名
确保文件命名总是以字母开头而不是数字,且字母一律小写,以下划线连接且不带其他标点符号,如:
<!-- HTML -->
jr.html
jr_list.html
jr_detail.html
<!-- SASS -->
jr.scss
jr_list.scss
jr_detail.scss
3.代码命名
-
ClassName命名规范 ClassName的命名应该尽量精短、明确、见名知意,必须以字母开头命名,且全部字母为小写,单词之间统一使用下划线 “_” 连接
基于姓氏命名法(继承 + 外来),祖先模块不能出现下划线,除了是全站公用模块,如 mod_ 系列的命名:
<!--组件内模块-->
<div class="modulename">
<div class="modulename_info">
<div class="modulename_son"></div>
<div class="modulename_son"></div>
...
</div>
</div>
<!-- 这个是全站公用模块,祖先模块允许直接出现下划线 -->
<div class="mod_info">
<div class="mod_info_son"></div>
<div class="mod_info_son"></div>
...
</div>
当子孙模块超过4级或以上的时候,可以考虑在祖先模块内具有识辨性的独立缩写作为新的子孙模块
<div class="modulename">
<div class="modulename_cover"></div>
<div class="modulename_info">
<div class="modulename_info_user">
<div class="modulename_info_user_img">
<img src="" alt="">
<!-- 这个时候 miui 为 modulename_info_user_img 首字母缩写-->
<div class="miui_tit"></div>
<div class="miui_txt"></div>
...
</div>
</div>
<div class="modulename_info_list"></div>
</div>
</div>
-
JavaScript内命名规范
1.变量名 命名方式: 全 英文小写 或 小驼峰式 命名方法
2.函数命名 命名方式: 全 英文小写 或 小驼峰式 ( 构造函数使用大驼峰命名法 )
命名规则:前缀为动词 如:get、fetch、refresh、delet等
3.常量名 命名方法:全部大写
命名规范:使用大写字母和下划线来组合命名,下划线用以分割单词
/*变量名*/ let arrList = []; let objData = {}; /*函数命名*/ function fetchFormData(){...} const getTableData = ()=>{...} /*构造函数命名*/ class WelcomPerson{ constructor(name){ this.name = name } say(){ return 'welcome!' + this.name + ',你好' } } /*常量名*/ const BASE_URL = 'http://192.168.0.186:8002'; const TITLE = 'JROK-首页'
二、代码规范
团队约定
统一团队的编码规范,有助于代码的维护。
1. HTML
-
除非有特定的功能、组件要求等,禁止随意使用id来定义元素样式,尽量使用class类名。
-
标签语法无错误,需要符合语义化。
-
所有具有开始标签和结束标签的元素都要写上起止标签,某些允许省略开始标签或和束标签的元素亦都要写上。
<!--推荐--> <img src='' /> <br/> <input /> <!--禁止--> <img src=''> <br> <input> -
HTML标签名、类名、标签属性和大部分属性值统一用小写 ;
<!--推荐--> <div> <h1></h1> </div> <!--禁止--> <DIV> <H1></H1> </DIV> -
文本可以和字符引用混合出现,尽量使用html转义符。HTML转义字符对照表
<!--推荐--> <a href="#">more>></a> <!--不推荐--> <a href="#">more>></a> -
段落元素与标题元素只能嵌套内联元素。
<!--推荐--> <h1> <span></span> </h1> <!--禁止--> <span> <h1></h1> </span> -
段落换行尽量使用块状标签包裹换行,不推荐使用br、hr等标签换行
<!--推荐--> <p>第一行</p> <p>第二行</p> <!--不推荐--> <p>第一行<br/>第二行</p> -
页面中svg等图源样式的引入使用img标签包裹引入
<!--推荐--> <img src='asstes/svg/title.svg'/> <!--禁止-->
直接将svg的代码粘贴到html中
#### 2. CSS
- 代码大小写:样式选择器,属性名,属性值关键字全部使用小写字母书写,属性字符串允许使用大小写。
```css
/* 推荐 */
.jrc{
display:block;
}
/* 禁止 */
.JrC{
DISPLAY:BLOCK;
}
-
选择器:尽量少用通用选择器
*/* 推荐 */ .jrc {} .jrc li {} .jrc li p{} /* 不推荐 */ *{} #jrc {} .jrc div{} -
禁止使用层级过深的选择器,最多3级。
/*错误示范:*/ .without-animation .book-body .body-inner .book-header .dropdown .dropdown-menu .buttons{} -
z-index层级不推荐超过三位数,层级太高容易串层,后期维护繁杂。
-
尽量使用
flex布局,减少float布局的使用。原因:浮动布局容易脱离文本域。
3. JS
-
在使用
axios请求方式中,尽量使用promise异步请求方式,且请求按页面模块封装在api文件内,在调用文件中以引入方式调用。//api-index.js import axios from "@/utils/axios" //引入封装后axios /******* * @description: template * @param {*} data * @return {*} promison Data */ export const templateApi = (data) => { return request({ url: "/api/url", method: "post", data }) } ---------------------------------------------------------------- //index.vue //不推荐 //此写法不方便进行全局接口拦截 耦合度高 且链式调用容易形成“面条代码” const getData () => { this.$axios.post('/api/url',data).then((res)=>{...}).catch((err)=>{...}) } //推荐 //分类书写 降低耦合度 后期方便维护 import { templateApi } from '@/api/index' //采用async异步调用并配合try catch捕捉error const getData = async () =>{ const data = {} try{ const res = await templateApi(data) console.log(res) ... }catch(err){ console.error(error) } } //或者 //异步调用与链式调用相结合 节约代码量 const getData = async () =>{ const data = {} const res = await templateApi(data).catch(err=>{...}) console.log(res) ... } -
请尽量使用es6+规范书写;
-
对象简写
/*对象简写*/ const job = 'JavaCoder' let item = {} //不推荐 item = { job:job } //推荐 item = { job } -
函数表达式、箭头函数
/*函数表达式 使用具名函数表达式而非函数声明 原因:提高可维护性*/ /*箭头函数 当你必须使用函数表达式(传递匿名函数)时,使用箭头函数标记 原因:它将创建在 this 上下文中执行的函数版本,通常是您想要的,并且语法更简洁*/ //不推荐 function filterTime(){...} [1,2,3].forEach(function(){...}) //推荐 const filterTime = ()=> {...} [1,2,3].forEach(()=>{...}) -
展开运算符
/*展开运算符 ... */ const obj = {a:1,b:2} const arr = [1,2] //合并新对象、数组 //不推荐 const newObj = Object.assign(obj,{c:3}) const newArr = arr.connect([3]) //推荐 const newObj = {...obj,c:3} const newArr = [...arr,3] -
解构赋值、模板字符串
/*解构赋值 模板字符串*/ // 不推荐 const getFullName = (user) => { const firstName = user.firstName const lastName = user.lastName return firstName + lastName } // 推荐 const getFullName = (user) => { const { firstName, lastName } = user //声明解构 return `${firstName} ${lastName}` //模板字符串 } // 五星好评 const getFullName = ({ firstName, lastName }) => { //传值结构 return `${firstName} ${lastName}` } -
es6模块的输出与输入
/*es6模块的输出与输入*/ // 不推荐 const util = require('./util') module.exports = util // 推荐 import Util from './util' export default Util // 五星好评 import { Util } from './util' export { Util }
-
-
请记得
const和let都是块级作用域,var是函数级作用域,对所有引用都使用const或let,不要使用var,原因:
var有污染页面全局变量的风险;/*const、let*/ // 不推荐 var name = 'JROK' var age = 18 // 推荐 const name = 'JROK' //常量 let age = 18 //变量/*将所有的 const 和 let 分组*/ // 不推荐 let a const b let c const d let e // 推荐 const b const d let a let c let e -
不允许出现未被使用的变量;
-
尽量不要出现“魔术字符串”
//不推荐 if(objName === 'JAVA'){...} //推荐 const coder = 'JAVA'; if(objName === coder){...} -
不要修改内置对象,如
Object和Array;原因:避免造成其他页面调用相同方法后调用失败 -
使用
===和!==而非==和!=,避免类型的隐式转换;//不推荐 0 == '0' //true //推荐 0 === '0' //false
4. VUE
-
少用watch监听值的变化,多使用双向绑定或者组件方法@change或者@input,原因:降低运行效率,且耦合度高,不利于后期维护
-
因vue单页面SPA框架特性,页面中创建的定时器
如:setTimeout,setInterval、事件监听如:addEventListener、onload,需在页面销毁前即:beforeDestroy()中进行销毁,如若不然则会在下个页面继续执行,造成报错阻塞或污染,影响下一页面代码逻辑执行。 -
组件的
data必须是一个函数,原因:避免变量污染//不推荐 export default { data: { foo: 'bar' } } //推荐 export default { data () { return { foo: 'bar' } } } -
Prop 定义应该尽量详细
//不推荐 props: ['status'] //推荐 props: { status: {//值名称 type: String,//传递值类型 required: true,//传递值是否必须 } } -
为
v-for设置键值 key 总是用key配合v-for,原因:精准diff算法需要,通过key值来提升渲染的效率。Vue2.0 v-for 中 :key 到底有什么用? - 知乎 (zhihu.com)
<!--禁止--> <ul> <li v-for="todo in todos"> {{ todo.text }} </li> </ul> <!--推荐--> <ul> <li v-for="todo in todos" :key="todo.id" > {{ todo.text }} </li> </ul> -
避免
v-if和v-for用在一起 **永远不要把v-if和v-for同时用在同一个元素上。**原因:带来性能方面的浪费(每次渲染都会先循环再进行条件判断)<!--不推荐--> <ul> <li v-for="user in users" v-if="shouldShowUsers" :key="user.id" > {{ user.name }} </li> </ul> <!--推荐--> <ul v-if="shouldShowUsers"> <li v-for="user in users" :key="user.id" > {{ user.name }} </li> </ul> -
为组件样式设置作用域,原因:防止样式变量污染,设置作用域scoped后当前样式只作用于当前页面。
<!--不推荐--> <style> .btn-close { background-color: red; } </style> <!--推荐--> <!-- 使用 `scoped` attribute --> <style scoped> .button { border: none; border-radius: 2px; } </style> -
指令缩写,原因:提高代码简洁度
<!--不推荐--> <input v-on:input="onInput" v-bind:value="newTodoText" > <!--推荐--> <input v-model='newTodoText' > -
书写顺序
-
单文件顺序
<!-- ComponentA.vue --> <script>/* ... */</script> <template>...</template> <style>/* ... */</style> -
标签内attribute顺序
-
定义 (提供组件的选项)
is
-
列表渲染 (创建多个变化的相同元素)
v-for
-
条件渲染 (元素是否渲染/显示)
v-ifv-else-ifv-elsev-showv-cloak
-
渲染方式 (改变元素的渲染方式)
v-prev-once
-
全局感知 (需要超越组件的知识)
id
-
唯一的 attribute (需要唯一值的 attribute)
refkey
-
双向绑定 (把绑定和事件结合起来)
v-model
-
其它 attribute (所有普通的绑定或未绑定的 attribute)
-
事件 (组件事件监听器)
v-on
-
内容 (覆写元素的内容)
-
v-html -
v-text
-
-
-
组件/实例的选项应该有统一的顺序。
这是我们推荐的组件选项默认顺序。它们被划分为几大类,所以你也能知道从插件里添加的新 property 应该放到哪里。
- 副作用 (触发组件外的影响)
el
- 全局感知 (要求组件以外的知识)
nameparent
- 组件类型 (更改组件的类型)
functional
- 模板修改器 (改变模板的编译方式)
delimiterscomments
- 模板依赖 (模板内使用的资源)
componentsdirectivesfilters
- 组合 (向选项里合并 property)
extendsmixins
- 接口 (组件的接口)
inheritAttrsmodelprops/propsData
- 本地状态 (本地的响应式 property)
datacomputed
- 事件 (通过响应式事件触发的回调)
watch- 生命周期钩子 (按照它们被调用的顺序)
beforeCreatecreatedbeforeMountmountedbeforeUpdateupdatedactivateddeactivatedbeforeDestroydestroyed
- 非响应式的 property (不依赖响应系统的实例 property)
methods
- 渲染 (组件输出的声明式描述)
-
template/render -
renderError
-
- 副作用 (触发组件外的影响)
-
三、注释规范
目的和原则
提高可读性和可维护性 如无必要,勿增注释;如有必要,尽量详尽
语法和快捷键
单行注释:// 快捷键: ctrl+/
多行注释:/**/ 快捷键: ctrl+shift+/
规范
1、注释符与注释内容之间加一个空格 2、注释行与上方代码间加一个空行
HTML顶部文档注释
<!--
* @Author: name
* @Date: 2022-02-11 09:44:53
* @LastEditTime: 2022-02-17 10:26:39
* @LastEditors: name
* @Description:
* @FilePath: \views\platform\bill\task\index.html
-->
CSS
/* content */
内容
/* end content */
JS
/**
* @description: 获取表格数据
* @param {Number} type 类型
* @return {*}
*/
const getTableData(type) =>{...}
四、便捷开发规范
好的软件、工具能更好的实现便捷开发,团队约定
-
开发工具:
- Visual Studio Code
-
VS Code插件:
- ESLint //代码格式规则检查
- css-auto-prefix //css书写自动添加兼容
- koroFileHeader //快捷生成注释
- Prettier //代码格式化
- Vue 3 Support - All In One //vue快捷提示、代码格式化
- filesize //引入文件大小展示
- Auto Close Tag //自动闭合html标签
- Auto Rename Tag //自动重命名html标签名
- Color Highlight //color高亮
-
调试工具:
- Chorme
- Edge
- 微信开发者工具
- Postman
-
浏览器插件:
- Vue.js devtools //vue官方调试工具
- JSON Viewer //网页Json查看
-
环境:
-
Node 14.* //向下兼容 不选择最新版本
-
npm
-
更改至淘宝源
npm config set registry http://registry.npm.taobao.org/
-
-
cnpm
-
安装
npm install -g cnpm -registry=https://registry.npm.taobao.org
-
-
-
网盘下载:
阿里云盘 提取码: e33q
五、代码提交规范
-
提交代码前必须解决所有页面报错
-
先拉取,如有冲突解决后,再提交
-
禁止代码同步功能
-
提交信息commit message 必须填写,格式为 type + content
<!--修复--> fix:修复问题 <!--更新--> update:更新代码 <!--添加--> add:添加文件 <!--删除--> del:删除某个文件