Кроме обычных свойств объект Vue может содержать вычисляемые свойства, который во многом аналогичны функциям, но в то же время отличаются от них. Рассмотрим небольшой пример:
<!DOCTYPE html> <html> <head> <title>Изучаем Vue.js</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@2.7.14/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: {name:'Tom', age:25}, methods:{ checkAge: function(){ console.log("method"); if(this.age > 17) return "доступ разрешен"; else return "доступ запрещен"; } } }); </script> </body> </html>
Здесь в зависимости от возраста пользователя функция checkAge возвращает некоторый результат. И при каждом изменении значения свойства age, функция checkAge будет пересчитывать свой результат. Однако минусом подобного подхода является то, что метод checkAge будет выполняться при изменении любого свойства во Vue, в том числе свойства name, которое с методом checkAge никак не связано. Это мы можем увидеть по консольному выводу из метода checkAge при изменении свойства name:
Более оптимальным в данном случае будет использование вычисляемых свойств, которые определяются с помощью параметра computed:
<!DOCTYPE html> <html> <head> <title>Изучаем Vue.js</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@2.7.14/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: {name:'Tom', age:25}, computed:{ enabled: function(){ console.log("computed"); if(this.age > 17) return "доступ разрешен"; else return "доступ запрещен"; } }, methods:{ checkAge: function(){ console.log("method"); if(this.age > 17) return "доступ разрешен"; else return "доступ запрещен"; } } }); </script> </body> </html>
Здесь enabled представляет вычисляемое свойство. Его определение во многом аналогично методу checkAge. Но теперь при изменении состояния Vue будут анализироваться сделанные изменения, и если потребуется, то свойство enabled будет повторно вычисляться. Поэтому в данном случае, если мы изменим свойство age, изменится свойство enabled и повторно выполнится функция checkAge. Но если изменится свойство name, то свойство enabled не будет изменяться:
Вычисляемое свойство можно разделить на сеттер и геттер. Геттер возвращает значение, а сеттер устанавливает. По умолчанию свойство имеет только геттер - во всех примерах выше вычисляемое свойство представляет функцию, которая возвращает некоторое значение. Теперь определим и геттер, и сеттер:
<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@2.7.14/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: {firstname:'Tom', lastname:'Smith'}, computed:{ fullname: { get: function () { return this.firstname + ' ' + this.lastname; }, set: function (newValue) { var names = newValue.split(' ') this.firstname = names[0] this.lastname = names[names.length - 1] } } } }); </script>
На уровне кода геттер задается через параметр get, который представляет функцию, возвращающую значение. А сеттер представляет функцию, задаваемую через параметр set. Причем каждое новое значение передается через параметр этой функции (в примере выше параметр newValue). И так как в данном случае вычисляемое свойство представляет объединение простых свойств firstname и lastname, то сеттере мы можем получить по отдельности значения этих свойств после изменения свойства fullname.