I have a Vue 3 app with vue router. I have a page where I make an API call on mounted() that return me some data in an array (like 100 elements), then I have a vue components that render every elements fetched from the API. So my page list all elements and user can scroll the page. Everthing is fine.
Then I click on a element (for example the 70th) and the single page is loaded (as excepted).
Now I want to go back, so I click on my browser back button and it reload my page where all elements are listed but since the elements are not fetched from the API the page has no scroll and it put me a the top of the page, few seconds later the elements are fetched and display on my page.
I want when I go back to be at the correct position (so in my example at the 70th elements) and not at the top of the page. Is there a way to force Vue to fetch data before rendering the page ?
export default {
data() {
return {
elements: {},
}
},
mounted(){
const route = useRoute()
this.params = route.params
axios.get('/elements')
.then((response) => {
this.elements = response.data.elements
})
},
}
2
Answers
So my problem was that in my vue router, I had the scroll behavior set to scroll at the top of the page. Based on Vue Router documentation, I adapted it to fix my problem.
First wrap your page component with
<KeepAlive>
, this will cache the page component instance when navigating.Then replace
onMounted
withonBeforeMount
.<KeepAlive>
will restore component state and trigger onlyonActivated
andonMounted
, soelements
are still there andfetchElements
won’t be called again.Done. demo
If your project is large, using
<KeepAlive>
on all routes might lead to performance issues. Useinclude
to only cache the components that need to be cached.