Игорь Шестухин

1. Незакрытые подписки
При монтировании компонента подписываться на событие scroll — частая практика. Но забыть отписаться при размонтировании — тоже. С каждым новым экземпляром количество обработчиков будет расти, память — утекать.
Решение:
Использовать onUnmounted для удаления слушателя. Либо выносить логику в композабл, где подписка и отписка находятся рядом.
2. Игнорирование TypeScript
В проектах без строгой типизации ref() часто остаётся unknown или any. Это снижает качество автодополнения и провоцирует ошибки.
Решение:
Всегда передавать дженерик: const count = ref<number>(0). То же касается defineProps и defineEmits.
3. Дублирование логики
Копирование одного и того же кода (работа с окном, localStorage, API) в разные компоненты — путь к хаосу.
Решение:
Создавать composables. Функция useScroll, возвращающая scrollY, может использоваться в любом месте приложения. Код становится модульным и тестируемым.
4. Нетипизированные события
Массив строк в defineEmits(['cancel', 'increase']) — плохая практика. Нет контроля над передаваемыми параметрами.
Решение:
Использовать объектную форму с дженериком:
const emit = defineEmits<{
cancel: []
increase: [value: number]
}>()
Теперь emit('increase', 'string') вызовет ошибку типа.
5. Глобальный стор без декомпозиции
Складывать всё состояние приложения в один Pinia‑стор — удобно в начале, но через полгода файл превращается в «свалку».
Решение:
Разделять сторы по доменам: postStore, userStore, notificationStore. Каждый отвечает только за свою зону ответственности.
6. Глобальная регистрация компонентов
app.component('DemoScroll', DemoScroll) выглядит удобно — не нужно импортировать. Но это убивает tree‑shaking: даже неиспользуемые компоненты попадают в бандл.
Решение:
Импортировать компоненты локально там, где они реально нужны. Только так можно гарантировать оптимизацию сборки.
7. Деструктуризация реактивных данных
const { posts } = usePostStore() — после этой строки posts теряет реактивность. Изменения в сторе не вызовут обновление компонента.
Решение:
Использовать storeToRefs для извлечения реактивных ссылок или обращаться через точку: store.posts.
Исключение:
С версии 3.5 в defineProps разрешена деструктуризация с дефолтными значениями — это безопасно.
Итог
Качественный код на Vue строится на трёх китах: типизация, декомпозиция и следование лучшим практикам. Отказ от глобальных регистраций, грамотная работа с композаблами и правильное использование Pinia превращают хаотичный проект в предсказуемую и масштабируемую систему.



Комментарии
0