How do I change the URL of the page in Nuxt SSR mode without reloading the whole page?

蓝咒 提交于 2020-01-16 18:34:50

问题


  • 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!