Перевод статьи: Austin Gil Vue.js functional components: what, why, and when?
tldr: если ваш компонент не нуждается в отслеживании состояния, превращение его в функциональные компоненты может повысить производительность рендеринга на 70%.
Функциональные компоненты (не путать с функциями рендеринга Vue) — это компонент, который не содержит ни состояния, ни экземпляра.
Проще говоря это означает, что компонент не поддерживает реактивность и не может сделать ссылку на себя через ключевое слово this.
Использование через шаблон
<template functional> <div>...</div> </template>
Использование через код компонента
<script> export default { functional: true, ... render(h): { ... } } </script>
Если у компонента нет состояния или экземпляра вы можете задаться вопросом, как можно ссылаться на такие вещи, как данные или методы. К счастью, Vue предоставляет параметр «context» для базовой функции рендеринга.
«context» является объектом со следующими свойствами:
Доступ к параметру context довольно прост. Например, если мы хотим что-то сделать с props, это может выглядеть так:
<template functional> <div> {{props.someProp}} </template> <script> export default { props: { someProp: String } } </script>
<script> export default { functional: true, props: { someProps: String }, render(h, ctx): { const someProps = ctx.props.someProp ... } } </script>
Краткое примечание о функциональных компонентах и props:
В функциональном компоненте вам фактически не нужно регистрировать props, которые он принимает. Однако, если вы зарегистрируете их, они все равно будут проверены на соответствие их конфигурации. Лично я считаю, что по-прежнему рекомендуется зарегистрировать их, чтобы можно было бы указать тип переменной, required, значение по умолчанию и/или пользовательские валидаторы.
Функциональные компоненты могут сделать доступ к вашим компонентам немного сложнее в работе или создать некоторую сложность, так зачем же их использовать?
Скорость.
Поскольку функциональные компоненты не имеют состояния, они не требуют дополнительной инициализации для таких вещей, как система реактивности Vue.
Функциональные компоненты будут по-прежнему реагировать на изменения входных данных, такие как новые props, но внутри самого компонента нет способа узнать, когда его данные изменились, поскольку он не поддерживает свое собственное состояние.
Для тех из вас, кто предпочитает факты, я провел тестирование для отображения 1000 элементов списка как компонентов с состоянием по сравнению с функциональными компонентами, и в то время как компоненты с состоянием занимали в среднем 140 мс, функциональные компоненты занимали около 40 мс.
Проверти сами:
https://codesandbox.io/s/vue-template-yterr?fontsize=14
Для большого приложения вы увидите значительные улучшения событий рендеринга/обновления DOM после реализации функциональных компонентов.
Функциональные компоненты, вероятно, не подходят во многих случаях. В конце концов, смысл использования JavaScript-фреймворка заключается в создании приложений, которые более реактивны. В Vue вы не можете сделать это без системы реактивности.
Однако есть несколько отличных вариантов использования функциональных компонентов:
Есть одна небольшая проблема, с которой я столкнулся для довольно конкретного случая использования. При использовании тега <template> и при приеме данных через props иногда требуется изменить данные внутри шаблона.
Со стандартным компонентом Vue это легко сделать, используя методы или computed props. С функциональными компонентами у нас нет доступа к методам или computed props.
Тем не менее, есть способ сделать это.
Допустим, наш компонент принимает prop «user», который является объектом со свойствами «firstName» и «lastName», и мы хотим отобразить шаблон, который показывает полное имя пользователя.
В функциональном компоненте <template> мы можем сделать это, создав новый метод прямо в определении нашего компонента, а затем использовать свойство $options, предоставляемое Vue, для доступа к нашему специальному методу:
<template functional> <div>{{ $options.userFullName(props.user)}}</div> </template> <script> export default { props: { user: Object }, userFullName(user) { return `${user.firstName} ${user.lastName}` } } </script>
Я слышал об еще одной проблеме, я лично с ней не сталкивался, но один из участников сообщества обнаружил, что при попытки использовать вложенные функциональные компоненты, которые имеют scoped slots, поведение отличается от таких же компонентов но с использованием внутреннего состояния https://github.com/vuejs/vue-loader/issues/1136.
Если вы заботитесь о производительности или работаете с очень большими приложениями, попробуйте на практике создать/использовать функциональные компоненты. Небольшая трата времени на обучение стоит этого.
Ссылки:
https://vuejs.org/v2/guide/render-function.html#Functional-Components
https://itnext.io/whats-the-deal-with-functional-components-in-vue-js-513a31eb72b0
Краткий перевод: https://vuejs.org/guide/components/v-model.html Основное использование v-model используется для реализации двусторонней привязки в компоненте. Начиная с Vue…
Сегодня мы рады объявить о выпуске Vue 3.4 «🏀 Slam Dunk»! Этот выпуск включает в…
Vue.js — это универсальный и адаптируемый фреймворк. Благодаря своей отличительной архитектуре и системе реактивности Vue…
Недавно, у меня истек сертификат и пришлось заказывать новый и затем устанавливать на хостинг с…
Каким бы ни было ваше мнение о JavaScript, но всем известно, что работа с датами…
Все, кто следит за последними событиями в мире адаптивного дизайна, согласятся, что введение контейнерных запросов…