javascript

Vue 2 в 2025: какие паттерны стоит забыть, а какие – оставить

  • пятница, 18 июля 2025 г. в 00:00:06
https://habr.com/ru/articles/928578/

Коротко расскажу о себе. С 2017 года начал заниматься обычной HTML версткой с амбициями на веб-программирование. Набираясь опыта, стал писать все более сложные проекты для e-commers. В 2020 году устроился фронтенд разработчиком Цифровые сервисы (входит в цифровой сабхолдинг РЖД-Технологии). Мы занимаемся импортозамещением иностранных сервисов и разработкой собственных решений автоматизации. Проект, которым я занимаюсь в течении пяти лет, автоматизирует процессы стратегического управления данными (Data Governance) на предприятии.

На старте данного проекта, взвесив все плюсы и минусы, принял решение использовать Vue 2 на фронтенде.

Ключевыми особенностями выбора стали:

  • Простота и низкий порог входа. VueJS в освоении легче чем Angular. Vue предлагал готовую структуру (шаблоны, директивы, роутинг, стейт-менеджмент), тогда как React требовал выбора библиотек (Redux/MobX, React Router и т. д.).

  • Реактивность «из коробки». В отличие от React, где нужно явно использовать useState/setState, Vue 2 автоматически отслеживал изменения данных через data() и обновлял DOM.

  • Высокая производительность. VueJS использовал для рендеринга Virtual DOM (как у React), но с оптимизациями для минимизации перерисовок. Так же, сократился размер бандла (~20 КБ в сжатом виде) против Angular (~50-100 КБ) и React (~40 КБ + библиотеки).

  • Экосистема и документация. Официальные библиотеки (Vuex, Vue Router) были хорошо интегрированы и документированы. Документация Vue считалась одной из лучших среди фреймворков.

  • Гибкость архитектуры. В отличие от Angular, не было жесткого требования к структуре проекта.

Vue 2 в 2025 году официально стал legacy, но множество проектов всё ещё работают на нём. Миграция на Vue 3 не всегда возможна сразу, поэтому важно правильно поддерживать и модернизировать старый код.

В этой статье разберём:

  • Устаревшие паттерны, от которых лучше избавиться.

  • Проверенные подходы, которые остаются актуальными.

  • Альтернативы из Vue 3, которые можно адаптировать уже сейчас

Паттерны, которые стоит забыть

1. Использование EventBus для глобальной коммуникации

Раньше EventBus (часто на основе new Vue()) использовали для обмена данными между компонентами без явной передачи пропсов.

Проблемы:

  • Сложно отслеживать поток событий.

  • Легко получить "мусорные" слушатели (memory leaks).

  • Плохая типизация (если используется TypeScript).

Современная альтернатива:

  • Vuex/Pinia — во Vue 2 лучше использовать Vuex для сложного стейта.

  • Provide/Inject — если нужно передавать данные глубоко по иерархии.

  • Composition API – общая логика в setup()

// Устаревший подход  
const bus = new Vue()

// Отправка события  
bus.$emit('user-updated', { id: 1 })

// Подписка (проблема: утечки памяти!)  
bus.$on('user-updated', (user) => { ... })

2. Глубокие watch c deep: true

Глубокое наблюдение за объектами (deep: true) часто приводит к неоптимальной производительности.

Проблемы:

  • Лишние ререндеры.

  • Сложность отладки.

Современная альтернатива:

  • Точечные вычисляемые свойства (computed).

  • Контролируемые обновления через методы или более мелкие watch.

3. Миксины (mixins) для повторного использования логики

Миксины были популярны в Vue 2, но создавали проблемы:

  • Конфликты имён.

  • Неочевидное поведение при наследовании.

Современная альтернатива:

  • Composition API (через @vue/composition-api) — даже в Vue 2 можно использовать его для лучшей организации кода.

  • Хуки и утилиты — выносить логику в отдельные функции.

// Устаревший подход  
const myMixin = {  
  methods: { fetchData() {} }  
}

// Современный метод: Composition-стиль  
import { useFetch } from '@/composables/useFetch'

export default {  
  setup() {  
    const { fetchData } = useFetch()
    return { fetchData }
  }  
}

4. Массивы в v-for без key

Хотя Vue 2 не требует key так строго, как React, отсутствие ключей ведёт к багам при обновлении списков.

Современный подход:

  • Всегда указывать уникальные key.

  • Избегать index в качестве ключа, если порядок может меняться.

Паттерны, которые остаются актуальными

1. Опции data, computed, methods

