【问题标题】:How do I change the URL of the page in Nuxt SSR mode without reloading the whole page?如何在 Nuxt SSR 模式下更改页面的 URL 而无需重新加载整个页面?
【发布时间】:2020-02-16 06:57:19
【问题描述】:
  • 我正在尝试构建一个主详细信息视图,其中列表和详细信息在桌面上并排显示,但在移动设备上的不同页面上显示,如下图所示
  • 列表中可能有 500 到 10000 个项目要显示
  • 我用 10000 个项目模拟了这两种方法,随意更改 server/app.js 文件中的数字

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

我尝试了什么?

接近 1 动态路线

  • 在 pages 文件夹内,我放了一个文章文件夹和 _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?
  • 哪种方法更好?

【问题讨论】:

标签: vue.js vuejs2 nuxt.js


【解决方案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 不知道 url 发生了变化,所以 pushState 后没有反映 url。

由于 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)

【讨论】:

  • 点赞!唯一的问题是我无法找出选择了哪个 id,$route.params.id 是未定义的,我想这就是你想说的 vue 路由器不知道 url 已经改变,有什么办法可以得到被选中的id,在来回移动时也不会滚动到所需的项目
  • 是的,$route.params 在 pushState 之后不反映 url。因此,您必须以不同的方式传递数据逻辑。如果这里已经有业务逻辑,则可以使用 store,但也可以使用自定义路由器事件。我将编辑我的答案以解释...
【解决方案2】:

您可以尝试将页面分成两部分:“/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>

【讨论】:

    猜你喜欢
    • 2016-01-12
    • 1970-01-01
    • 2016-02-01
    • 1970-01-01
    • 2013-04-25
    • 2020-04-20
    • 2013-06-21
    • 2015-03-23
    • 2021-03-12
    相关资源
    最近更新 更多