У меня есть приложение Vue 3 с маршрутизатором Vue. У меня есть страница, на которой я вызываю API-вызов метода mount(), который возвращает мне некоторые данные в массиве (например, 100 элементов), затем у меня есть компоненты vue, которые отображают все элементы, полученные из API. Итак, на моей странице перечислены все элементы, и пользователь может прокручивать страницу. Все в порядке.
Затем я нажимаю на элемент (например, 70-й) и загружается единственная страница (как исключение).
Теперь я хочу вернуться, поэтому я нажимаю кнопку «Назад» в браузере, и она перезагружает мою страницу, где перечислены все элементы, но поскольку элементы не извлекаются из API, страница не имеет прокрутки, и я помещаюсь в верхнюю часть страницы. , через несколько секунд элементы извлекаются и отображаются на моей странице.
Я хочу, чтобы при возвращении я находился в правильной позиции (например, в моем примере на 70-м элементе), а не в верхней части страницы. Есть ли способ заставить Vue получать данные перед рендерингом страницы?
export default {
data() {
return {
elements: {},
}
},
mounted(){
const route = useRoute()
this.params = route.params
axios.get('/elements')
.then((response) => {
this.elements = response.data.elements
})
},
}



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Сначала оберните компонент страницы с помощью <KeepAlive>, это будет кэшировать экземпляр компонента страницы при навигации.
<!-- App.vue -->
<template>
<RouterView v-slot = "{ Component }">
<KeepAlive>
<component :is = "Component" />
</KeepAlive>
</RouterView>
</template>
Затем замените onMounted на onBeforeMount. <KeepAlive> восстановит состояние компонента и вызовет только onActivated и onMounted, поэтому elements все еще там и fetchElements больше не будет вызываться.
<script lang = "ts" setup>
import { ref, onBeforeMount } from 'vue';
import { fetchElements } from '../api';
const elements = ref<string[]>([]);
onBeforeMount(async () => {
elements.value = (await fetchElements()).data.elements;
});
</script>
<template>
<ol>
<li v-for = "(item, index) in elements" :key = "index">
{{ item }}
</li>
</ol>
<RouterLink to = "/">Go to /</RouterLink>
</template>
Сделанный. демо
Если ваш проект большой, использование <KeepAlive> на всех маршрутах может привести к проблемам с производительностью. Используйте include, чтобы кэшировать только те компоненты, которые необходимо кэшировать.
<KeepAlive include = "List">
Итак, моя проблема заключалась в том, что в моем маршрутизаторе vue у меня было настроено поведение прокрутки в верхней части страницы. Основываясь на документации Vue Router , я адаптировал ее для решения своей проблемы.
const router = createRouter({
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
return { top: 0 }
}
},
})
Спасибо. Я нашел проблему, это была скорее проблема маршрутизатора Vue с моей настройкой поведения прокрутки. Я не уверен, что на 100 % понимаю ваше решение, но мне не удалось его повторить.