如何在不重新加载整个页面的情况下以Nuxt SSR模式更改页面的URL?

时间:2019-10-19 15:14:20

标签: vue.js vuejs2 nuxt.js nuxt

  • 我正在尝试构建一个主详细信息视图,其中列表和详细信息在桌面上并排显示,但在移动设备的不同页面上显示,如下图所示
  • 我可能要在列表中显示500到10000个项目
  • 我用10000个项目模拟了这两种方法,可以随时更改server / app.js文件中的数字

enter image description here

  • 单击列表中的项目时,我希望更改URL,以便单击后退按钮,然后转到上一个按钮。
  • 请勿为此页面重新加载,并且页面应处于SSR模式

我尝试了什么?

接近1条动态路由

  • 在“内部页面”文件夹中,我放置了一个articles文件夹和_id.vue文件,并添加了nuxt-link

  • 此设置非常慢,摘要更改需要20秒

  • Here is Approach 1 on CodeSandbox

通过推送方法2自定义@ nuxtjs / router模块

  • 我尝试使用自定义@ nuxtjs / module代替默认路由器

  • 通过这种方法选择链接要快得多,而且URL也在变化

  • 但是,如果我单击项目4877,它会重新加载页面,并且滚动条会回到页面顶部?

  • 我如何将滚动条保持在原处或防止重新加载页面?

  • Here is Approach 2 on CodeSandbox with Custom Router

简单问题

  • 当我在列表中选择一个项目而不重新加载页面时,如何在SSR模式下更改URL?
  • 哪种方法更好?

2 个答案:

答案 0 :(得分:1)

无需重新加载页面或刷新dom,history.pushState即可完成工作。
在您的组件或其他地方添加此方法可以做到这一点:

addHashToLocation(params) {
  history.pushState(
    {},
    null,
    this.$route.path + '#' + encodeURIComponent(params)
  )
}

因此,在组件中的任何位置,调用addHashToLocation('/my/new/path')可以使用window.history堆栈中的查询参数推送当前位置。

要将查询参数添加到当前位置而无需推送新历史记录条目,请改用history.replaceState

  

应该与Vue 2.6.10和Nuxt 2.8.1一起使用。     

     

请谨慎使用此方法!
  Vue Router不知道网址已更改,因此在pushState之后它不会反映网址。

由于Vue Router无法反映更改,因此无法获取url参数。因此,我们必须处理不同的逻辑以在路由之间传递数据。这可以通过专用的Vuex存储或Nuxt全局总线事件来完成。

// 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)

答案 1 :(得分:1)

您可以尝试将页面分为两部分:“ / pages / arcticles.vue”和“ /pages/arcticles/_id.vue”。 此方法与您的第一个类似,列表未重新加载列表。 以速度我不知道该怎么办。结果页面大小为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>