一起使用 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的主要内容,如果未能解决你的问题,请参考以下文章