По умолчанию computed данные являются только геттерами, что означает, что они будут выводить только результат вашего выражения.
В некоторых практических сценариях, когда computed свойство изменено, вам может потребоваться активировать внешний API или
изменить исходные данные в другом месте проекта. Функция, которая выполняет это изменение называется setter.
Computed свойство по умолчанию, только возвращает значение, и при попытке задать этому свойству новое значение вы получите ошибку. Но если вы будете использовать setter, то сможете задавать значение computed свойству.
Использование setter в computed свойстве позволяет реактивно прослушивать данные и вызвать функцию (сеттер), который содержит возвращаемое значение из
getter, который можно дополнительно использовать в setter.
Но сначала давайте посмотрим на геттер и сеттер JavaScript ES5. Начиная с ES5, вы можете использовать встроенный геттер и сеттер для определения средств доступа к объектам, таких как:
get свойство Object к функции, которая возвращает значение для этого свойства всякий раз, когда оно
просматривается, как показано здесь:
const obj = {
get example() {
return 'Getter'
}
}
console.log(obj.example) //Getter
set для привязки определенного свойства объекта к функции всякий раз, когда это свойство изменяется:
const obj = {
set example(value) {
this.information.push(value)
},
information: []
}
obj.example = 'hello'
obj.example = 'world'
console.log(obj.information) //['hello', 'world']
Теперь при задании значения obj.example = 'hello', срабатывает функция.
Основываясь на этих нововведениях, Vue.js предоставляет нам аналогичные функции, get() в качестве геттера и set() в качестве сеттера для конкретного вычисляемого свойства:
computed: {
myComputedDataProp: {
get() {}
set(value) {}
}
}
Чтобы понять, как работают сеттеры и геттеры, давайте выполним следующие шаги:
Определите возвращаемое значение myComputedDataProp как this.count + 1 всякий раз, когда
myComputedDataProp просматривается:
myComputedDataProp: {
get() {
return this.count + 1
}
},
Затем, всякий раз, когда изменяется myComputedDataProp, используйте setter для установления count нового значения, а затем вызовите метод внутри компонента с именем callAnotherApi с этим новым значением this.count:
myComputedDataProp: {
set(value) {
this.count = value - 1
this.callAnotherApi(this.count)
},
Полный код примера:
data() {
return {
count: 0
}
},
method: {
callAnotherApi() { //do something }
},
computed: {
myComputedDataProp: {
get() {
return this.count + 1;
},
set(value) {
this.count = value - 1
this.callAnotherApi(this.count)
},
},
},
}
В данном примере, мы добавили setter, и если вы просто измените count - он станет 1, так как при загрузке сработает сразу геттер, но если вы зададите новое значение самому свойству computed - this.myComputedDataProp = 10, сработает блок кода сеттера.
Упражнение
Создадим и импортируем пустой компонент.
Добавим скелет компонента:
<template>
</template>
<script>
export default {
}
</script>
Создайте поле ввода с v-model, привязанным к computed свойству - incrementOne, возвращающим значение переменной count в геттере, и устанавливающая переменную count в сеттере:
<template> <div class="container"> <input type="number" v-model="incrementOne" /> <h3>Get input: {{ incrementOne }}</h3> </div> </template> <script> export default { data() { return { count: -1, } }, computed: { incrementOne: { get() { // getter return this.count + 1; }, set(val) { //setter this.count = val - 1; }
}, } </script>
Далее, давайте снова воспользуемся сеттером. Мы разделим новый аргумент val на 2, и сохраните это в новую переменную данных под названием divideByTwo:
<template>
<div class="container">
<input type="number" v-model="incrementOne" />
<h3>Get input: {{ incrementOne }}</h3>
<h5>Set division: {{ divideByTwo }}</h5>
</div>
</template>
<script>
export default {
data() {
return {
count: 0,
divideByTwo: 0,
}
},
//...
</script>
Обновите сеттер, чтобы он делил val на 2, и привяжите это новое значение к переменной DivideByTwo:
set(val) {
this.count = val
this.divideByTwo = val / 2
},
Полный код:
<template>
<div class="container">
<input type="number" v-model="incrementOne" />
<h3>Get input: {{ incrementOne }}</h3>
<h5>Set division: {{ divideByTwo }}</h5>
</div>
</template>
<script>
export default {
data() {
return {
count: 0,
divideByTwo: 0,
}
},
computed: {
incrementOne: {
// getter
get() {
return this.count
},
// setter
set(val) {
this.count = val;
this.divideByTwo = val / 2
},
},
},
}
</script>
Для запоминания - геттеры используются, когда мы просто получаем значение computed свойства, сеттеры - когда изменяется значение свойства, и мы хотим как то дополнительно обработать значение свойства, как в примере выше - мы получаем в сеттере новое значение, и можем производить какие-то манипуляции на его основе.