问题
- I am trying to build a Master Detail View where list and detail are shown side by side on desktop but on different pages on mobile as shown in the image below
- I may have between 500 to 10000 items on the list to display
- I simulated both approaches with 10000 items, feel free to change the number in server/app.js file
- When I click on an item in the list, I want the URL to change so that I click back button I go to the previous button.
- The page should not reload for doing this and it should be in SSR mode
What have I tried?
Approach 1 Dynamic Routes
Inside pages folder, I put an articles folder and _id.vue file and added a nuxt-link
This setup is VERY VERY slow, takes 20 seconds for the summary to change
Here is Approach 1 on CodeSandbox
Approach 2 Custom @nuxtjs/router module with push
Instead of the default router, I tried using the custom @nuxtjs/module
Links are selected much much faster in this approach and the URL is also changing
However if I click on item 4877, it reloads the page and the scrollbar goes back to the top of the page?
How do I keep the scrollbar wherever it is or PREVENT reloading the page?
Here is Approach 2 on CodeSandbox with Custom Router
Simple Question
- What do I do in SSR mode to change the URL as I select an item in the list without reloading the page?
- Which approach is better?
回答1:
Without reloading the page or refreshing the dom, history.pushState
can do the job.
Add this method in your component or elsewhere to do that:
addHashToLocation(params) {
history.pushState(
{},
null,
this.$route.path + '#' + encodeURIComponent(params)
)
}
So anywhere in your component, call addHashToLocation('/my/new/path')
to push the current location with query params in the window.history stack.
To add query params to current location without pushing a new history entry, use history.replaceState
instead.
Should work with Vue 2.6.10 and Nuxt 2.8.1.
Be careful with this method!
Vue Router don't know that url has changed, so it doesn't reflect url after pushState.
As Vue Router doesn't reflect change, it's not possible to get params of url. So we have to handle a different logic to pass data between routes. This can be done with dedicated Vuex store, or simply with the Nuxt global bus events.
// main component
created() {
// event fire when pushState
this.$nuxt.$on('pushState', params => {
// do your logic with params
})
},
beforeDestroy() {
this.$nuxt.$off('pushState')
},
...
// Where there are history.pushState
this.$nuxt.$emit('pushState', params)
回答2:
you can try to split page in 2 parts: "/pages/arcticles.vue" and "/pages/arcticles/_id.vue". This approach similar with your first, list not reload list. With speed i don't know what to do. Resulting page size is 15Mb.
arcticles.vue
<template>
<div class="root">
<div class="left">
<ul>
<li v-for="i in sortedArticles" :key="i.feedItemId">
<nuxt-link :to="'/articles/' + i.feedItemId">
Article {{ i.title }}
</nuxt-link>
</li>
</ul>
</div>
<nuxt-child class="right"></nuxt-child>
</div>
</template>
arcticles/_id.vue
<template>
<div>
Article {{ $route.params.id }}
</div>
</template>
来源:https://stackoverflow.com/questions/58465065/how-do-i-change-the-url-of-the-page-in-nuxt-ssr-mode-without-reloading-the-whole