一起使用 fetch 和 asyncData

Posted

技术标签:

【中文标题】一起使用 fetch 和 asyncData【英文标题】:Use fetch and asyncData together 【发布时间】:2021-11-09 16:06:48 【问题描述】:

我有疑问..

在我的 Nuxt 静态项目页面(Nuxt 版本 => 2.12)中,我需要快速恢复数据。

假设:

使用 asyncData,检查速度目标,因为使用 asyncData 我可以在组件渲染期间获取数据。但是这个项目有 3 种不同的 API 调用,与我设置的语言一样多,当我选择一种语言时,值会保存在 Vuex 存储中。

在这个过程的同时,语言值也保存在本地存储中,所以,如果我只使用asyncData,当页面刷新时API调用将不会正确调用保存的语言(asyncData可以'不访问本地存储)。

这里,fetch钩子进入游戏,将watch设置在store的状态语言值上,它可以触发fetch并获取正确的数据。此外,即使页面被刷新,能够读取本地存储值的 fetch 钩子也能很好地工作。

那么我为什么不只使用 fetch 挂钩呢?因为 fetch 比 asyncData 慢。

问题:

同时使用 fetch 和 asyncData 是一种反模式吗?

有没有更好的办法?

这是我的代码:

export default 
  asyncData (context) 
    const slug = (context.route.path === '/' || context.route.path === '') ? '/home' : context.route.path
    return context.app.$storyapi
      .get(`cdn/stories$slug`, 
        language: context.store.state.language.language
      ).then((res) => 
        return res.data
      ).catch((res) => 
        context.$errorMessage(res.response,
          'Sorry but this content doesn\'t extist', `Sorry, but the content called: "$context.route.name" has a problem or doesn't exist`
        )
      )
  ,
  data () 
    return 
      story: 
        content: 
      
    
  ,
  async fetch () 
    const slug = (this.$route.path === '/' || this.$route.path === '') ? '/home' : this.$route.path
    const  data  = await this.$storyapi.get(`cdn/stories$slug`, 
      language: this.$store.state.language.language
    )
    this.story = data.story
  ,
  watch: 
    '$store.state.language.language': '$fetch'
  

只是为了补充信息,我想进一步说代码运行良好,这是关于最佳实践的问题。

【问题讨论】:

asyncData 可以读取您的本地存储。您可以通过访问 VUEX 商店访问 asyncData 中的语言。那么那里是未定义的吗?也许问题出在代码上,它从本地存储填充了 VUEX 存储 我从上下文的 asyncData 访问存储:语言:context.store.state.language。但是,当我刷新页面时,我保存在本地存储中并且需要进行正确的 API 调用的存储中语言的状态被初始化,即 context.store.state.language.language = " " 而不是 context.store.state.language.language = "es"。 能否添加代码,从本地存储中填充语言存储值? 我使用一个库:vuex-persistedstate。我创建了一个 nuxt 插件: import createPersistedState from 'vuex-persistedstate' export default ( store ) => createPersistedState( key: 'vuex', paths: ['language'] )(store) 所以,在每个刷新我不会失去我的价值npmjs.com/package/vuex-persistedstate 【参考方案1】:

自从fetch()asyncData()慢? 另外,如果你真的需要重新运行一些东西,你完全可以use await this.$nuxt.refresh()。 您可能可以同时运行这两种方法,但它们可以做同样的事情,所以这有点重复,我建议只选择一个。

我不确定它在 localStorage 中的位置是一个问题,但您可能可以使用其中一个可用的包来对这些数据进行通用存储,例如:https://github.com/unjs/unstorage 如果没有,cookie 也应该足够了(服务器和客户端都可用)。

【讨论】:

嗨,kissu .. “较慢”是指在 Nuxt 的生命周期中,获取较晚。因此,举个例子,如果我必须使用 fetch 动态填充页面头部的标题,它可能会显示 undefined,直到 fetchState.pending 变为 false。 如果你在这里查看生命周期:nuxtjs.org/docs/2.x/concepts/nuxt-lifecycle#lifecycle 你注意到你确实有asyncData -> beforeCreate -> created -> fetch。创建一个实例并没有那么繁重(它不是mounted),如果beforeCreate 为空,这应该没那么重要。即使所有这些都在做事情,在周期中不会显着减慢页面速度的两个步骤:比较几毫秒(或更低)和整个 API 获取是可笑的。即使获取 SSL 证书也可能需要比周期的 2 个步骤更长的时间。不要想太多。 另外,这种优化是超细粒度的,可能会矫枉过正。如果你想在性能方面做到最好,你甚至不会使用 Nuxt 或任何框架,而只是发布超低级代码,比如二进制。如果您在亚马逊工作,可能会注意到这里和那里掌握几毫秒,但这可能不是您的情况(我假设)所以是的,编写一些简单且可写的代码,您应该是优秀的 IMO! @DanieleFalchetti 嗯,是的,我在亚马逊工作。不仅仅在开玩笑。无论如何,你是对的,我是一个完美主义者,但事实是我想把我使用的工具推到最大。使用 Nuxt,这是非常有可能的,因为它是一个很酷的框架。不管怎样,我会尽量让一个或另一个钩子有效,我还不知道哪个钩子,但可以肯定的是,只剩下一个了。非常感谢亲。

以上是关于一起使用 fetch 和 asyncData的主要内容,如果未能解决你的问题,请参考以下文章

Nuxtjs 在 asyncData 中获取 Firestore 数据

NuxtJs asyncData 的用例是啥?

如何使用 Nuxt 和 asyncData 观察路由变化

将 Fetch 与授权标头和 CORS 一起使用

如何使用 Nuxt 访问 asyncData 中的数据

如何将 window.fetch() 与 httpOnly cookie 或基本身份验证一起使用