前端團隊有評審代碼的要求,但因爲每一個開發人員的水平不一樣,技術關注點不一樣,因此對代碼評審的關注點不一樣,爲了保證代碼質量,團隊代碼風格統一,特此擬定一份《前端團隊代碼評審 CheckList 清單》,這樣代碼評審人員在評審代碼時,能夠參照這份清單,對代碼進行評審。從而輔助整個團隊提升代碼質量、統一代碼規範。若是你的團隊尚未這麼一份代碼評審 CheckList 清單,也許這正是你須要的;若是你的團隊已經有了代碼評審參照標準,這份清單也許能起到錦上添花的效果。javascript
辛苦整理良久,還望手動點贊鼓勵~css
github地址爲:github.com/fengshi123/…,若是喜歡或者有所啓發,請幫忙給個 star ~,對做者也是一種鼓勵。前端
eslint
檢查的規範繼承自 eslint-config-standard
檢驗規則,具體的規則介紹參照連接:cn.eslint.org/docs/rules/ ,這裏及如下部分再也不重複介紹這些檢驗規則。
vue
stylelint
檢查的規範繼承自 stylelint-config-standard
檢驗規則,具體的規則介紹參照連接:www.npmjs.com/package/sty… ,這裏及如下部分再也不重複介紹這些檢驗規則。
java
推薦:git
studentInfot複製代碼
推薦:github
const Car = {
make: "Honda",
model: "Accord",
color: "Blue"
};複製代碼
不推薦:vuex
const Car = {
carMake: "Honda",
carModel: "Accord",
carColor: "Blue"
};複製代碼
推薦:
npm
.block__element{}
.block--modifier{}複製代碼
命名須要符合語義化,若是函數命名,能夠採用加上動詞前綴:
編程
動詞 | 含義 |
---|---|
can | 判斷是否可執行某個動做 |
has | 判斷是否含有某個值 |
is | 判斷是否爲某個值 |
get | 獲取某個值 |
set | 設置某個值 |
推薦:
//是否可閱讀
function canRead(){
return true;
}
//獲取姓名
function getName{
return this.name
} 複製代碼
每一個常量應該命名,否則看代碼的人不知道這個常量表示什麼意思。
推薦:
const COL_NUM = 10;
let row = Math.ceil(num/COL_NUM);複製代碼
不推薦:
let row = Math.ceil(num/10);複製代碼
建立對象和數組推薦使用字面量,由於這不只是性能最優也有助於節省代碼量。
推薦:
let obj = {
name:'tom',
age:15,
sex:'男'
} 複製代碼
不推薦:
let obj = {};
obj.name = 'tom';
obj.age = 15;
obj.sex = '男';複製代碼
推薦:
const menuConfig = {
title: "Order",
// User did not include 'body' key
buttonText: "Send",
cancellable: true
};
function createMenu(config) {
config = Object.assign(
{
title: "Foo",
body: "Bar",
buttonText: "Baz",
cancellable: true
},
config
);
// config now equals: {title: "Order", body: "Bar", buttonText: "Send", cancellable: true}
// ...
}
createMenu(menuConfig);
複製代碼
不推薦:
const menuConfig = {
title: null,
body: "Bar",
buttonText: null,
cancellable: true
};
function createMenu(config) {
config.title = config.title || "Foo";
config.body = config.body || "Bar";
config.buttonText = config.buttonText || "Baz";
config.cancellable =
config.cancellable !== undefined ? config.cancellable : true;
}
createMenu(menuConfig);
複製代碼
對象成員嵌套越深,讀取速度也就越慢。因此好的經驗法則是:若是在函數中須要屢次讀取一個對象屬性,最佳作法是將該屬性值保存在局部變量中,避免屢次查找帶來的性能開銷。
推薦:
let person = {
info:{
sex:'男'
}
}
function getMaleSex(){
let sex = person.info.sex;
if(sex === '男'){
console.log(sex)
}
} 複製代碼
不推薦:
let person = {
info:{
sex:'男'
}
}
function getMaleSex(){
if(person.info.sex === '男'){
console.log(person.info.sex)
}
}
複製代碼
當須要將浮點數轉換成整型時,應該使用Math.floor()
或者Math.round()
,而不是使用parseInt()
將字符串轉換成數字。Math 是內部對象,因此
Math.floor()
其實並無多少查詢方法和調用時間,速度是最快的。
推薦:
let num = Math.floor('1.6');複製代碼
不推薦:
let num = parseInt('1.6');複製代碼
函數參數越少越好,若是參數超過兩個,要使用 ES6
的解構語法,不用考慮參數的順序。
推薦:
function createMenu({ title, body, buttonText, cancellable }) {
// ...
}
createMenu({
title: 'Foo',
body: 'Bar',
buttonText: 'Baz',
cancellable: true
});
複製代碼
不推薦:
function createMenu(title, body, buttonText, cancellable) {
// ...
}
複製代碼
使用參數默認值 替代 使用條件語句進行賦值。
推薦:
function createMicrobrewery(name = "Hipster Brew Co.") {
// ...
}
複製代碼
不推薦:
function createMicrobrewery(name) {
const breweryName = name || "Hipster Brew Co.";
// ...
}複製代碼
這是一條在軟件工程領域流傳久遠的規則。嚴格遵照這條規則會讓你的代碼可讀性更好,也更容易重構。若是違反這個規則,那麼代碼會很難被測試或者重用 。
在 JavaScript
中,永遠不要污染全局,會在生產環境中產生難以預料的 bug
。舉個例子,好比你在 Array.prototype
上新增一個 diff
方法來判斷兩個數組的不一樣。而你同事也打算作相似的事情,不過他的 diff
方法是用來判斷兩個數組首位元素的不一樣。很明顯大家方法會產生衝突,遇到這類問題咱們能夠用 ES2015/ES6
的語法來對 Array
進行擴展。
推薦:
class SuperArray extends Array {
diff(comparisonArray) {
const hash = new Set(comparisonArray);
return this.filter(elem => !hash.has(elem));
}
}複製代碼
不推薦:
Array.prototype.diff = function diff(comparisonArray) {
const hash = new Set(comparisonArray);
return this.filter(elem => !hash.has(elem));
};
複製代碼
函數式變編程可讓代碼的邏輯更清晰更優雅,方便測試。
推薦:
const programmerOutput = [
{
name: 'Uncle Bobby',
linesOfCode: 500
}, {
name: 'Suzie Q',
linesOfCode: 1500
}, {
name: 'Jimmy Gosling',
linesOfCode: 150
}, {
name: 'Gracie Hopper',
linesOfCode: 1000
}
];
let totalOutput = programmerOutput
.map(output => output.linesOfCode)
.reduce((totalLines, lines) => totalLines + lines, 0)
複製代碼
不推薦:
const programmerOutput = [
{
name: 'Uncle Bobby',
linesOfCode: 500
}, {
name: 'Suzie Q',
linesOfCode: 1500
}, {
name: 'Jimmy Gosling',
linesOfCode: 150
}, {
name: 'Gracie Hopper',
linesOfCode: 1000
}
];
let totalOutput = 0;
for (let i = 0; i < programmerOutput.length; i++) {
totalOutput += programmerOutput[i].linesOfCode;
}複製代碼
爲了讓代碼更簡潔易讀,若是你的函數中出現了條件判斷,那麼說明你的函數不止幹了一件事情,違反了函數單一原則 ;而且絕大數場景可使用多態替代
推薦:
class Airplane {
// ...
}
// 波音777
class Boeing777 extends Airplane {
// ...
getCruisingAltitude() {
return this.getMaxAltitude() - this.getPassengerCount();
}
}
// 空軍一號
class AirForceOne extends Airplane {
// ...
getCruisingAltitude() {
return this.getMaxAltitude();
}
}
// 賽納斯飛機
class Cessna extends Airplane {
// ...
getCruisingAltitude() {
return this.getMaxAltitude() - this.getFuelExpenditure();
}
}
複製代碼
不推薦:
class Airplane {
// ...
// 獲取巡航高度
getCruisingAltitude() {
switch (this.type) {
case '777':
return this.getMaxAltitude() - this.getPassengerCount();
case 'Air Force One':
return this.getMaxAltitude();
case 'Cessna':
return this.getMaxAltitude() - this.getFuelExpenditure();
}
}
}複製代碼
代碼中使用了定時器 setTimeout
和 setInterval
,須要在不使用時進行清除。
利用scss
中的變量配置,能夠進行項目的顏色、字體大小統一更改(換膚),有利於後期項目的維護。
推薦:
$--color-success: #67C23A;
$--color-warning: #E6A23C;
$--color-danger: #F56C6C;
$--color-info: #909399;
複製代碼
scss
中的@import
規則在生成css
文件時就把相關文件導入進來。這意味着全部相關的樣式被概括到了同一個css
文件中,而無需發起額外的下載請求,在構建咱們本身的組件庫時推薦使用。
@import "./base.scss";
@import "./pagination.scss";
@import "./dialog.scss";
@import "./autocomplete.scss";
@import "./dropdown.scss";
@import "./dropdown-menu.scss";
複製代碼
scss
局部文件的文件名如下劃線開頭。這樣,scss
就不會在編譯時單獨編譯這個文件輸出css
,而只把這個文件用做導入。
推薦:
scss
的嵌套和父選擇器標識符 & 能解決BEM
命名的冗長,且使樣式可讀性更高。
推薦:
.el-input {
display: block;
&__inner {
text-align: center;
}
}複製代碼
mixin
混合器用來實現大段樣式的重用,減小代碼的冗餘,且支持傳參。
@mixin button-size($padding-vertical, $padding-horizontal, $font-size, $border-radius) {
padding: $padding-vertical $padding-horizontal;
font-size: $font-size;
border-radius: $border-radius;
&.is-round {
padding: $padding-vertical $padding-horizontal;
}
}
@include m(medium) {
@include button-size($--button-medium-padding-vertical, $--button-medium-padding-horizontal, $--button-medium-font-size, $--button-medium-border-radius);
}
@include m(small) {
@include button-size($--button-small-padding-vertical, $--button-small-padding-horizontal, $--button-small-font-size, $--button-small-border-radius);
}
複製代碼
(1)使用@extend
產生 DRY CSS風格的代碼(Don't repeat yourself)
(2)@mixin
主要的優點就是它可以接受參數。若是想傳遞參數,你會很天然地選擇@mixin
而不是@extend
推薦:
.common-mod {
height: 250px;
width: 50%;
background-color: #fff;
text-align: center;
}
.show-mod--right {
@extend .common-mod;
float: right;
}
.show-mod--left {
@extend .common-mod;
}
複製代碼
插值能動態定義類名的名稱,當有兩個頁面的樣式相似時,咱們會將相似的樣式抽取成頁面混合器,但兩個不一樣的頁面樣式的命名名稱根據BEM
命名規範不能同樣,這時咱們可以使用插值進行動態命名。
推薦:
@mixin home-content($class) {
.#{$class} {
position: relative;
background-color: #fff;
overflow-x: hidden;
overflow-y: hidden;
&--left {
margin-left: 160px;
}
&--noleft {
margin-left: 0;
}
}
}
複製代碼
可經過each
遍歷、map
數據類型、@mixin/@include
混合器、#{} 插值 結合使用,從而減小冗餘代碼,使代碼更精簡。
推薦:
$img-list: (
(xlsimg, $papers-excel),
(xlsximg, $papers-excel),
(gifimg, $papers-gif),
(jpgimg, $papers-jpg),
(mp3img, $papers-mp3),
(mp4img, $papers-mp3),
(docimg, $papers-word),
(docximg, $papers-word),
(rarimg, $papers-zip),
(zipimg, $papers-zip),
(unknownimg, $papers-unknown)
);
@each $label, $value in $img-list {
.com-hwicon__#{$label} {
@include commonImg($value);
}
}
複製代碼
scss
自帶函數的應用,從而進行相關的計算,例如 mix
函數的使用以下。
@include m(text) {
&:hover,
&:focus {
color: mix($--color-white, $--color-primary, $--button-hover-tint-percent);
border-color: transparent;
background-color: transparent;
}
&:active {
color: mix($--color-black, $--color-primary, $--button-active-shade-percent);
border-color: transparent;
background-color: transparent;
}
}
複製代碼
gulp-sass
插件能實時監測scss
代碼檢查其語法錯誤並將其編譯成css
代碼,幫助開發人員檢查scss
語法的準確性,且其是否符合咱們的預期,相關配置以下:
gulp.task('gulpsass', function() {
return gulp.src('src/style/components/hwIcon.scss')
.pipe(gulpsass().on('error', gulpsass.logError))
.pipe(gulp.dest('src/style/dest'));
});
gulp.task('watch', function() {
gulp.watch('src/style/components/hwIcon.scss', ['gulpsass']);
});
複製代碼
咱們開發過程當中自定義的組件的名稱須要爲多個單詞,這樣作能夠避免跟現有的以及將來的HTML
元素相沖突,由於全部的 HTML
元素名稱都是單個單詞的。
推薦:
Vue.component('todo-item', {
// ...
})
export default {
name: 'TodoItem',
// ...
}複製代碼
不推薦:
Vue.component('todo', {
// ...
})
export default {
name: 'Todo',
// ...
}
複製代碼
當在組件中使用 data
屬性的時候 (除了 new Vue
外的任何地方),它的值必須是返回一個對象的函數。 由於若是直接是一個對象的話,子組件之間的屬性值會互相影響。
推薦:
export default {
data () {
return {
foo: 'bar'
}
}
}複製代碼
不推薦:
export default {
data: {
foo: 'bar'
}
}複製代碼
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
值。在組件上老是必須用 key
配合 v-for
,以便維護內部組件及其子樹的狀態。
推薦:
<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>複製代碼
組件名應該傾向於完整單詞而不是縮寫,編輯器中的自動補全已經讓書寫長命名的代價很是之低了,而其帶來的明確性倒是很是寶貴的。不經常使用的縮寫尤爲應該避免。
推薦:
components/
|- StudentDashboardSettings.vue
|- UserProfileOptions.vue 複製代碼
不推薦:
components/
|- SdSettings.vue
|- UProfOpts.vue 複製代碼
在 JavaScript
中,用多行分隔對象的多個屬性是很常見的最佳實踐,由於這樣更易讀。
推薦:
<MyComponent
foo="a"
bar="b"
baz="c"
/>複製代碼
不推薦:
<MyComponent foo="a" bar="b" baz="c"/> 複製代碼
組件模板應該只包含簡單的表達式,複雜的表達式則應該重構爲計算屬性或方法。複雜表達式會讓你的模板變得不那麼聲明式。咱們應該儘可能描述應該出現的是什麼,而非如何計算那個值。並且計算屬性和方法使得代碼能夠重用。
推薦:
<!-- 在模板中 -->
{{ 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:
和用 # 表示 v-slot:
)。
推薦:
<input
@input="onInput"
@focus="onFocus"
>複製代碼
不推薦:
<input
v-on:input="onInput"
@focus="onFocus"
>複製代碼
單文件組件應該老是讓標籤順序保持爲 <template> 、<script>、 <style> 。
推薦:
<!-- ComponentA.vue -->
<template>...</template>
<script>/* ... */</script>
<style>/* ... */</style>複製代碼
不推薦:
<!-- ComponentA.vue -->
<template>...</template>
<style>/* ... */</style>
<script>/* ... */</script>複製代碼
父子組件的通訊推薦使用 prop
和 emit
,而不是this.$parent
或改變 prop
;
兄弟組件之間的通訊推薦使用 EventBus(on)
,而不是濫用 vuex
;
祖孫組件之間的通訊推薦使用listeners
或 provide / inject
(依賴注入) ,而不是濫用 vuex
;
頁面跳轉,例如 A 頁面跳轉到 B 頁面,須要將 A 頁面的數據傳遞到 B 頁面,推薦使用 路由參數進行傳參,而不是將須要傳遞的數據保存 vuex,而後在 B 頁面取出 vuex的數據,由於若是在 B 頁面刷新會致使 vuex 數據丟失,致使 B 頁面沒法正常顯示數據。
推薦:
let id = ' 123';
this.$router.push({name: 'homeworkinfo', query: {id:id}}); 複製代碼
script
標籤內部的聲明順序以下:
data > prop > components > filter > computed > watch >
鉤子函數(鉤子函數按其執行順序)> methods複製代碼
(1)推薦使用計算屬性:計算屬性基於響應式依賴進行緩存,只在相關響應式依賴發生改變時它們纔會從新求值;相比之下,每次調用方法都會再次執行方法;
(2)推薦使用計算屬性:而不是根據 Watch
偵聽屬性,進行回調; 可是有計算屬性作不到的:當須要在數據變化時執行異步或開銷較大的操做時,偵聽器是最有用的。
v-if
是「真正」的條件渲染,由於它會確保在切換過程當中條件塊內的事件監聽器和子組件適當地被銷燬和重建。 v-if
也是惰性的:若是在初始渲染時條件爲假,則什麼也不作——直到條件第一次變爲真時,纔會開始渲染條件塊。
相比之下,v-show
就簡單得多——無論初始條件是什麼,元素老是會被渲染,而且只是簡單地基於 CSS
的屬性 display
進行切換。
推薦:
若是運行時,須要很是頻繁地切換,推薦使用 v-show
比較好;若是在運行時,條件不多改變,則推薦使用 v-if
比較好。
由於團隊如今使用 vue
框架,因此在項目開發中儘可能使用 vue
的特性去知足咱們的需求,儘可能(不到萬不得已)不要手動操做DOM
,包括:增刪改dom
元素、以及更改樣式、添加事件等。
不少時候有些代碼已經沒有用了,可是沒有及時去刪除,這樣致使代碼裏面包括不少註釋的代碼塊,好的習慣是提交代碼前記得刪除已經確認棄用的代碼,例如:一些調試的console
語句、無用的棄用代碼。
代碼註釋不是越多越好,保持必要的業務邏輯註釋,至於函數的用途、代碼邏輯等,要經過語義化的命令、簡單明瞭的代碼邏輯,來讓閱讀代碼的人快速看懂。
辛苦整理良久,若是對你有幫助,還望手動點贊鼓勵~~~~~~
github地址爲:github.com/fengshi123/…,若是喜歡或者有所啓發,請幫忙給個 star ~,對做者也是一種鼓勵。
一、clean-code-javascript
:github.com/ryanmcdermo…
二、SCSS
— 縮減50%的樣式代碼 : juejin.im/post/5c4888…
三、vue cookbook
:cn.vuejs.org/v2/cookbook…