- Минимальные требования перед запуском проекта
- Используемый стек
- Code style
- Структура проекта
- Работа с API
- Работа с формами
- Комментирование кода
- Команды
- Рекомендации
Ознакомиться с используемым стеком, хотя бы частично.
Установить минимальную версию Node.js: v21.7.3 (LTS)
Установить минимальную версию npm: v10.5.0 (Latest)
- Фреймворк - nuxt 3 @^3.12.4
- Глобальное хранилище - @pinia/nuxt @^0.5.1
- Ui библиотека - shadcn-nuxt @^0.10.4
- Препроцессор - SASS @^1.77.8
- Валидация - "@vuelidate/core": "^2.0.3", "@vuelidate/validators": "^2.0.4",,
По всей компании придерживаемся стиля Allman для размещения фигурных скобок.
В стиле Allman открывающая фигурная скобка размещается на новой строке, выровненная с началом управляющей структуры. Важно: Избегаем фигурные скобки, если внутри только одна строка кода (касается if, for, while и других конструкций).
// Функции
function calculateTotal(items)
{
let total = 0;
for (let i = 0; i < items.length; i++)
total += items[i].price;
return total;
}
function validateUser(user)
{
if (!user.email)
throw new Error('Email is required');
return true;
}
// Условные операторы
if (user.isAuthenticated)
{
console.log('Пользователь авторизован');
if (user.hasPermission('admin'))
showAdminPanel();
}
else
redirectToLogin();
// Циклы
for (let i = 0; i < array.length; i++)
{
if (array[i].isValid)
processItem(array[i]);
}
// Дополнительные примеры без фигурных скобок
while (condition)
doSomething();
// Объекты и классы
const userConfig =
{
name: 'John Doe',
email: '[email protected]',
settings:
{
theme: 'dark',
notifications: true
}
};- Папки → kebab-case (например:
user-profile/,news-list/) - Файлы (кроме компонентов) → kebab-case (например:
user-service.js,api-utils.js) - Компоненты → PascalCase (например:
UserCard.vue,NewsList.vue)
- Формат названий функций и переменных - camelCase
- Формат названий констант - SCREAM_CASE
- Формат названий CSS селекторов - БЭМ
- Используем табуляцию табами - размер 4 пробела
- Консистентность отступов - все файлы должны использовать одинаковые отступы
- Настройка редактора - смотреть файл
.editorconfigдля VSCode в./.vscode/settings.jsonдля того чтобы редактор не подставлял что-то другое - Внутри тегов
<script>,<template>и<style>весь код должен быть отступлен на один таб от начала строки - Это обеспечивает четкую визуальную иерархию и улучшает читаемость кода
Примечание: В примере ниже используются настоящие табы размером в 4 пробела
<template>
<div class="user-card">
<div class="user-card__header">
<img class="user-card__avatar" src="avatar.jpg" alt="Avatar">
<h2 class="user-card__title">Иван Иванов</h2>
</div>
<div class="user-card__content">
<p>Описание пользователя...</p>
</div>
</div>
</template>
<script>
export default {
name: 'UserCard',
props:
{
user:
{
type: Object,
required: true
}
},
computed:
{
fullName()
{
return `${this.user.firstName} ${this.user.lastName}`
}
}
}
</script>
<style scoped>
.user-card
{
padding: 20px;
border: 1px solid #ccc;
}
.user-card__header
{
display: flex;
align-items: center;
margin-bottom: 15px;
}
</style>- Используем наименование по BEM - block__element--modifier
- Избегаем
&в стилях с целью увеличения читаемости и удобства поиска нужных классов - Стандартные теги внутри BEM элементов - можно иногда пропускать установку им классов и напрямую указывать стили для этих элементов (но не глобально)
- Классы в HTML компонента - только по БЭМ либо глобальные классы с префиксом
g- - Именование компонентов - если компонент в папке
components/Blog/Card.vue, то именовать надоblog-card, а подключение<BlogCard />
// Блок
.user-card {
padding: 20px;
border: 1px solid #ccc;
}
// Элементы
.user-card__header {
display: flex;
align-items: center;
margin-bottom: 15px;
}
.user-card__avatar {
width: 50px;
height: 50px;
border-radius: 50%;
}
// Модификаторы
.user-card--featured {
border-color: #007bff;
background-color: #f8f9fa;
}
.user-card--featured .user-card__title {
color: #007bff;
}
// Глобальные классы с префиксом g- эти стили писать не в компонентах конечно
.g-container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
.g-button {
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
}<template>
<div class="user-card user-card--featured">
<div class="user-card__header">
<img class="user-card__avatar" src="avatar.jpg" alt="Avatar">
<h2 class="user-card__title">Иван Иванов</h2>
</div>
<div class="user-card__content">
<p>Описание пользователя...</p>
<!-- Стандартные теги без классов -->
<h3>Дополнительная информация</h3>
<p>Еще один параграф</p>
</div>
</div>
</template>В этом разделе будет подробно (по возможности) описана структура проекта, чтобы не возникало вопросов, что, где и почему Общая структура проекта будет выглядеть следующим образом:
Корень проекта /
| - api
| - assets
| - components
| - composables
| - layouts
| - pages
| - plugins
| - public
| - server
| - utils
| - assets/
| |- fonts/.
| |- styles/;
| |- base/;
| |- index.scss;
| |- tailwind.css;
Дальше разберем каждую по отдельности
В данной директории будут находиться функции-запросы, разделенные по модулям, т.е. модуль авторизации (auth.js), модуль работы с пользователем (user.js) и т.д.
Это поможет нам скомпоновать идентичные запросы в одном месте и избавит нас от дублирования одинаковых запросов.
❗Исключением является запрос, который существует конкретно на одной странице и в одном месте, тогда создание модуля избыточно.
В данной директории будут находиться стили, которые доступны всему проекту
Тут должны быть ваши шрифты
styles/
|
|- base/
| |- _fonts.scss // Ваши шрифты
| |- _global.scss // Возможно повторяющиеся стили по всему проекту
| |- _mixins.scss // Миксины для упрощения вашей жизни
| |- _variables.scss // SCSS переменные
|
- index.scss // Главный SCSS файл
В данной директории находятся все переиспользуемые компоненты приложения. Рекомендуется группировать компоненты по функциональности в отдельные папки (например: components/User/, components/News/, components/Forms/). Это улучшает навигацию по коду и упрощает поддержку проекта. Каждая папка может содержать основной компонент и связанные с ним подкомпоненты.
- Название компонентов: используем PascalCase (например:
UserCard.vue,NewsList.vue) - Язык: пока что избегаем TypeScript, пишем на JavaScript
- Работа с DOM: избегаем прямого обращения к DOM элементам
- Подход: работаем через стандартные методы Vue и работу через Virtual DOM
Тут будут лежать все ваши компоненты компоненты
Тут будут лежать компоненты от shadcn-ui
В данной директории будут находиться все функциональные компоненты. Каждый файл обязательно должен называться с приставки use-.
В данной директории будут находиться все ваши страницы.
В данной директории будут находиться все ваши сторонние (или кастомные) плагины.
В данной директории будут находиться фав-иконки и различные изображения.
В данной директории будут находиться все служебных функции, например:
- formatPrice.js - функция для отображения цены в RU формате
В данной директории будут храниться тесты, например:
- tests/utils/formatPrice.js - тест для утилса utils/formatPrice.js
Для отправки серверных запросов используем кастомный useRequest, основанный на useFetch,
для отправки клиентских запросов используем useClientRequest, основанный на $fetch, в чем разница серверных/клиентских запросов
можно ознакомить на странице официальной документации Nuxt.
Если вкратце, то клиентские запросы - это обычные, всем нам известные запросы, которые мы использовали во Vue 3,
Vue 2, React и т.д., они выполняются на стороне клиента, либо при монтировании страницы, либо при взаимодействии
с пользователем. Серверные же запросы, исходя из названия выполняются еще на стороне сервера, еще до монтирования страницы,
но во время гидрации (или регидрации - это одно и тоже), сделано это для того,
чтобы у пользователя не было ситуации, где данных еще нет, ему в любом случае уже придет готовый html
Вы можете ознакомиться с ним открыв файл: pages/api.vue
В каких случаях требуется комментирование кода:
- Объяснение цели или назначения определенного блока кода, если она не очевидна.
- Описание сложных алгоритмов или логики, которые могут быть сложно понятны для других разработчиков.
- Указание на предполагаемые ошибки или проблемы, которые могут возникнуть в коде.
- Описание намерений или целей разработчика при написании определенного фрагмента кода, если она не очевидна.
- Комментирование важных или критических частей кода для обеспечения понимания других разработчиков.
Пример, когда не стоит писать комментарий ❌:
// Это объект, который представляет пользователя
const user = {
name: "John Doe",
age: 30,
email: "[email protected]"
};// Функция для суммирования чисел
const add = (a, b) => a + b;Но если мы создали utils, который помогает нам с суммированием, то описываем его следующим образом:
/**
* Функция для суммирования двух чисел.
* @param a - Первое число для суммирования.
* @param b - Второе число для суммирования.
* @return {number} Сумма двух чисел.
*/
const add = (a, b) => {
return a + b;
}Вы можете ознакомиться с ним открыв файл: pages/form.vue
Вы можете ознакомиться с ним открыв файл: pages/pinia.vue
- Функциональные изменения или добавление новых фич.
- Для бизнес-логики: (расчёты, фильтры, сортировка, валидация форм и прочее)
- Регрессия: Если ранее работавшая функциональность неожиданно выходит из строя, то его нужно покрывать тестами
- Цепочка действий компонентов: будет полезно написать тест для последовательного выполнения цепочки действий, например: есть форма с несколькими шагами и возможными различными исходами.
describe
Метод describe нужен для группировки связанных тестов.
test и it
Метод test / it используется для создания и определения отдельного теста. Он принимает два аргумента:
-
Первый аргумент — строка, описывающая, что именно проверяется в тесте. Это название теста, которое помогает понять, какой функционал тестируется.
-
Второй аргумент — функция, которая содержит код, выполняющий проверку (или сам тест). В этой функции обычно используется один или несколько методов для проверки утверждений.
test и it это практически идентичные функции, разница только в названии. Испоьзуется в связке с describe для лучшей читаемости.
expect
-
Проверять соответствие значений ожидаемому результату
-
Тестировать различные условия
-
Выводить понятные сообщения об ошибках
Основыные проверки:
-
.toBe() - строгое сравнение (===)
-
.toEqual() - глубокое сравнение объектов
-
.toBeTruthy()</span> - проверка на true
-
.toBeFalsy() - проверка на false
-
.toContain()</span> - проверка наличия в массиве
-
.toThrow() - проверка на ошибку
Настройка тестовой среды с использованием Pinia
import { setActivePinia, createPinia } from 'pinia';
import { user } from '@/stores/user';
describe('User Store', () => {
beforeEach(() => {
// Создаем новое хранилище перед каждым тестом
setActivePinia(createPinia());
});
});- Документация vitest - https://vitest.dev/
- Гайд от накста по тестам - https://nuxt.com/docs/getting-started/testing
- Тот же гайд от накста, но на русском - https://nuxt-ru.vercel.app/docs/getting-started/testing
- Видеогайд по тестом ( на английском ) - https://www.youtube.com/watch?v=yGzwk9xi9gU
Обязательно установите зависимости:
npm installЗапустите сервер разработки на http://localhost:3000 (если не занят):
npm run devСборка для продакшена:
npm run buildЛокальный предварительный просмотр сборки:
npm run previewДля получения дополнительной информации ознакомьтесь с документацией по развертыванию.
маска: https://beholdr.github.io/maska/v3/ нотификации: https://www.npmjs.com/package/vue-toast-notification
- Если вам нужно использовать слайдер на проекте: https://swiperjs.com/
- Если вам нужно использовать click-outside и другие приколы используйте: https://vueuse.org/
- Если вы не можете разобраться с grid сеткой: https://cssgrid-generator.netlify.app/
- Если вы не можете разобраться с flex сеткой: https://angrytools.com/css-flex/
- Если вам нужно конвертнуть фавиконку: https://favicon.io/favicon-converter/
- Если вам нужно конвертнуть шрифты: https://transfonter.org/