предисловие
У фронтенд-команды есть требования к проверке кода, но из-за разного уровня каждого разработчика и различных технических проблем фокус проверки кода отличается.Чтобы обеспечить унификацию качества кода и стиля кода команды, Настоящим составляется «Кодекс команды переднего плана». Контрольный список проверки», чтобы рецензенты кода могли обращаться к этому списку для проверки кода при просмотре кода. Тем самым помогая всей команде улучшить качество кода и унифицировать спецификации кода. Если у вашей команды еще нет такого контрольного списка проверки кода, возможно, это то, что вам нужно; если у вашей команды уже есть тесты проверки кода, этот список может быть вишенкой на торте.
Я много работал над организацией в течение долгого времени, и я надеюсь вручную поставить лайк и поощрить ~
Адрес гитхаба:GitHub.com/ревматизм123/…, если вам нравится или у вас есть вдохновение, пожалуйста, помогите поставить звезду ~, что также является поощрением для автора.
1. Инструмент статической проверки кода
1.1. Используйте инструмент eslint для проверки кода javascript
eslint
Спецификация чека наследуется от eslint-config-standard
Правила осмотра, введение конкретных правил смотрите по ссылке:cn.eslint.org/docs/rules/, эти правила проверки не будут повторяться здесь и в следующих разделах.
1.2 Используйте инструмент stylelint для проверки кода стиля css
stylelint
Спецификация чека наследуется отstylelint-config-standard
Правила осмотра, введение конкретных правил смотрите по ссылке:Woohoo. Эта лошадь Plus.com/package/basking…, эти правила проверки не будут повторяться здесь и в следующих разделах.
Во-вторых, соглашение об именах
2.1, JS принимает название Camel Case для малых верблюдов.
рекомендовать:
studentInfot
2.2. Избегайте дублирования имен
рекомендовать:
const Car = {
make: "Honda",
model: "Accord",
color: "Blue"
};
Не рекомендуется:
const Car = {
carMake: "Honda",
carModel: "Accord",
carColor: "Blue"
};
2.3 Имя класса CSS соответствует соглашению об именовании БЭМ.
рекомендовать:
.block__element{}
.block--modifier{}
2.4 Именование соответствует семантике
Именование должно соответствовать семантике.Если функция названа, перед ней может стоять глагол:
глагол | имея в виду |
---|---|
can | Определить, может ли действие быть выполнено |
has | определить, содержит ли оно значение |
is | определить, является ли это значением |
get | получить значение |
set | установить значение |
рекомендовать:
//是否可阅读
function canRead(){
return true;
}
//获取姓名
function getName{
return this.name
}
3. Рекомендуемый метод написания JS
3.1 Каждая константа должна быть названа
Каждая константа должна быть названа, иначе люди, глядя на код, не будут знать, что означает константа.
рекомендовать:
const COL_NUM = 10;
let row = Math.ceil(num/COL_NUM);
Не рекомендуется:
let row = Math.ceil(num/10);
3.2 Рекомендуется использовать литералы
Использование литералов рекомендуется для создания объектов и массивов, так как это не только обеспечивает лучшую производительность, но и помогает сэкономить код.
рекомендовать:
let obj = {
name:'tom',
age:15,
sex:'男'
}
Не рекомендуется:
let obj = {};
obj.name = 'tom';
obj.age = 15;
obj.sex = '男';
3.3, рекомендуемый метод записи свойств объекта по умолчанию
рекомендовать:
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);
3.4 Сохранить значение свойства объекта как локальную переменную
Чем глубже вложенность членов объекта, тем ниже скорость чтения. Итак, хорошее эмпирическое правило: если вам нужно прочитать свойство объекта несколько раз в функции, лучше всего сохранить значение свойства в локальной переменной, чтобы избежать накладных расходов на производительность при многократном поиске.
рекомендовать:
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)
}
}
3.5 Преобразование строки в целое число
Когда вам нужно преобразовать число с плавающей запятой в целое число, вы должны использоватьMath.floor()
илиMath.round()
, Вместо того, чтобы использоватьparseInt()
Преобразование строки в число.Math 是内部对象,所以
Math.floor()
На самом деле методов запросов и времени вызова не много, а скорость самая быстрая.
рекомендовать:
let num = Math.floor('1.6');
Не рекомендуется:
let num = parseInt('1.6');
3.6, функциональные параметры
Чем меньше параметров функции, тем лучше.Если параметров больше двух, используйтеES6
синтаксис деструктурирования, независимо от порядка аргументов.
рекомендовать:
function createMenu({ title, body, buttonText, cancellable }) {
// ...
}
createMenu({
title: 'Foo',
body: 'Bar',
buttonText: 'Baz',
cancellable: true
});
Не рекомендуется:
function createMenu(title, body, buttonText, cancellable) {
// ...
}
3.7. Используйте значения параметров по умолчанию
Вместо этого используйте значение параметра по умолчанию. Используйте условный оператор для назначения.
рекомендовать:
function createMicrobrewery(name = "Hipster Brew Co.") {
// ...
}
Не рекомендуется:
function createMicrobrewery(name) {
const breweryName = name || "Hipster Brew Co.";
// ...
}
3.8 Критерий минимальной функции
Это давнее правило в программной инженерии. Строгое следование этому правилу сделает ваш код более читабельным и простым для рефакторинга. Если это правило будет нарушено, код будет сложно протестировать или использовать повторно.
3.9 Не пишите глобальные методы
существует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));
};
3.10 Рекомендовать функциональное программирование
Функциональное программирование переменных может сделать логику кода более понятной, элегантной и простой для тестирования.
рекомендовать:
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;
}
3.11. Используйте полиморфизм для замены условных операторов
Для того, чтобы сделать код более лаконичным и читабельным, если в вашей функции есть условное суждение, это означает, что ваша функция делает больше чем одну вещь, нарушая принцип единственной функции, и большинство сценариев можно заменить полиморфизмом.
рекомендовать:
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();
}
}
}
3.12. Сброшен ли таймер
Таймер используется в кодеsetTimeout
а такжеsetInterval
, который необходимо очищать, когда он не используется.
В-четвертых, SCSS рекомендовал писать
4.1 Использование переменной $
использоватьscss
В переменной конфигурации цвет и размер шрифта проекта могут быть изменены единообразно (скин), что способствует поддержанию более позднего проекта.
рекомендовать:
$--color-success: #67C23A;
$--color-warning: #E6A23C;
$--color-danger: #F56C6C;
$--color-info: #909399;
4.2, файл стиля импорта @import
scss
середина@import
правила генерируютсяcss
При импорте файла импортируются соответствующие файлы. Это означает, что все связанные стили сгруппированы в один и тот жеcss
Файл без инициирования дополнительного запроса загрузки, который рекомендуется при создании собственной библиотеки компонентов.
@import "./base.scss";
@import "./pagination.scss";
@import "./dialog.scss";
@import "./autocomplete.scss";
@import "./dropdown.scss";
@import "./dropdown-menu.scss";
4.3, использование локального именования файлов
scss
Имя частичного файла начинается со знака подчеркивания. так,scss
не будет компилировать вывод этого файла отдельно во время компиляцииcss
, и использовать этот файл только как импорт.
рекомендовать:
4.4 Идентификатор родительского селектора и реализация спецификации команды БЭМ
scss
Идентификаторы вложенных и родительских селекторов могут быть разрешеныBEM
Имена являются подробными и делают стили более читабельными.
рекомендовать:
.el-input {
display: block;
&__inner {
text-align: center;
}
}
4.5 Использование микшера @mixin
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);
}
4.6 Использование директивы @extend
(1) Использование@extend
производитьDRY CSSСтилизованный код (не повторяйтесь)
(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;
}
4.7, использование интерполяции #{}
Интерполяция может динамически определять имя класса. Когда есть две страницы с похожими стилями, мы будем извлекать похожие стили в микшеры страниц, но имена двух разных стилей страниц основаны на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;
}
}
}
4.8, каждый обход, тип данных карты, микшер @mixin/@include, комбинированное использование интерполяции #{}
доступный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);
}
}
4.9 Применение функций scss
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;
}
}
4.10, использование gulp-sass
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']);
});
5. Рекомендуемый метод написания Vue
5.1 Названия компонентов из нескольких слов
Имя пользовательского компонента в нашем процессе разработки должно состоять из нескольких слов, чтобы избежать существующих и будущихHTML
элементы сталкиваются, потому что всеHTML
Имена элементов состоят из одного слова.
рекомендовать:
Vue.component('todo-item', {
// ...
})
export default {
name: 'TodoItem',
// ...
}
Не рекомендуется:
Vue.component('todo', {
// ...
})
export default {
name: 'Todo',
// ...
}
5.2 Данные компонента должны быть функцией
при использовании в компонентеdata
атрибут (кромеnew Vue
где-нибудь снаружи), его значение должно быть функцией, возвращающей объект. Потому что, если это объект напрямую, значения свойств между подкомпонентами будут влиять друг на друга.
рекомендовать:
export default {
data () {
return {
foo: 'bar'
}
}
}
Не рекомендуется:
export default {
data: {
foo: 'bar'
}
}
5.3. Определение реквизита должно быть максимально подробным.
prop
Определение должно быть максимально подробным, хотя бы с указанием его типа.
рекомендовать:
props: {
status: String
}
// 更好的做法!
props: {
status: {
type: String,
required: true,
validator: function (value) {
return [
'syncing',
'synced',
'version-conflict',
'error'
].indexOf(value) !== -1
}
}
}
Не рекомендуется:
props: ['status']
5.4 Установите значение ключа для v-for
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>
5.5 Названия компонентов полных слов
В именах компонентов следует отдавать предпочтение полным словам, а не аббревиатурам, автодополнение в редакторах сделало написание длинных имен очень дешевым, а ясность, которую оно дает, бесценна. Особенно следует избегать сокращений, которые обычно не используются.
рекомендовать:
components/
|- StudentDashboardSettings.vue
|- UserProfileOptions.vue
Не рекомендуется:
components/
|- SdSettings.vue
|- UProfOpts.vue
5.6 Каждая характерная линия из нескольких характерных элементов
существуетJavaScript
, рекомендуется разделять несколько свойств объекта на несколько строк, поскольку это легче читать.
рекомендовать:
<MyComponent
foo="a"
bar="b"
baz="c"
/>
Не рекомендуется:
<MyComponent foo="a" bar="b" baz="c"/>
5.7 Простые выражения в шаблонах
Шаблоны компонентов должны содержать только простые выражения, сложные выражения должны быть преобразованы в вычисляемые свойства или методы. Сложные выражения делают ваши шаблоны менее декларативными. Вместо того, чтобы вычислить это значение, мы должны попытаться описать, что должно появиться. А вычисляемые свойства и методы позволяют повторно использовать код.
рекомендовать:
<!-- 在模板中 -->
{{ 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(' ')
}}
5.8 Простые вычисляемые свойства
Сложные вычисляемые свойства должны быть разбиты на как можно больше простых свойств.
рекомендовать:
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)
)
}
}
5.9 Сокращения инструкций
В инструкциях рекомендуется использовать сокращенную форму (используйте : для обозначения v-bind:
, представлена @ v-on:
и обозначается #v-slot:
).
рекомендовать:
<input
@input="onInput"
@focus="onFocus"
>
Не рекомендуется:
<input
v-on:input="onInput"
@focus="onFocus"
>
5.10. Поддерживайте постоянный порядок этикеток
Однофайловые компоненты всегда должны сохранять порядок тегов ,
рекомендовать:
<!-- ComponentA.vue -->
<template>...</template>
<script>/* ... */</script>
<style>/* ... */</style>
Не рекомендуется:
<!-- ComponentA.vue -->
<template>...</template>
<style>/* ... */</style>
<script>/* ... */</script>
5.11 Связь между компонентами
Рекомендуется связь между родительским и дочерним компонентами.prop
а такжеemit
, вместоthis.$parent
или изменитьprop
;
Рекомендуется связь между родственными компонентамиEventBus(on)
, а не злоупотреблятьvuex
;
Рекомендуется связь между компонентами-внуками.listeners
или provide / inject
(инъекция зависимости), а не злоупотреблениеvuex
;
5.12, доставка данных о переходе на страницу
Переход на страницу, переход на страницу, например, страницу A B, страница должна передавать данные на страницу B. Рекомендуемые параметры передачи параметров маршрута, а не необходимость передавать хранилище данных vuex, а затем удалять данные vuex на странице B, потому что, если страница B vuex обновления могут привести к потере данных, в результате чего на странице B данные не отображаются должным образом.
рекомендовать:
let id = ' 123';
this.$router.push({name: 'homeworkinfo', query: {id:id}});
5.13 Внутренний порядок объявления тегов сценария
script
Порядок объявления внутри тега следующий:
data > prop > components > filter > computed > watch >
钩子函数(钩子函数按其执行顺序)> methods
5.14 Вычисляемые свойства, методы и слушатели
(1) рекомендуется использовать вычисляемые свойства: вычисляемые свойства кэшируются на основе реактивных зависимостей и переоцениваются только при изменении соответствующих реактивных зависимостей; напротив, метод выполняется снова каждый раз при вызове метода;
(2) Рекомендуются вычисляемые свойства: вместо
Watch
Слушайте свойства, делайте обратные вызовы, но есть вещи, которые вычисляемые свойства делать не могут: прослушиватели наиболее полезны, когда вам нужно выполнять асинхронные или дорогостоящие операции при изменении данных.
5.15. v-if VS v-show
v-if
является «настоящим» условным рендерингом, поскольку он гарантирует, что прослушиватели событий и дочерние компоненты внутри условного блока будут правильно уничтожены и перестроены во время перехода.v-if
Также лениво: если условие ложно при начальном рендеринге, ничего не делать - условный блок не начнет рендеринг, пока условие не станет истинным в первый раз.Напротив,
v-show
намного проще - элемент всегда рендерится вне зависимости от начальных условий, и просто основывается наCSS
свойстваdisplay
переключить.
рекомендовать:
Если среда выполнения должна переключаться очень часто, рекомендуется использоватьv-show
Лучше; рекомендуется, если условия редко меняются во время выполненияv-if
Лучше.
6. Другие нормы команды
6.1 Старайтесь не манипулировать DOM вручную
Поскольку теперь команда используетvue
Framework, так что попробуйте использовать его в разработке проектовvue
Особенности для удовлетворения наших потребностей, старайтесь не работать вручнуюDOM
, в том числе: дополнения, удаления и измененияdom
элементы, а также изменение стилей, добавление событий и т.д.
6.2. Удалить устаревший код
Много раз какой-то код больше не нужен, но он не удаляется вовремя, что приводит к большому количеству закомментированных блоков кода в коде.Хорошая привычка - не забывать удалять код, который был подтвержден как устаревший, перед отправкой код, например: некоторая отладкаconsole
Утверждения, бесполезный устаревший код.
6.3, для ведения необходимых примечаний
Чем больше комментариев к коду, тем лучше. Сохраняйте необходимые комментарии по бизнес-логике. Что касается назначения функций, логики кода и т. д., вы должны использовать семантические команды и простую и понятную логику кода, чтобы люди, читающие код, быстро поняли.
Это было трудно организовать в течение долгого времени. Если это было полезно для вас, я надеюсь вручную лайкнуть и поощрить ~~~~~~
Адрес гитхаба:GitHub.com/ревматизм123/…, если вам нравится или у вас есть вдохновение, пожалуйста, помогите поставить звезду ~, что также является поощрением для автора.
использованная литература
1,clean-code-javascript
:GitHub.com/Eardrum невооруженным глазом…
2,SCSS
— Уменьшен код стиля на 50%:nuggets.capable/post/684490…
3.vue cookbook
:Talent.v UE JS.org/V2/cookbook…