Выполнение асинхронных методов на стороне SSR
В LiteSSR работа с асинхронными данными на стороне серверного рендеринга (SSR) упрощена благодаря предоставлению метода definePrefetchStore
. Этот метод позволяет создавать сторы, в которых асинхронные методы автоматически оборачиваются в onPrefetch
, что облегчает выполнение запросов и обработку данных как на сервере, так и на клиенте.
definePrefetchStore
Метод definePrefetchStore
предназначен для создания префетч-сторов, которые управляют асинхронными операциями в вашем приложении. Это позволяет эффективно загружать и передавать данные между сервером и клиентом, сохраняя при этом производительность и удобство разработки.
Создание Prefetch Store
Для создания префетч-стора необходимо выполнить следующие шаги:
import { ref } from "vue";
import { definePrefetchStore } from "@lite-ssr/vue";
export const useTodo = definePrefetchStore('todo', () => {
// Инициализация состояний
const todo = ref<null | any>(null);
const loading = ref<boolean>(false);
const error = ref<boolean>(false);
// Инициализация асинхронных функций
const fetchTodo = async (id: number) => {
loading.value = true;
const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${id}`);
if (response.ok) {
todo.value = await response.json();
} else {
todo.value = null;
error.value = true;
}
loading.value = false;
};
// Возвращаем состояния и функции
return {
todo,
loading,
error,
fetchTodo
}
})
Описание реализации
В приведённом примере мы создаём префетч-стор useTodo
с помощью метода definePrefetchStore
. Этот стор включает следующие компоненты:
-
Состояния (
ref
):todo
: хранит данные задачи.loading
: индикатор загрузки данных.error
: индикатор ошибки при загрузке данных.
-
Асинхронные функции:
fetchTodo
: функция для получения данных задачи по её идентификатору. Она обновляет состоянияloading
,todo
иerror
в зависимости от результата запроса.
Этот подход позволяет централизованно управлять асинхронными операциями, обеспечивая их выполнение как на сервере, так и на клиенте.
Префетч-сторы, аналогичные сторам в Pinia, требуют уникального наименования. Это необходимо для корректной передачи данных, полученных на стороне SSR, клиенту.
Использование Prefetch Store в компоненте
После создания префетч-стора, его можно использовать в компонентах для выполнения асинхронных операций и отображения данных.
<template>
<div>
<span v-if="loading">Загрузка данных...</span>
<span v-else-if="error">Не удалось загрузить данные</span>
<pre v-else>{{ serializedData }}</pre>
</div>
</template>
<script setup lang="ts">
import { computed, onMounted } from 'vue'
import { useTodo } from "./useTodo";
// Подключаем наш стор
const { fetchTodo, todo, loading, error } = useTodo();
// Сериализуем данные для удобочитаемости
const serializedData = computed(() => todo.value ? JSON.stringify(todo.value, null, '\t') : '');
// Получаем данные при монтировании компонента
await fetchTodo(1);
</script>
Описание использования
В данном примере мы используем префетч-стор useTodo
внутри компонента для выполнения асинхронного запроса и отображения данных:
- Импортируе м стор: Подключаем
useTodo
для доступа к состояниям и функциям. - Сериализация данных: Используем
computed
для преобразования полученных данных в строку для удобного отображения. - Инициация запроса: При монтировании компонента вызываем
fetchTodo
для получения данных задачи с идентификатором1
.
useAsyncData
Библиотека также предоставляет собственную альтернативу useAsyncData
из Nuxt. Однако, мы настоятельно рекомендуем не использовать этот подход из-за низкой производительности и потенциальных проблем с оптимизацией.
Пример использования useAsyncData
<!-- App.vue -->
<template>
<div>
<span v-if="loading">Загрузка данных...</span>
<span v-else-if="error">Не удалось загрузить данные</span>
<pre v-else>{{ serializedData }}</pre>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { useAsyncData } from "@lite-ssr/vue";
// Инициализируем асинхронный запрос
const fetchTodo = async (id: number) => {
const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${id}`);
if (!response.ok) throw new Error('Failed to fetch');
return response.json();
};
// Выполняем запрос
const { data, loading, error } = await useAsyncData('todo', () => fetchTodo(1));
// Сериализуем данные д ля удобочитаемости
const serializedData = computed(() => data.value ? JSON.stringify(data.value, null, '\t') : '');
</script>
Предупреждение при использовании useAsyncData
Мы крайне не рекомендуем использовать useAsyncData
из-за его низкой производительности. Для отслеживания полученных данных требуется получать путь компонента, его пропсы и другую информацию для корректной передачи данных на клиент. Вместо этого предпочтительнее использовать префетч-сторы, которые обеспечивают более эффективное управление асинхронными данными.
З аключение
Работа с асинхронными данными упрощена благодаря методам definePrefetchStore
и useAsyncData
. Однако, для обеспечения высокой производительности и оптимизации рекомендуется использовать префетч-сторы. Они предоставляют гибкий и эффективный способ управления асинхронными операциями, обеспечивая плавную работу как на сервере, так и на клиенте.