Даже в 2025 году Options API остаётся читаемым и удобным для небольших компонентов.

Когда использовать:

  • Простые компоненты без сложной логики.

  • Легаси-проекты, где миграция на Composition API нецелесообразна.

2. Scoped-стили (<style scoped>)

Scoped CSS по-прежнему отлично работает для изоляции стилей.

Альтернативы:

  • CSS-модули (<style module>).

  • Tailwind CSS (если проект использует utility-first подход).

3. Локальное состояние в data()

Подходит для простых компонентов:

export default {  
  data() {  
    return {  
      count: 0,  
      user: null  
    }
  }  
}

Плюсы:

  • Простота (нет лишних зависимостей)

  • Прозрачность (все данные видны в одном месте)

Когда использовать?

  • Малые компоненты без сложной логики

  • Проекты без Composition API

4. Слоты (Slots) для гибкости

Остаются лучшим способом композиции:

<!-- Компонент Card.vue -->  
<template>  
  <div class="card">  
    <slot name="header"></slot>  
    <slot></slot>  
    <slot name="footer"></slot>  
  </div>  
</template>  

<!-- Использование -->  
<Card>  
  <template #header>  
    <h2>Заголовок</h2>  
  </template>  
  Основной контент  
  <template #footer>  
    <button>Сохранить</button>  
  </template>  
</Card>

Плюсы:

  • Гибкость (можно менять содержимое без пропсов)

  • Полная совместимость с Vue 3

Что из Vue 3 можно внедрить уже сейчас?

Composition API (через @vue/composition-api)

Главным нововведением для Vue 2 все же остается использование возможностей Vue 3 с помощью composition-api. Это новый способ организации кода во Vue.js, он решает проблемы Options API (который используется в Vue 2) и делает код более гибким, переиспользуемым и удобным для TypeScript.

Пример использования:

import { ref, computed, onMounted } from '@vue/composition-api'

export default {  
  setup() {  
    const count = ref(0)
    const double = computed(() => count.value * 2)

    onMounted(() => {  
      console.log('Компонент смонтирован')
    })

    return { count, double }
  }  
}

Плюсы:

  • Лучшая организация кода

  • Легче мигрировать на Vue 3

Фрагменты (множественные корневые элементы)

Во Vue 2.7+ можно использовать:

<template>
  <div>Первая нода</div>
  <div>Вторая нода</div>
</template>

Кастомные директивы с аргументами

Пример:

// Регистрация
Vue.directive('color', {
  bind(el, binding) {
    el.style.color = binding.value
  }
})
// Использование
<div v-color="'red'">Текст</div>

Стейт-менеджер - какой выбрать?

Мой выбор однозначно падает на Pinia. Vuex, как и Vue 2, постепенно становится legacy-решением, тогда как Pinia приобрел статус официального стейт-менеджера во Vue 3. Среди основных преимуществ хочу выделить:

  • Простота и удобство – отсутствие лишних mutations, встроенная поддержка типизации.

  • Гибкая модульность – каждый стор независим, не требуются namespaces.

  • Полная совместимость с Composition API – идеально подходит для современных подходов разработки.

  • Упрощенная миграция на Vue 3 – поскольку Pinia является стандартным решением для Vue 3.

Vuex по-прежнему можно использовать, но важно понимать: эта технология постепенно устаревает. Не стоит пренебрегать современными и более гибкими альтернативами.

Заключение

Vue 2 ещё жив, но некоторые его паттерны уже устарели. Оптимизируйте код, отказываясь от EventBus, миксинов и глубоких watch, но сохраняйте рабочие подходы вроде Options API для простых компонентов.

Совет: Постепенно внедряйте Composition API и Pinia, чтобы упростить будущий переход на Vue 3.

В 2025 году существует множество больших языковых моделей, которые ускоряют мою работу с JavaScript-кодом и написанием unit-тестов. Однако важно не полагаться на LLM безоговорочно — всегда тщательно проверяйте и тестируйте предоставленный код.

Лично я для работы с Vue чаще всего использую китайскую модель DeepSeek – она хорошо справляется с боевыми задачами. Если у вас не получается объяснить модели, какую функцию нужно реализовать, попробуйте применить декомпозицию: разбейте сложную функцию на более простые методы. Этот подход я применяю не только в программировании:

  • при написании функций и методов;

  • в системном анализе;

  • при принятии задач в работу;

  • в повседневной и социальной жизни.

Расскажите в комментариях, как у вас на проекте проходил переход с Vue 2 на Vue 3.