# Изменения функциональных компонентов
кардинальное изменение
# Обзор
Краткий обзор того, что изменилось:
- Выигрыш по производительности функциональных компонентов в 2.x пренебрежительно мал в 3.x, поэтому рекомендуется просто использовать компоненты с состоянием
- Функциональные компоненты могут создаваться только с помощью простых функций, которые получают аргументами
props
иcontext
(т.е.,slots
,attrs
,emit
) - КАРДИНАЛЬНОЕ ИЗМЕНЕНИЕ: удалён атрибут
functional
для<template>
однофайловых компонентов (SFC) - КАРДИНАЛЬНОЕ ИЗМЕНЕНИЕ: удалена опция
{ functional: true }
в компонентах, создаваемых функциями
Для получения дополнительной информации читайте дальше!
# Введение
Во Vue 2 функциональные компоненты в основном использовались в двух случаях:
- для оптимизации производительности, потому что инициализировались быстрее, чем компоненты с состоянием
- для возможности возвращать несколько корневых узлов из компонента
Однако, во Vue 3 производительность компонентов с состоянием улучшилась до такой степени, что разница стала пренебрежительно мала. Кроме того, компоненты с состоянием теперь получили возможность возвращать несколько корневых узлов.
В результате, единственная оставшаяся причина для функциональных компонентов — простые компоненты, такие как компонент для создания динамического заголовка. В остальных случаях рекомендуется использовать компоненты с состоянием, как обычно.
# Синтаксис в 2.x
Компонент <dynamic-heading>
, отвечающий за отрисовку соответствующего заголовка (т.е., h1
, h2
, h3
, и т.д.), можно записать однофайловым компонентом в 2.x так:
<!-- Пример функционального компонента во Vue 2 -->
<script>
export default {
functional: true,
props: ['level'],
render(h, { props, data, children }) {
return h(`h${props.level}`, data, children)
}
}
</script>
2
3
4
5
6
7
8
9
10
Или так, если предпочитаете использовать <template>
в однофайловых компонентах:
<!-- Пример функционального компонента во Vue 2 с <template> -->
<template functional>
<component
:is="`h${props.level}`"
v-bind="attrs"
v-on="listeners"
/>
</template>
<script>
export default {
props: ['level']
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
# Синтаксис в 3.x
# Компоненты создаются функциями
Теперь во Vue 3 все функциональные компоненты создаются с помощью простых функций. Другими словами, нет необходимости указывать опцию { functional: true }
компонента.
Функции получают два аргумента: props
и context
. Аргумент context
— объект, в котором содержатся свойства компонента attrs
, slots
и emit
.
Кроме того, вместо неявной передачи h
в функцию render
, теперь h
импортируется глобально.
Приведённый выше пример компонента <dynamic-heading>
теперь можно переписать так:
import { h } from 'vue'
const DynamicHeading = (props, context) => {
return h(`h${props.level}`, context.attrs, context.slots)
}
DynamicHeading.props = ['level']
export default DynamicHeading
2
3
4
5
6
7
8
9
# Однофайловые компоненты (SFC)
В версиях 3.x разница производительности между функциональными компонентами и компонентами с состоянием была кардинально уменьшена и теперь будет незначительной в большинстве случаев использования. В результате, стратегия миграции для разработчиков, использующих functional
в однофайловых компонентах будет заключаться в удалении этого атрибута и переименовании всех ссылок props
в $props
и attrs
в $attrs
.
Используя компонент <dynamic-heading>
из примера выше, в итоге он будет выглядеть так:
<template>
<component
v-bind:is="`h${$props.level}`"
v-bind="$attrs"
/>
</template>
<script>
export default {
props: ['level']
}
</script>
2
3
4
5
6
7
8
9
10
11
12
Ключевые отличия в том, что:
- Из
<template>
удалён атрибутfunctional
- Теперь
listeners
передаются как часть$attrs
и могут быть удалены
# Дальнейшие шаги
Более подробную информацию об использовании новых функциональных компонентов, а также изменениях, вносимых в render-функции можно прочитать здесь: