За замовчуванням computed - лише для читання: значення виводиться з інших даних. Спроба записати дає попередження в консолі, і нічого не змінюється.
Записувана обчислювана властивість - об'єкт з get і set:
import { ref, computed } from 'vue';
const firstName = ref('Оля');
const lastName = ref('Коваль');
const fullName = computed({
get: () => `${firstName.value} ${lastName.value}`,
set: (value) => {
[firstName.value, lastName.value] = value.split(' ');
},
});
fullName.value = 'Іра Лі';
firstName.value; // 'Іра'
set не зберігає значення сам - він змінює вихідні дані, з яких get потім перерахує результат.
Типові застосування:
1. v-model над перетвореним значенням - наприклад, ціна в копійках у стані й у гривнях у полі:
const priceCents = ref(12550);
const priceUah = computed({
get: () => (priceCents.value / 100).toFixed(2),
set: (value) => { priceCents.value = Math.round(Number(value) * 100); },
});
<input v-model="priceUah" type="number" step="0.01">
2. Обгортка над props + emit для v-model на компоненті (до Vue 3.4 - стандартний шаблон, тепер його замінює defineModel):
const value = computed({
get: () => props.modelValue,
set: (v) => emit('update:modelValue', v),
});
3. Синхронізація з URL чи сховищем: читання з параметра запиту, запис - через router.replace.
Що варто знати:
getмає бути чистим: без побічних ефектів, запитів, змін іншого стану;setне викликається, якщо змінити значення «всередині»: для об'єктаfullName.value.x = 1змінює повернений об'єкт, а не викликає сеттер;- у Vue 3.4+
getотримує попереднє значення першим аргументом - зручно, щоб повернути той самий об'єкт, якщо нічого суттєво не змінилося, і не запускати зайві оновлення.
Докладніше в документації: Обчислювані властивості з записом