Префетчинг данных — это подход, при котором необходимые для компонента данные загружаются заранее, еще до того, как пользователь откроет соответствующий маршрут. В контексте Vue Router это позволяет улучшить пользовательский опыт, снижая задержки при переходе между страницами.
beforeEnter для предзагрузки данныхКаждый маршрут в Vue Router может иметь собственный навигационный
guard. beforeEnter выполняется перед входом на маршрут и
позволяет инициировать асинхронные операции.
import { createRouter, createWebHistory } from 'vue-router';
import UserProfile from './components/UserProfile.vue';
import { fetchUserData } from './api';
const routes = [
{
path: '/user/:id',
component: UserProfile,
beforeEnter: async (to, from, next) => {
try {
const data = await fetchUserData(to.params.id);
to.meta.prefetchedData = data;
next();
} catch (error) {
next('/error');
}
}
}
];
const router = createRouter({
history: createWebHistory(),
routes
});
export default router;
В этом примере данные пользователя загружаются до отображения
компонента. Сохранение данных в to.meta позволяет
компоненту получить их сразу при монтировании, без дополнительных
запросов.
setup и Composition APIВ Composition API можно комбинировать Vue Router и асинхронную загрузку данных:
import { onBeforeRouteEnter } from 'vue-router';
import { ref } from 'vue';
import { fetchUserData } from '../api';
export default {
setup() {
const userData = ref(null);
onBeforeRouteEnter(async (to, from, next) => {
try {
const data = await fetchUserData(to.params.id);
next(vm => vm.userData = data);
} catch {
next('/error');
}
});
return { userData };
}
}
onBeforeRouteEnter предоставляет доступ к экземпляру
компонента через коллбек next(vm => ...), что позволяет
напрямую назначать предзагруженные данные в реактивные свойства.
Для маршрутов с вложенными компонентами выгодно загружать данные на уровне родителя, чтобы дочерние компоненты сразу получали необходимую информацию.
<template>
<div>
<router-view :items="items" />
</div>
</template>
<script>
import { ref, onMounted } from 'vue';
import { fetchItems } from '../api';
export default {
setup() {
const items = ref([]);
onMounted(async () => {
items.value = await fetchItems();
});
return { items };
}
}
</script>
Дочерние маршруты получают данные через props, что
позволяет избежать повторных запросов при переключении между дочерними
страницами.
Vue Router поддерживает динамический импорт компонентов, что уменьшает размер начальной сборки приложения. Префетчинг данных можно совмещать с ленивой загрузкой:
const UserProfile = () => import('./components/UserProfile.vue');
const routes = [
{
path: '/user/:id',
component: UserProfile,
beforeEnter: async (to, from, next) => {
const data = await fetchUserData(to.params.id);
to.meta.prefetchedData = data;
next();
}
}
];
Совместное использование динамического импорта и
beforeEnter позволяет минимизировать время ожидания при
переходе, поскольку одновременно загружается компонент и необходимые
данные.
Для повышения скорости отклика интерфейса можно запускать асинхронные запросы заранее, еще до того, как пользователь перейдет по ссылке:
import { fetchUserData } from '../api';
function prefetchUserData(id) {
fetchUserData(id).then(data => {
// сохранить данные в глобальном состоянии или кэше
});
}
// В шаблоне
<a @mouseenter="() => prefetchUserData(user.id)" :href="`/user/${user.id}`">Профиль</a>
Такой подход особенно полезен для навигации через меню или списки, где вероятность перехода высока. В сочетании с Vuex или Pinia можно хранить предзагруженные данные централизованно.
При предзагрузке данных важно предусматривать обработку ошибок. Если запрос не удался, маршрут можно перенаправить на страницу ошибки или показать временный state:
beforeEnter: async (to, from, next) => {
try {
const data = await fetchUserData(to.params.id);
to.meta.prefetchedData = data;
next();
} catch (error) {
next({ path: '/error', query: { message: error.message } });
}
}
Использование query-параметров позволяет передать информацию о причине сбоя и отобразить пользователю понятное сообщение.
Глобальный guard router.beforeEach позволяет
централизованно управлять предзагрузкой данных для всех маршрутов:
router.beforeEach(async (to, from, next) => {
if (to.meta.prefetch && !to.meta.prefetchedData) {
try {
const data = await fetchDataForRoute(to);
to.meta.prefetchedData = data;
} catch {
return next('/error');
}
}
next();
});
Это упрощает поддержку приложений с большим числом маршрутов, где нужно одинаково обрабатывать предварительную загрузку данных.
Префетчинг в Vue Router повышает скорость отклика и улучшает пользовательский опыт, минимизируя задержки при переходе между маршрутами. Ключевые подходы включают:
beforeEnter и глобальных guard для
асинхронной загрузки данных.onBeforeRouteEnter.Эти техники позволяют создавать приложения на Vue, где переходы между страницами происходят мгновенно, а пользователи видят контент без лишних задержек.