1. 前言
1.1 概述
为了提高工作效率,便于后台人员添加功能及前端后期优化维护,输出高质量的文档,在网站建设中,使结构更加清晰,代码简明有序,有一个更好的前端架构。
2.1 规范基本准则
符合 web 标准,使用具有语义的标签,使结构、表现、行为分离,兼容性优良。页面性能优化,代码简洁、明了、有序,尽可能的减少服务器的负载,保证最快的解析速度。
2. 规范总结
2.1 HTML 规范
-
文件应以“
<!DOCTYPE ......>
” 首行顶格开始,推荐使用“<!DOCTYPE html>
”。 -
必须声明文档的编码 charset,且与文件本身编码保持一致,推荐使用 UTF-8 编码<meta charset="utf-8"/>。
-
用两个空格来代替制表符(tab) -- 这是唯一能保证在所有环境下获得一致展现的方法。
-
嵌套元素应当缩进一次(即两个空格),保持良好的简洁的树形结构。
正确示范代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Title</title>
</head>
<body></body>
</html>
-
class 命名必须单词全字母小写,单词间以 - 分隔,避免数字开头
-
HTML 引号,必须使用双引号(“”)而不是单引号(‘’)
-
HTML 属性应当按照以下给出的顺序依次排列,确保代码的易读性。
- class, id, name
- data-_
- src, for, type, href, value
- title, alt
- role, aria-_
<a class="class-a" id="classA" data-toggle="modal" href="">Example Link</a>
<input class="form-control" type="text" />
<img src="../img..." alt="description" />
- 提倡使用语义化标签
不推荐
<div class="header"></div>
<div class="body"></div>
<div class="footer"></div>
推荐
<header>头部</header>
<article>正文</article>
<footer>尾部</footer>
-
不许使用 table 表格进行页面布局。table 仅可在表格列表信息数据渲染使用。
-
禁止在标签内嵌套样式,应给相应 class 名称去定义样式。
不推荐
<div style="color: red"></div>
推荐
<div class="tag-color">标签</div>
- 禁止 a 标签的 href 取值为空或不写 href 属性
重构时默认尽量用脚本“javascript:;”或者“javascript:void(0);”代替,而不是“#”,避免页面乱跳。
不推荐 <a href="#"></a>
推荐 <a href="javascript:void(0);"></a>
- html 标签统一小写,禁止大写,避免页面不统一。
反例
<!--prettier-ignore-->
<DIV>
<P></P>
</DIV>
正例
<div>
<p></p>
</div>
- 在页面底部引入 javascript 文件,让页面以最快的速度呈现在用户面前
不推荐
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>Title</title>
<script src="jquery.js"></script>
</head>
<body></body>
</html>
推荐
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>Title</title>
</head>
<body>
<script src="jquery.js"></script>
</body>
</html>
- 建议为所有的图片加上 alt 属性 ,避免图片加载失败时对用户有所提示。并且有利于搜索引擎。firefox 不支持显示图像 alt 属性,可以加入 title 属性。
<img src="../img..." alt="description" />
Firefox
<img src="../img..." title="description" />
1.2 CSS/less 规范
-
十六进制值应该全部小写,例如,#fff。在扫描文档时,小写字符易于分辨。
-
避免为 0 值指定单位。例如:是{ margin:0 }, 而不是 { margin:0px }
-
不建议使用 "_" 下划线来命名 CSS 选择器,可以用“ - ”中划线,因为输入的时候少按一个 shift 键; 浏览器兼容问题(比如使用 _tips 的选择器命名,在 IE6 是无效的)能良好区分 JavaScript 变量命名(JS 变量命名是用“_”)
-
避免选择器嵌套层级过多,尽量少于 3 级;
-
选择器分组时,保持独立的选择器占用一行;
不推荐
/* prettier-ignore */
.seclector, .seclector-secondary {
padding: 15px;
margin: 0 0 15px;
}
推荐 .seclector,
.seclector-secondary {
padding: 15px;
margin: 0 0 15px;
}
- 避免使用 @import,与 <link> 相比,@import 要慢很多,不光增加额外的请求数,还会导致不可预料的问题。替代办法:
a. 通过 Sass 或 Less 类似的 CSS 预处理器将多个 CSS 文件编译为一个文件;
b. 其他 CSS 文件合并工具;
-
除了重置浏览器默认样式外,禁止直接为 html 、a、img 等添加 css 样式设置
-
合并 margin、padding、border 的-left/-top/-right/-bottom 的设置,尽量使用短名称。
/* 不推荐 */
.box {
margin-bottom: 0;
margin-top: 0;
margin-left: 10px;
}
/* 推荐 */
.box {
margin: 0 0 0 10px;
}
-
如果没有边框时,不要写成 border:0,应该写成 border:none
-
background、font 等可以缩写的属性,尽量使用缩写形式。
-
层级(z-index)必须清晰明确,页面弹窗、气泡为最高级(最高级为 999),不同弹窗气泡之间可在三位数之间调整;普通区块为 10-90 内 10 的倍数;区块展开、弹出为当前父层级上个位增加,禁止层级间盲目攀比。
-
不要在 rgb()、rgba()、hsl()、hsla() 或 rect() 值的内部的逗号后面插入空格。这样利于从多个属性值(既加逗号也加空格)中区分多个颜色值(只加逗号,不加空格)。
-
对于经常出现的组件,尽量避免使用属性选择器(例如,[class^="..."])。浏览器的性能会受到这些因素的影响。
-
为了获得更准确的错误报告,每条声明都应该独占一行。
<!-- 不推荐 -->
.box { color: #fff; padding: 0 12px; font-size: 10px; }
/* 推荐 */
.box {
color: #fff;
padding: 0 12px;
font-size: 10px;
}
- 当使用特定厂商的带有前缀的属性时,通过缩进的方式,让每个属性的值在垂直方向对齐,这样便于多行编辑。
/* prettier-ignore */
.selector {
-webkit-animation-delay: 500ms;
animation-delay: 500ms;
}
1.3 JS 规范
-
注释!!!---为了方便其它同事,自己写代码的时候一定要写注释。若是定义的全局注释或者函数等注释采用标准等文档注释。
-
函数命名统一采用驼峰命名法
-
一次性修改样式属性;例如:
// 优化前
let ele = document.getElementById("ele");
ele.style.background = "#e6e6e6";
ele.style.color = "#000";
ele.style.fontSize = "12rem";
<!-- 优化后 -->
<style>
.addActive {
background: "#eee";
color: rebeccapurple;
height: 200px;
}
</style>
<script>
document.getElementById("app").className = "addActive";
</script>
-
简短的判断,可用三元操作符替代 if 条件判断语句。
-
用 var 声明变量,不要使用 let。避免低版本浏览器报错。在 vue、react 项目中可使用 let。
-
不要加多余的逗号,这可能会在 IE 下引起错误,同时如果多一个逗号某些 ES3 的实现会计算多数组的长度。
反例;
// prettier-ignore
var obj = {
name: "Mercury",
gender: "female",
};
正例;
var obj = {
name: "Mercury",
gender: "female"
};
- 语句结束一定要加分号
3. 框架规范
3.1 Vue 规范
- 组件名为多个单词
组件名应该始终是多个单词的,根组件 App 除外。
// 正例
export default {
name: 'TodoItem',
// ... }
// 反例
export default {
name:'Todo',
// ... }
- 组件数据
组件的 data 必须是一个函数。当在组件中使用 data 属性的时候 (除了 new Vue 外的任何地方),它的值必须是返回一个对象的函数。
正例:
// In a .vue file
export default {
data () {
return {
foo: 'bar'
}
}
}
// 在一个 Vue 的根实例上直接使用对象是可以的,
// 因为只存在一个这样的实例。
new Vue({
data: {
foo: 'bar'
}
})
反例:
export default {
data: {
foo: 'bar'
}
}
- Prop 定义
Prop 定义应该尽量详细。
在你提交的代码中,prop 的定义应该尽量详细,至少需要指定其类型。
正例:
props: {
status: String
}
// 更好的做法!
props: {
status: {
type: String,
required: true,
validator: function(value) {
return (
["syncing", "synced", "version-conflict", "error"].indexOf(value) !==
-1
);
}
}
}
反例:
// 这样做只有开发原型系统时可以接受
props: ['status']
- 为 v-for 设置键值
总是用 key 配合 v-for: 在组件上总是用 key 配合 v-for,以便维护内部组件及其子树的状态。甚至在元素上维护可预测的行为,比如动画中的对象固化 (object constancy),也是一种好的做法。
正例:
<ul>
<li v-for="todo in todos" :key="todo.id">
{{ todo.text }}
</li>
</ul>
反例:
<ul>
<li v-for="todo in todos">
{{ todo.text }}
</li>
</ul>
- 避免 v-if 和 v-for 用在一起
不要把 v-if 和 v-for 同时用在同一个元素上。一般我们在两种常见的情况下会倾向于这样做:为了过滤一个列表中的项目 (比如 v-for="user in users" v-if="user.isActive")。在这种情形下,请将 users 替换为一个计算属性 (比如 activeUsers),让其返回过滤后的列表。为了避免渲染本应该被隐藏的列表 (比如 v-for="user in users" v-if="shouldShowUsers")。这种情形下,请将 v-if 移动至容器元素上 (比如 ul, ol)
正例
<ul v-if="shouldShowUsers">
<li v-for="user in users" :key="user.id">
{{ user.name }}
</li>
</ul>
反例
<ul>
<li v-for="user in users" v-if="shouldShowUsers" :key="user.id">
{{ user.name }}
</li>
</ul>
- 为组件样式设置作用域
为了避免样式冲突,整个项目要么全都使用 scoped 特性,要么使用 BEM 约定。
// 正例
<!-- 使用 scoped 特性 -->
<template>
<button class="btn btn-sure">确认</button>
</template>
<style scoped>
.btn {
border: 1px solid #f1f1f1;
}
.btn-sure {
background-color: blue;
}
</style>
<!-- 使用 BEM(Block Element Modifier) 特性 -->
<template>
<button class="menu-btn menu-btn-sure">确认</button>
</template>
<style>
.menu-btn {
border: 1px solid #f1f1f1;
}
.menu-btn-sure {
background-color: blue;
}
</style>
// 反例
<template>
<button class="btn btn-sure">确认</button>
</template>
<style>
.btn {
border: 1px solid #f1f1f1;
}
.btn-sure {
background-color: blue;
}
</style>
- 组件文件 Component
正例
components/
|- TodoList.vue
|- TodoItem.vue
反例:
Vue.component("TodoList", {});
Vue.component("TodoItem", {});
- 单文件组件文件的大小写
单文件组件的文件名应该要始终是单词大写开头 (PascalCase)
正例
components/
|- MyComponent.vue
反例
components/
|-myComponent.vue
|- mycomponent.vue
- 基础组件名
应用特定样式和约定的基础组件 (也就是展示类的、无逻辑的或无状态的组件) 应该全部以一个特定的前缀开头,比如 Base、App 或 V
正例:
components/
|- BaseButton.vue
|- BaseTable.vue
|- BaseIcon.vue
反例:
components/
|- MyButton.vue
|- VueTable.vue
|- Icon.vue
- 单例组件名
只应该拥有单个活跃实例的组件应该以 The 前缀命名,以示其唯一性。这不意味着组件只可用于一个单页面,而是每个页面只使用一次。这些组件不接受任何 prop,因为它们是为你的应用定制的,而不是它们在你的应用中的上下文。如果你发现有必要添加 prop,那就表明这实际上是一个可复用的组件,只是目前在每个页面里只使用一次。
正例:
components/
|- TheHeading.vue
|- TheSidebar.vue
反例
components/
|- Heading.vue
|- MySidebar.vue
- 紧密耦合的组件名
和父组件紧密耦合的子组件应该以父组件名作为前缀命名。
正例:
components/
|- TodoList.vue
|- TodoListItem.vue
|- TodoListItemButton.vue components/
|- SearchSidebar.vue
|- SearchSidebarNavigation.vue
反例:
components/
|- SearchSidebar.vue
|- NavigationForSearchSidebar.vue
- 组件名中的单词顺序
组件名应该以高级别的 (通常是一般化描述的) 单词开头,以描述性的修饰词结尾。
正例
components/
|- SearchButtonClear.vue
|- SearchButtonRun.vue
|- SearchInputQuery.vue
|- SearchInputExcludeGlob.vue
|- SettingsCheckboxTerms.vue
|- SettingsCheckboxLaunchOnStartup.vue
反例:
components/
|- ClearSearchButton.vue
|- ExcludeFromSearchInput.vue
|- LaunchOnStartupCheckbox.vue
|- RunSearchButton.vue
|- SearchInput.vue
|- TermsCheckbox.vue
- 模板中的组件名大小写遵循 PascalCase 规则
正例:
<!-- 在单文件组件和字符串模板中 -->
<MyComponent />
反例:
<!-- 在单文件组件和字符串模板中 -->
<mycomponent />
<!-- 在单文件组件和字符串模板中 -->
<myComponent />
- 完整单词的组件名
组件名应该倾向于完整单词而不是缩写。
正例:
components/
|- StudentDashboardSettings.vue
|- UserProfileOptions.vue
反例:
components/
|- SdSettings.vue
|- UProfOpts.vue
- 多个特性的元素,分多行撰写,每个特性一行。
正例
<img src="https://vuejs.org/images/logo.png" alt="Vue Logo" />
<!-- prettier-ignore -->
<MyComponent
foo="a"
bar="b"
baz="c">
</MyComponent>
反例
<img src="https://vuejs.org/images/logo.png" alt="Vue Logo"/>
<MyComponent foo="a" bar="b" baz="c"/></MyComponent>
- 模板中简单的表达式
组件模板应该只包含简单的表达式,复杂的表达式则应该重构为计算属性或方法。复杂表达式会让你的模板变得不那么声明式。我们应该尽量描述应该出现的是什么,而非如何计算那个值。而且计算属性和方法使得代码可以重用。
正例
<!-- 在模板中 -->
{{ normalizedFullName }} // 复杂表达式已经移入一个计算属性
computed: {
normalizedFullName: function() {
return this.fullName
.split(" ")
.map(function(word) {
return word[0].toUpperCase() + word.slice(1);
})
.join(" ");
}
}
反例:
{{ fullName.split(' ').map(function (word)
{ return word[0].toUpperCase() + word.slice(1) }).join(' ') }}
- 简单的计算属性
正例:
computed: {
basePrice: function() {
return;
this.manufactureCost / (1 - this.profitMargin);
},
discount: function() {
return this.basePrice - (this.discountPercent || 0);
},
finalPrice: function() {
return this.basePrice - this.discount;
}
}
反例:
computed: {
price: function() {
var basePrice = this.manufactureCost / (1 - this.profitMargin);
return basePrice - basePrice - (this.discountPercent || 0);
}
}
- 指令缩写
用 : 表示 v-bind: 和用 @ 表示 v-on:
正例:
<input @input="onInput" @focus="onFocus" />
反例:
<input v-bind:value="newTodoText" :placeholder="newTodoInstructions" />
- 单文件组件的顶级元素顺序
<template></template>
<script></script>
<style></style>
网友评论