Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Навіщо toRef, toRefs і toValue і як писати composable, що приймає і ref, і звичайне значення?

Ці утиліти розв'язують одну проблему: як передати реактивне значення далі, не втративши реактивності.

toRefs(reactiveObj) - перетворює кожну властивість reactive-об'єкта на ref, пов'язаний з оригіналом. Головне застосування - повернути стан з composable так, щоб його можна було деструктуризувати:

function useMouse() {
  const state = reactive({ x: 0, y: 0 });
  // ...
  return toRefs(state);
}

const { x, y } = useMouse();   // x і y - ref-и, реактивні

toRef - один ref:

const title = toRef(props, 'title');   // ref, що читає props.title
const fullName = toRef(() => `${props.first} ${props.last}`);   // ref тільки для читання з геттера

toValue(source) (3.3+) - «розгорнути що завгодно»: ref - .value, геттер - результат виклику, звичайне значення - як є.

Composable, що приймає ref, геттер або значення - тип MaybeRefOrGetter:

import { ref, watchEffect, toValue, type MaybeRefOrGetter } from 'vue';

export function useFetch<T>(url: MaybeRefOrGetter<string>) {
  const data = ref<T | null>(null);

  watchEffect(async () => {
    data.value = null;
    const response = await fetch(toValue(url));   // читання всередині ефекту = залежність
    data.value = await response.json();
  });

  return { data };
}
useFetch('/api/users');                              // рядок
useFetch(userUrl);                                   // ref
useFetch(() => `/api/users/${props.id}`);           // геттер від props

Чому toValue треба викликати всередині watchEffect/computed: саме там Vue відстежує читання. Якщо розгорнути значення один раз на початку composable, зміни props.id вже не підхопляться.

Типова помилка з props:

useFetch(`/api/users/${props.id}`);   // рядок обчислено один раз - не реактивно
useFetch(() => `/api/users/${props.id}`);   // правильно

unref - старший аналог toValue, що не викликає геттери. У новому коді краще toValue.

Докладніше в документації: Утиліти реактивності

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання