В предыдущих статьях мы узнали о основах Vue API и как работать с однофайловыми компонентами Vue. Опираясь на эти
основы, в этой и следующих статьях, исследуются различные подходы к контролю данных внутри компонента Vue.
Вы узнаете, как использовать мощную реактивность данных и кеш Vue, как использовать вычисляемые свойства, как настроить watch, и попробуете наблюдать за изменениями данных компонента. Вы также узнаете, как использовать асинхронные методы для получения и обработки данных для ваших компонентов Vue.
По умолчанию Vue автоматически кэширует computed свойства, делая их более эффективными при обновлении пользовательского интерфейса, чем использование свойства
возвращаемое data или с использованием methods компонента Vue.
Синтаксис вычисляемого свойства подобен написанию methods компонента с
возвращаемым значением:
export default {
computed: {
yourComputedProperty() {
/* need to have return value */
}
}
}
Внутри сomputed, мы можем получить любое свойство текущего компонента:
export default {
data() {
return {
yourData: "your data"
}
},
computed: {
yourComputedProperty() {
return `${this.yourData}-computed`;
}
}
}
Давайте рассмотрим несколько примеров того, где вы должны рассмотреть возможность использования computed:
Валидация формы: в следующем примере у нас есть поле ввода, к которому привязано свойство name, а error - является вычисляемым свойством. Если name содержит ложное значение (что означает, что name является пустой строкой, 0, undefined, null или false), error будет присвоено значение «Требуется имя». В противном случае он будет пуст.
<template>
<input v-model="name">
<div>
<span>{{ error }}</span>
</div>
</template>
<script>
export default {
data() {
return {
name: '',
}
},
computed: {
error() {
return this.name ? '' : 'Name is required'
}
}
}
</script>
Объединение data переменных: вы можете использовать computed для объединения нескольких свойств данных чтобы создать их них, одно вычисляемое свойство. Возьмем, к примеру, следующий код. Мы объединяем две переменные data - title и surname - в одну вычисляемую строку, formName и отображаем его значение внутри template:
<template>
<div>{{ formalName }}</div>
</template>
<script>
export default {
data() {
return {
title: 'Mr.',
surname: 'Smith'
}
},
computed: {
formalName() {
return `${this.title} ${this.surname}`;
}
}
}
</script>
В результате, имя title и surname будут добавлены в переменную formalName и ее значение будет - Mr. Smith.
Вычисление и отображение сложной информации: Иногда возникает необходимость выполнить дополнительные вычисления или для извлечение конкретной информации из большого объекта данных. Computed помогает достичь этой цели, сохраняя наш код читабельным.
Возьмите большой объект данных, в нашем примере это post. Этот объект данных имеет свойство fields, которое содержит несколько вложенных объектов, таких как
author и entries. Каждая запись в entries содержит дополнительную информацию, такую как title, content и featured - переменная отвечающая за отображение записи:
data() {
return {
post: {
fields: {
author: {
firstName: 'John',
lastName: 'Doe'
},
entries: [
{
title: "Entry 1",
content: "Entry 1's content",
featured: true
},
{
title: "Entry 2",
content: "Entry 2's content",
featured: false
}
]
}
}
}
},
Computed свойство для получения полного имени автора может выглядеть так:
fullName() {
const { firstName, lastName } = this.post.fields.author;
return `${firstName} ${lastName}`
},
А количество записей так:
totalEntries () {
return this.post.fields.entries.length
},
FeaturedEntries содержит отфильтрованный список post.fields.entries на основе значения feature объекта каждой записи, используя встроенный метод filter:
featuredEntries() {
const { entries } = this.post.fields;
return entries.filter(entry => !!entry.featured)
}
Затем мы модем использовать наши computed свойства для визуализации информации в template yашего компонента. Полный код показан здесь:
<template>
<div>
<p>{{ fullName }}</p>
<p>{{ totalEntries }}</p>
<p>{{ featuredEntries }}</p>
</div>
</template>
<script>
export default {
data() {
return {
post: {
fields: {
author: {
firstName: 'John',
lastName: 'Doe'
},
entries: [
{
title: "Entry 1",
content: "Entry 1's content",
featured: true
},
{
title: "Entry 2",
content: "Entry 2's content",
featured: false
}]
}
}
}
},
computed: {
fullName() {
const { firstName, lastName } = this.post.fields.author;
return `${firstName} ${lastName}`
},
totalEntries () {
return this.post.fields.entries.length
},
featuredEntries() {
const { entries } = this.post.fields;
return entries.filter(entry => !!entry.featured)
}
}
</script>