Кроме обычных свойств объект Vue может содержать так называемые вычисляемые свойства или computed properties, который во многом аналогичны функциям, но в то же время отличаются от них. Для понимания, зачем они нужны, рассмотрим небольшой пример:
<!DOCTYPE html> <html> <head> <title>Изучаем Vue 3</title> <meta charset="utf-8" /> </head> <body> <div id="app"> <input type="text" v-model="name" /> <input type="text" v-model="age" /> <p>Имя: {{name}} Возраст {{age}}</p> <p>{{checkAge()}}</p> </div> <script src="https://unpkg.com/vue"></script> <script> Vue.createApp({ data() { return {name:'Tom', age:25} }, methods:{ checkAge: function(){ console.log("checkAge"); if(this.age > 18) return "доступ разрешен"; else return "доступ запрещен"; } } }).mount('#app'); </script> </body> </html>
В данном случае в зависимости от возраста пользователя функция checkAge возвращает некоторый результат. И при каждом изменении значения свойства age, функция checkAge будет пересчитывать свой результат. Однако минусом подобного подхода является то, что метод checkAge будет выполняться при изменении любого свойства во Vue, в том числе свойства name, которое с методом checkAge никак не связано. Это мы можем увидеть по консольному выводу из метода checkAge при изменении свойства name:
Более оптимальным в данном случае будет использование вычисляемых свойств, которые определяются с помощью параметра computed:
<!DOCTYPE html> <html> <head> <title>Изучаем Vue 3</title> <meta charset="utf-8" /> </head> <body> <div id="app"> <input type="text" v-model="name" /> <input type="text" v-model="age" /> <p>Имя: {{name}} Возраст {{age}}</p> <p>{{checkAge()}}</p> <p>{{enabled}}</p> </div> <script src="https://unpkg.com/vue"></script> <script> Vue.createApp({ data() { return {name:'Tom', age:25} }, computed:{ enabled: function(){ console.log("computed"); if(this.age > 18) return "доступ разрешен"; else return "доступ запрещен"; } }, methods:{ checkAge: function(){ console.log("checkAge"); if(this.age > 18) return "доступ разрешен"; else return "доступ запрещен"; } } }).mount('#app'); </script> </body> </html>
В данном примере enabled
представляет вычисляемое свойство. Его определение во многом аналогично методу checkAge.
Но теперь при изменении состояния Vue будут анализироваться сделанные изменения, и если потребуется, то свойство enabled будет повторно вычисляться. Поэтому в данном случае, если мы изменим свойство age, изменится свойство enabled и повторно выполнится функция checkAge.
Но если изменится свойство name, то свойство enabled не будет изменяться:
Вычисляемое свойство можно разделить на сеттер и геттер. Геттер возвращает значение, а сеттер устанавливает. По умолчанию свойство имеет только геттер - во всех примерах выше вычисляемое свойство представляет функцию, которая возвращает некоторое значение. Теперь определим и геттер, и сеттер:
<!DOCTYPE html> <html> <head> <title>Изучаем Vue 3</title> <meta charset="utf-8" /> </head> <body> <div id="app"> <input type="text" v-model="firstname" /> <input type="text" v-model="lastname" /> <input type="text" v-model="fullname" /> <p>Имя: {{fullname}}</p> </div> <script src="https://unpkg.com/vue"></script> <script> Vue.createApp({ data() { return {firstname:'Tom', lastname:'Smith'} }, computed:{ fullname: { get: function () { return this.firstname + ' ' + this.lastname; }, set: function (newValue) { const names = newValue.split(' ') this.firstname = names[0] this.lastname = names[names.length - 1] } } } }).mount('#app'); </script> </body> </html>
На уровне кода геттер задается через параметр get - он представляет функцию, которая возвращает некоторое значение. А сеттер представляет функцию, которая задавается через параметр set. Причем каждое новое значение передается через параметр этой функции (в примере выше параметр newValue). И так как в данном случае вычисляемое свойство представляет объединение простых свойств firstname и lastname, то сеттере мы можем получить по отдельности значения этих свойств после изменения свойства fullname.