Vue что такое computed
Чем отличаются computed от methods во Vue?
Вычисляемые значения кешируются, обновляя свои значения при изменении тех реактивных свойств, от которых они зависимы. Computed нельзя вызывать или передавать им значения в сигнатуру. По сути, это не функции, это свойства объекта vue, геттер.
Методы, в свою очередь, повторно вызываются каждый раз, когда к ним идет обращение, могут получать параметры в свою сигнатуру и тп.
Вот кейс, который отлично демонстрирует различие не на базовом уровне (не то, как они функционируют), а на уровне прикладном (как это использовать):
Представьте обычный таймер, который раз в секунду добавляет единицу к свойству circles в свойстве data вашего экземпляра вью
Вот верстка для этого компонента:
Что делает вью? Рендерит компонент каждый раз, когда значение circles увеличивается на единицу. Каждый раз во время рендера вызывается метод getRunnerStatus. Откройте консоль и вы увидите, что из метода там печатается ‘hi’. В чем проблема? Статус таймера-то не изменяется. Вывод будет всегда одинаковый: Runner’s status: running
Если вместо метода запилить computed, то вы увидите, что ‘hi’ в консоли вывелась один раз. Значение закешировано, свойство finished не было изменено, вычисленное свойство не было пересчитано (функция не вызывалась).
Касательно вашего примера: вы используете метод drawRes() в верстке, по-этому он и вызывается каждый раз при рендере view, собственно, по тем причинам, которые я описал выше.
ps при желании вычисляемое свойство можно сделать сеттером, но я лично не встречал таких кейсов в проде.
# Computed Properties and Watchers
# Computed Properties
In-template expressions are very convenient, but they are meant for simple operations. Putting too much logic in your templates can make them bloated and hard to maintain. For example, if we have an object with a nested array:
And we want to display different messages depending on if author already has some books or not
That’s why for complex logic that includes reactive data, you should use a computed property.
# Basic Example
Try to change the value of books array in the application data and you will see how publishedBooksMessage is changing accordingly.
# Computed Caching vs Methods
You may have noticed we can achieve the same result by invoking a method in the expression:
Instead of a computed property, we can define the same function as a method. For the end result, the two approaches are indeed exactly the same. However, the difference is that computed properties are cached based on their reactive dependencies. A computed property will only re-evaluate when some of its reactive dependencies have changed. This means as long as author.books has not changed, multiple access to the publishedBooksMessage computed property will immediately return the previously computed result without having to run the function again.
This also means the following computed property will never update, because Date.now() is not a reactive dependency:
In comparison, a method invocation will always run the function whenever a re-render happens.
# Computed Setter
Computed properties are by default getter-only, but you can also provide a setter when you need it:
# Watchers
While computed properties are more appropriate in most cases, there are times when a custom watcher is necessary. That’s why Vue provides a more generic way to react to data changes through the watch option. This is most useful when you want to perform asynchronous or expensive operations in response to changing data.
In this case, using the watch option allows us to perform an asynchronous operation (accessing an API) and sets a condition for performing this operation. None of that would be possible with a computed property.
In addition to the watch option, you can also use the imperative vm.$watch API.
# Computed vs Watched Property
The above code is imperative and repetitive. Compare it with a computed property version:
Much better, isn’t it?
Deployed on Netlify.
Caught a mistake or want to contribute to the documentation? Edit this on GitHub!
(opens new window)
Last updated: 2021-06-04, 16:01:19 UTC
Vue.js для начинающих, урок 7: вычисляемые свойства
Сегодня, в седьмом уроке курса по Vue, мы поговорим о вычисляемых свойствах. Эти свойства экземпляра Vue не хранят значения, а вычисляют их.
Цель урока
Начальный вариант кода
Задача
Решение задачи
Мы для решения этой задачи воспользуемся вычисляемыми свойствами. Так как эти свойства не хранят значения, а вычисляют их, давайте добавим в объект с опциями, используемый при создании экземпляра Vue, свойство computed и создадим вычисляемое свойство с именем title :
Теперь нам осталось лишь вывести title в теге
нашей страницы.
Сейчас этот тег выглядит так:
А теперь мы сделаем его таким:
Взглянем на страницу и проверим работоспособность того, что мы только что сделали.
Заголовок страницы изменился
Это был очень простой пример, но пример, вполне применимый на практике. Давайте теперь рассмотрим более сложный вариант использования вычисляемых свойств.
Более сложный пример
Этот механизм работает нормально, но если нам понадобится, основываясь на том, на какой именно цветной квадрат наведена мышь, менять не только изображение, но и что-то ещё, это будет означать необходимость рефакторинга данного кода. Давайте этим и займёмся.
Почему 0? Дело в том, что мы планируем устанавливать это свойство на основе индекса ( index ) элемента, над которым находится указатель мыши. Мы можем добавить индекс в конструкцию v-for :
Если сейчас обновить страницу и открыть консоль инструментов разработчика, мы можем убедиться в том, что при наведении мыши на квадраты в консоль попадают значения 0 и 1.
Проверка работоспособности созданного нами механизма
Однако изображение теперь на странице не выводится. В консоли появляется предупреждение.
Предупреждение, выводимое в консоль
Если теперь обновить страницу, изображение выведется и будет реагировать на наведение мыши на цветные квадраты. Но теперь этот механизм реализован с использованием вычисляемого свойства.
Обратите внимание на то, что кнопка тоже, как и ранее, правильно реагирует на установку inStock в 0.
Кнопка и надпись зависят от количества товара каждого вида
Почему всё продолжает правильно работать? Дело в том, что inStock всё ещё используется для привязки класса disableButton к нашей кнопке. Единственное различие нового варианта приложения и его предыдущего варианта заключается в том, что теперь inStock — это вычисляемое, а не обычное свойство.
Дополнительные сведения о вычисляемых свойствах
Учитывая это, можно сказать, что если для получения некоего значения требуются ресурсоёмкие вычисления, то для их выполнения выгоднее использовать вычисляемое свойство, а не метод. Метод придётся вызывать каждый раз, когда будет нужно соответствующее значение.
Кроме того, важно помнить о том, что в коде вычисляемых свойств не следует менять данные, хранящиеся в экземпляре Vue. В этом коде нужно лишь выполнять вычисления, основанные на существующих данных. Эти функции должны быть чистыми, лишёнными побочных эффектов.
Практикум
→ Вот заготовка, которую вы можете использовать для решения этой задачи
Итоги
На этом занятии мы познакомились с вычисляемыми свойствами. Вот самое важное из того, что мы о них узнали:
Если вы выполняете домашние задания к этому курсу, расскажите, делаете ли вы исключительно то, что вам предлагается, или идёте дальше?
Computed Properties and Watchers
Computed Properties
In-template expressions are very convenient, but they are meant for simple operations. Putting too much logic in your templates can make them bloated and hard to maintain. For example:
At this point, the template is no longer simple and declarative. You have to look at it for a second before realizing that it displays message in reverse. The problem is made worse when you want to include the reversed message in your template more than once.
That’s why for any complex logic, you should use a computed property.
Basic Example
Computed Caching vs Methods
You may have noticed we can achieve the same result by invoking a method in the expression:
Instead of a computed property, we can define the same function as a method. For the end result, the two approaches are indeed exactly the same. However, the difference is that computed properties are cached based on their reactive dependencies. A computed property will only re-evaluate when some of its reactive dependencies have changed. This means as long as message has not changed, multiple access to the reversedMessage computed property will immediately return the previously computed result without having to run the function again.
This also means the following computed property will never update, because Date.now() is not a reactive dependency:
In comparison, a method invocation will always run the function whenever a re-render happens.
Why do we need caching? Imagine we have an expensive computed property A, which requires looping through a huge Array and doing a lot of computations. Then we may have other computed properties that in turn depend on A. Without caching, we would be executing A’s getter many more times than necessary! In cases where you do not want caching, use a method instead.
Computed vs Watched Property
The above code is imperative and repetitive. Compare it with a computed property version:
Much better, isn’t it?
Computed Setter
Computed properties are by default getter-only, but you can also provide a setter when you need it:
Watchers
While computed properties are more appropriate in most cases, there are times when a custom watcher is necessary. That’s why Vue provides a more generic way to react to data changes through the watch option. This is most useful when you want to perform asynchronous or expensive operations in response to changing data.
Ask a yes/no question:
In this case, using the watch option allows us to perform an asynchronous operation (accessing an API), limit how often we perform that operation, and set intermediary states until we get a final answer. None of that would be possible with a computed property.
In addition to the watch option, you can also use the imperative vm.$watch API.
Vue: Computed — вычисляемые свойства
или когда хочется упростить себе жизнь
Apr 23, 2017 · 6 min read
Обновлено 22.01.2018: Пересмотрел свежим взглядом и внёс мелкие правки. Заходите и в Telegram-канал по Vue: https://t.me/vuejs_ru
Условно, используемые данные во Vue можно разделить на 3 части:
И если первые два подразумевают “статичность” (присвоенное значение останется неизменным, до присвоения нового), то вычисляемые свойства автоматически рассчитывают своё значение.
Частая область их применения — красивое отображение данных для пользователя. Это может быть вывод даты в подробном формате или форматирование текста, выбор одного из варианта по условию.
Сама идея отслеживания изме н ений думаю перенята у Angular. Подобное там можно реализовать с помощью watch’еров, которые реагируют на произошедшие изменения. К сожалению, при увеличении их числа начинает медленнее выполняться цикл дайждеста — что приводило к “ощущениям” тормозов приложения.
Вкратце, вычисляемые свойства…
Вычисляемые свойства vs. watch
Vue предоставляет два варианта отслеживания данных:
Не стоит всё отслеживание реализовывать на основе методов-наблюдателей. Многое лучше делать с использованием вычисляемых свойств, используя все их преимущества.
Watch стоит использовать при “дорогих” операциях вычислений, а также для реализации асинхронных операций. Другим применением, может быть вызов дополнительной логики (например, для статистики).
Вычисляемые свойства vs. методы
Похожий результат можно получать и воспользовавшись методами для форматирования или преобразования данных. В чём разница?
Метод необходимо каждый раз явно вызвать для получения нового значения, а его результат никак не кешируется (ну или ещё придётся реализовывать мемоизацию).
Вычисляемые свойства автоматически отслеживают все свои зависимости и запускают перерасчёт только при их изменениях, кешируя результат.
Кеширование
Благодаря кешированию значений, не нужно переживать по поводу использования других вычисляемых свойств — никакого каскадного перерасчёта не будет. Каждое свойство “знает” свои зависимости и пересчитывается только при их изменениях, остальные вернут закешированное значение.
Вычисляемые свойства для выноса логики из шаблона
Допустим есть шаблон, в котором хочется вывести имя пользователя в верхнем регистре, а также сколько прошло времени со дня рождения:
В шаблоне, который предназначен для определения структуры элемента теперь присутствует логика. По возможности, следует стараться этого избегать, меньше будет путаницы и чище код.
А что будет если потребуются сложные вычисления? Кроме того, что шаблон ещё сильнее распухнет, сам синтаксис шаблонов допускает использование внутри фигурных скобок только одного выражения. Тернарный оператор ещё допустим, но логика сложнее — нет.
Исправить пример дело пары минут — добавляем свойство computed и описываем в объекте все вычисляемые свойства, которые по сути являются просто функциями, возвращающими новое значение:
Не используйте стрелочные функции при определении вычисляемых свойств, иначе this внутри них не будет указывать на экземпляр Vue! Но краткую запись метода использовать можно:
В шаблоне вычисляемые свойства можно использовать как обычные:
Вычисляемые свойства для различных “флагов”
Это конечно уже зависит от вкусовых предпочтений каждого, но я стараюсь по максимуму выносить логику из шаблона.
Например, чтобы выводить сообщение об отсутствии элементов в массиве можно сделать так:
И это полностью рабочий вариант. А можно сделать вычисляемое свойство для флага и использовать уже его:
Никакой логики в шаблоне, читается лучше, а при необходимости эти вычисляемые свойства можно использовать и в других сравнениях.
Вычисляемые свойства как замена фильтров
Во Vue 1.х можно было использовать фильтры в выражениях шаблона:
В релизе Vue.js 2 фильтры были удалены, а их функционал было предложено перенести в вычисляемые свойства для более явного разделения логики от разметки:
С версии Vue 2.1.0 вновь стало возможным использовать фильтры, но только внутри mustache-шаблонов.
Вычисляемые свойства для манипуляции массивами
По аналогии с предыдущим примером можно легко манипулировать элементами массива: фильтровать или сортировать.
Это пригодится, когда нет возможности получать с сервера данные сразу в нужном формате/порядке. С помощью вычисляемого свойства исправить это очень просто:
Вычисляемые свойства для добавления динамичности
Может пригодиться для реализации настраиваемых компонентов. Например, когда описание элемента может быть расположено в разных свойствах объекта. Для этого достаточно передать название свойства, и на их основе создать вычисляемое свойство:
Сеттеры вычисляемых свойств
Наверное редкий случай, когда это может пригодиться (по крайней мере мне ещё ни разу не приходилось воспользоваться), но есть возможность настроить вычисляемое свойство не только на чтение, но и реализовать логику на запись:
Теперь запись this.fullName = ‘Иван Иванов’ вычисляемого свойства вызовет сеттер, и this.firstName и this.lastName будут соответствующим образом обновлены.
Вычисляемые свойства и нереактивные данные
Но при изменении размеров окна браузера значение остаётся тем же. Почему это не сработало? Потому что вычисляемые свойства отслеживают изменения только реактивных данных (data или props).
Что же делать в таком случае? Можно добиться “реактивности” несколько другим способом. При инициализации Vue добавить переменную и записать в неё какое-то стартовое значение (или пустое). Теперь есть реактивная переменная и стартовое состояние:
Как же поддерживать эту переменную в актуальном состоянии? Для этого в mounted хуке добавим обработчик события изменения размера экрана, а в коллбэке сохраним новое значение в нашу переменную:
В итоге у нас будет “реактивная” переменная с актуальным значением размера окна, которую можно использовать в других вычисляемых свойствах.
Вычисляемые свойства + асинхронность
Как упоминалось в самом начале, вычисляемые свойства не могут содержать в себе асинхронной логики вычисления значения. Одним из вариантов асинхронного вычисления можно сделать с помощью метода наблюдателя.
Есть другой вариант — воспользоваться плагином vue-async-computed: