Что такое функциональные компоненты?vue-72

Функциональные компоненты — это особый тип компонентов в Vue, которые не имеют собственного состояния (stateless), не имеют экземпляра (no-instance) и работают исключительно на основе входных параметров (props). Они представляют собой чистые функции, которые принимают props и возвращают VNodes.

Основные характеристики

  1. Отсутствие состояния: Не имеют собственного реактивного data()
  2. Нет экземпляра: Не имеют this контекста
  3. Нет хуков жизненного цикла: Кроме functionalContext
  4. Высокая производительность: Легковесные, так как не создают экземпляров компонента

Синтаксис функциональных компонентов

Вариант 1: Опция functional в объекте компонента

Vue.component('my-functional-component', {
  functional: true,
  props: ['message'],
  render(createElement, context) {
    return createElement('div', context.props.message)
  }
})

Вариант 2: Функциональный компонент как функция

const FunctionalComponent = (props, context) => {
  return context.slots().default
}

Параметр context

Функциональные компоненты получают второй аргумент — context, который содержит:

{
  props: Object,       // Переданные параметры
  children: Array,     // Дочерние VNodes
  slots: Function,     // Функция, возвращающая slots объект
  data: Object,        // Все атрибуты и обработчики
  parent: Component,   // Родительский компонент
  listeners: Object,   // Зарегистрированные обработчики событий
  scopedSlots: Object  // Scoped slots (2.6+)
}

Когда использовать функциональные компоненты

  1. Презентационные компоненты: Чисто визуальные элементы без логики
  2. Обертки/декораторы: Для модификации отображения дочерних элементов
  3. Высокопроизводительные списки: Когда нужно рендерить много элементов
  4. Динамические компоненты: Когда логика выбора шаблона простая

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

Простой презентационный компонент

Vue.component('smart-button', {
  functional: true,
  props: ['type', 'text'],
  render(h, { props }) {
    return h('button', {
      class: `btn btn-${props.type}`
    }, props.text)
  }
})

Компонент-обертка

const BorderWrapper = {
  functional: true,
  render(h, { children }) {
    return h('div', { class: 'border-wrapper' }, children)
  }
}

Оптимизированный список

const ItemList = {
  functional: true,
  props: ['items'],
  render(h, { props }) {
    return h('ul',
      props.items.map(item =>
        h('li', { key: item.id }, item.text)
      )
  }
}

Преимущества

  1. Производительность: На 40-50% быстрее обычных компонентов
  2. Простота: Легче тестировать и поддерживать
  3. Композиционность: Лучше сочетаются с другими компонентами
  4. Чистота: Нет побочных эффектов, проще рассуждать о коде

Ограничения

  1. Нет доступа к this
  2. Нельзя использовать вычисляемые свойства (computed)
  3. Нет хуков жизненного цикла (created, mounted и т.д.)
  4. Нет реактивного состояния

Сравнение с обычными компонентами

Характеристика Обычный компонент Функциональный компонент
Состояние (data) ✅ Да ❌ Нет
Экземпляр (this) ✅ Да ❌ Нет
Хуки жизненного цикла ✅ Да ❌ Нет
Вычисляемые свойства ✅ Да ❌ Нет
Производительность ⏳ Средняя ⚡ Высокая
Сложность 📈 Высокая 📉 Низкая

Практический пример из реального проекта

// Компонент для отображения статуса с иконкой
const StatusIndicator = {
  functional: true,
  props: {
    status: {
      type: String,
      validator: s => ['success', 'warning', 'error'].includes(s)
    }
  },
  render(h, { props }) {
    const icon = {
      success: '✓',
      warning: '!',
      error: '×'
    }[props.status]

    return h('span', {
      class: `status status-${props.status}`
    }, [icon, props.status.toUpperCase()])
  }
}

Резюмируем:

функциональные компоненты — это мощный инструмент для создания легковесных, производительных презентационных компонентов. Они идеально подходят для случаев, когда не требуется внутреннее состояние или методы жизненного цикла, позволяя существенно оптимизировать производительность приложения.