Композабл для загрузки
Загрузка данных из файла каждый раз устроена одинаково: реф для данных, реф для loading, реф для сообщения об ошибке и onMounted с fetch(). Меняется только файл. Это работа для композабла, у которого параметр — адрес файла:
import { onMounted, ref } from "vue";
export function useFetch(url) {
const data = ref(null);
const error = ref("");
const loading = ref(true);
onMounted(async () => {
const response = await fetch(url);
if (!response.ok) {
error.value = "Извините, не удалось загрузить данные.";
} else {
data.value = await response.json();
}
loading.value = false;
});
return { data, error, loading };
}Компонент, которому нужны данные, вызывает его с именем файла и получает три рефа:
<script setup>
import { useFetch } from "./useFetch.js";
const { data, error, loading } = useFetch("menu.json");
</script>Что стоит заметить:
onMountedработает и в композабле, и принадлежит он компоненту, который этот композабл вызывает: данные загружаются, когда этот компонент монтируется. Два компонента, которые вызываютuseFetch(), загружают каждый свой файл, каждый при своём монтировании, и у каждого своиdata,errorиloading.dataначинается сnull, что означает «пока ничего»: композабл не может знать, что лежит в файле — массив, объект или текст. Шаблон показывает список, только когдаloadingравноfalse, а к этому моменту вdataуже лежит меню.- Сообщение об ошибке общее, потому что композабл загружает что угодно.
Такие композаблы есть почти в каждом приложении на Vue, а библиотеки предлагают готовые. В VueUse, популярной коллекции композаблов, есть свой useFetch(), а ещё useLocalStorage().
Задание
- 1
Напишите
useFetch(url)вuseFetch.js: перенесите в него три рефа иonMountedизApp.vue, переименовавmenuвdata, подставивurlвместо"menu.json"и заменив сообщение об ошибке на общее:Извините, не удалось загрузить данные.Верните{ data, error, loading }. ВApp.vueимпортируйте его, достаньте рефы с помощьюconst { data, error, loading } = useFetch("menu.json");и выводите в спискеitem in data. - 2
Теперь отзывы: в
Reviews.vueзагрузитеreviews.jsonс помощьюuseFetch()и покажите каждый отзыв в видеАнна: Лучший морковный торт в городе., а пока они грузятся, выводитеЗагрузка…, как у меню.