Основано на официальном руководстве по стилю Vue.
1. Обязательное
1. Название компонента из нескольких слов
Имена компонентов всегда должны состоять из нескольких слов, за исключением корневого компонента App.
Положительный пример:
export default {
name: 'TodoItem',
// ...
}
Пример счетчика:
export default {
name: 'Todo',
// ...
}
2. Данные компонента
Данные компонента должны быть функцией.
При использовании свойства данных в компоненте (где угодно, кроме нового Vue) его значение должно быть функцией, возвращающей объект.
Положительный пример:
// In a .vue file
export default {
data () {
return {
foo: 'bar'
}
}
}
// 在一个 Vue 的根实例上直接使用对象是可以的,
// 因为只存在一个这样的实例。
new Vue({
data: {
foo: 'bar'
}
})
Пример счетчика:
export default {
data: {
foo: 'bar'
}
}
3. Определение реквизита
Определения реквизита должны быть как можно более подробными.
В коде, который вы отправляете, определение реквизита должно быть максимально подробным, по крайней мере, с указанием его типа.
Положительный пример:
props: {
status: String
}
// 更好的做法!
props: {
status: {
type: String,
required: true,
validator: function (value) {
return [
'syncing',
'synced',
'version-conflict',
'error'
].indexOf(value) !== -1
}
}
}
Пример счетчика:
// 这样做只有开发原型系统时可以接受
props: ['status']
4. Установите значение ключа для v-for
Всегда используйте ключ с v-for.
Ключ всегда должен использоваться с 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. Избегайте одновременного использования v-if и v-for
Никогда не используйте одновременно v-if и v-for для одного и того же элемента.
Как правило, мы склонны делать это в двух распространенных ситуациях:
- Для фильтрации элементов в списке (например, v-for="user in users" v-if="user.isActive"). В этом случае замените пользователей вычисляемым свойством (например, 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>
6. Стили компонентов области видимости
Стили в компонентах приложения верхнего уровня и компонентах макета могут быть глобальными для приложения, но все остальные компоненты должны иметь область действия.
Это правило актуально только для однофайловых компонентов. Вам не нужно использовать функцию ограниченной области. Настройка области также возможна с помощью модулей CSS, которые представляют собой стратегию, подобную БЭМ, основанную на классах, но вы также можете использовать другие библиотеки или соглашения.Несмотря на это, для библиотек компонентов мы должны предпочесть стратегии на основе классов, а не функции с областью действия.
Это упрощает переопределение внутренних стилей: используйте понятные человеку имена классов без слишком высокого приоритета селектора и с меньшей вероятностью вызовут конфликты.
Положительный пример:
<template>
<button class="c-Button c-Button--close">X</button>
</template>
<!-- 使用 BEM 约定 -->
<style>
.c-Button {
border: none;
border-radius: 2px;
}
.c-Button--close {
background-color: red;
}
</style>
Пример счетчика:
<template>
<button class="btn btn-close">X</button>
</template>
<style>
.btn-close {
background-color: red;
}
</style>
<template>
<button class="button button-close">X</button>
</template>
<!-- 使用 `scoped` 特性 -->
<style scoped>
.button {
border: none;
border-radius: 2px;
}
.button-close {
background-color: red;
}
</style>
2. Настоятельно рекомендуется (улучшенная читаемость)
1. Файл компонента
Пока существует система сборки, которая может объединять файлы, разделяйте каждый компонент на файлы.
Когда вам нужно отредактировать компонент или проверить использование компонента, вы можете найти его быстрее.
Положительный пример:
components/
|- TodoList.vue
|- TodoItem.vue
Пример счетчика:
Vue.component('TodoList', {
// ...
})
Vue.component('TodoItem', {
// ...
})
2. Случай однофайловых составных файлов
Имена файлов для однофайловых компонентов всегда должны начинаться с заглавной буквы (PascalCase).
Положительный пример:
components/
|- MyComponent.vue
Пример счетчика:
components/
|- myComponent.vue
|- mycomponent.vue
3. Название основного компонента
Все базовые компоненты, применяющие определенные стили и соглашения (то есть компоненты, представляющие классы, не имеющие логики или состояния), должны начинаться с определенного префикса, например Base, App или V.
Положительный пример:
components/
|- BaseButton.vue
|- BaseTable.vue
|- BaseIcon.vue
Пример счетчика:
components/
|- MyButton.vue
|- VueTable.vue
|- Icon.vue
4. Имя компонента синглтона
Компоненты, которые должны иметь только один активный экземпляр, должны называться с префиксом The для уникальности.
Это не означает, что компонент можно использовать только на одной странице, а только один раз на странице. Эти компоненты никогда не принимают никаких реквизитов, потому что они настроены для вашего приложения, а не для их контекста в вашем приложении. Если вы считаете необходимым добавить свойства, это означает, что на самом деле это повторно используемый компонент, который в настоящее время используется только один раз на странице.
Положительный пример:
components/
|- TheHeading.vue
|- TheSidebar.vue
Пример счетчика:
components/
|- Heading.vue
|- MySidebar.vue
5. Тесно связанные имена компонентов
Подкомпоненты, которые тесно связаны со своим родителем, должны называться с именем родителя в качестве префикса.
Если компонент имеет смысл только в контексте родительского компонента, эта связь должна быть отражена в его имени. Поскольку редакторы обычно упорядочивают файлы в алфавитном порядке, при этом связанные файлы сохраняются вместе.
Положительный пример:
components/
|- TodoList.vue
|- TodoListItem.vue
|- TodoListItemButton.vue
components/
|- SearchSidebar.vue
|- SearchSidebarNavigation.vue
Пример счетчика:
components/
|- SearchSidebar.vue
|- NavigationForSearchSidebar.vue
6. Порядок слов в названиях компонентов
Имена компонентов должны начинаться с высокоуровневого (обычно обобщенного) слова и заканчиваться описательным модификатором.
Положительный пример:
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
7. Регистр имени компонента в шаблонах
всегда PascalCase
Положительный пример:
<!-- 在单文件组件和字符串模板中 -->
<MyComponent/>
Пример счетчика:
<!-- 在单文件组件和字符串模板中 -->
<mycomponent/>
<!-- 在单文件组件和字符串模板中 -->
<myComponent/>
8. Полное имя компонента слова
В названиях компонентов следует отдавать предпочтение полным словам, а не аббревиатурам.
Положительный пример:
components/
|- StudentDashboardSettings.vue
|- UserProfileOptions.vue
Пример счетчика:
components/
|- SdSettings.vue
|- UProfOpts.vue
9. Элементы с несколькими свойствами
Элементы с несколькими атрибутами должны быть написаны на нескольких строках, по одной для каждого атрибута.
Положительный пример:
<img
src="https://vuejs.org/images/logo.png"
alt="Vue Logo"
>
<MyComponent
foo="a"
bar="b"
baz="c"
/>
Пример счетчика:
<img src="https://vuejs.org/images/logo.png" alt="Vue Logo">
<MyComponent foo="a" bar="b" baz="c"/>
10. Простые выражения в шаблонах
Шаблоны компонентов должны содержать только простые выражения, сложные выражения должны быть преобразованы в вычисляемые свойства или методы.
Сложные выражения делают ваши шаблоны менее декларативными. Вместо того, чтобы вычислить это значение, мы должны попытаться описать, что должно появиться. А вычисляемые свойства и методы позволяют повторно использовать код.
Положительный пример:
<!-- 在模板中 -->
{{ 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(' ')
}}
11. Простые вычисляемые свойства
Положительный пример:
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)
)
}
}
12. Значения атрибутов в кавычках
Непустые значения атрибутов HTML всегда должны быть заключены в кавычки (одинарные или двойные, в зависимости от того, что не используется в вашем JS).
Значения функций без пробелов можно оставить в HTML без кавычек, но это часто приводит к тому, что значения функций с пробелами избегают, что делает их менее читаемыми.
Положительный пример:
<AppSidebar :style="{ width: sidebarWidth + 'px' }">
Пример счетчика:
<AppSidebar :style={width:sidebarWidth+'px'}>
13. Сокращения инструкций
Оба используют сокращения инструкций (используйте : для v-bind: и @ для v-on:)
Положительный пример:
<input
@input="onInput"
@focus="onFocus"
>
Пример счетчика:
<input
v-bind:value="newTodoText"
:placeholder="newTodoInstructions"
>
3. Рекомендуется
1. Порядок элементов верхнего уровня однофайлового компонента
Однофайловые компоненты всегда должны иметь теги
Положительный пример:
<!-- ComponentA.vue -->
<template>...</template>
<script>/* ... */</script>
<style>/* ... */</style>
4. Используйте с осторожностью (потенциально опасный режим)
1. Не использовать ключ в v-if/v-if-else/v-else
Если набор v-if + v-else имеет один и тот же тип элемента, лучше использовать ключ (например, два элемента
).Положительный пример:
<div v-if="error" key="search-status" > 错误:{{ error }} </div> <div v-else key="search-results" > {{ results }} </div>
Пример счетчика:
<div v-if="error"> 错误:{{ error }} </div> <div v-else> {{ results }} </div>
2. Селекторы элементов в области видимости
Селекторов элементов следует избегать в области видимости.
В стиле с ограниченной областью действия селекторы классов предпочтительнее селекторов элементов, поскольку интенсивное использование селекторов элементов происходит медленно.Положительный пример:
<template> <button class="btn btn-close">X</button> </template> <style scoped> .btn-close { background-color: red; } </style>
Пример счетчика:
<template> <button>X</button> </template> <style scoped> button { background-color: red; } </style>
3. Неявная связь между родительскими и дочерними компонентами
Связь между родительским и дочерним компонентами должна осуществляться через реквизиты и события, а не this.$parent или изменение реквизитов.
Положительный пример:
Vue.component('TodoItem', { props: { todo: { type: Object, required: true } }, template: ` <input :value="todo.text" @input="$emit('input', $event.target.value)" > ` })
Пример счетчика:
Vue.component('TodoItem', { props: { todo: { type: Object, required: true } }, methods: { removeTodo () { var vm = this vm.$parent.todos = vm.$parent.todos.filter(function (todo) { return todo.id !== vm.todo.id }) } }, template: ` <span> {{ todo.text }} <button @click="removeTodo"> X </button> </span> ` })
4. Глобальное управление состоянием без Flux
Глобальным состоянием следует управлять через Vuex, а не через this.$root или глобальную шину событий.
Положительный пример:
// store/modules/todos.js export default { state: { list: [] }, mutations: { REMOVE_TODO (state, todoId) { state.list = state.list.filter(todo => todo.id !== todoId) } }, actions: { removeTodo ({ commit, state }, todo) { commit('REMOVE_TODO', todo.id) } } } <!-- TodoItem.vue --> <template> <span> {{ todo.text }} <button @click="removeTodo(todo)"> X </button> </span> </template> <script> import { mapActions } from 'vuex' export default { props: { todo: { type: Object, required: true } }, methods: mapActions(['removeTodo']) } </script>
Пример счетчика:
// main.js new Vue({ data: { todos: [] }, created: function () { this.$on('remove-todo', this.removeTodo) }, methods: { removeTodo: function (todo) { var todoIdToRemove = todo.id this.todos = this.todos.filter(function (todo) { return todo.id !== todoIdToRemove }) } } })
приложение
1. Рекомендуется использовать vs code для внешнего кодирования, а размер Tab указан как 2 пробела.
- против конфигурации кода
{ "editor.tabSize": 2, "workbench.startupEditor": "newUntitledFile", "workbench.iconTheme": "vscode-icons", // 以下为stylus配置 "stylusSupremacy.insertColons": false, // 是否插入冒号 "stylusSupremacy.insertSemicolons": false, // 是否插入分好 "stylusSupremacy.insertBraces": false, // 是否插入大括号 "stylusSupremacy.insertNewLineAroundImports": false, // import之后是否换行 "stylusSupremacy.insertNewLineAroundBlocks": false, // 两个选择器中是否换行 "vetur.format.defaultFormatter.html": "js-beautify-html", "eslint.autoFixOnSave": true, "eslint.validate": [ "javascript", { "language": "html", "autoFix": true }, { "language": "vue", "autoFix": true }, "javascriptreact", "html", "vue" ], "eslint.options": { "plugins": ["html"] }, "prettier.singleQuote": true, "prettier.semi": false, "javascript.format.insertSpaceBeforeFunctionParenthesis": false, "vetur.format.js.InsertSpaceBeforeFunctionParenthesis": false, "vetur.format.defaultFormatter.js": "prettier", // "prettier.eslintIntegration": true }
- против плагина кода
- Auto Close Tag
- Path Intellisense
- Prettier
- Vetur
- vscode-icons