如何正确使用nuxt 2.12中的新fetch()挂钩进行SSR?

时间:2020-04-04 10:30:45

标签: vue.js fetch nuxt.js server-side-rendering

我将Nuxt更新为最新版本,因为他们引入了新的Field钩子。 在我的项目中,我正在从Prismic检索数据。以前,我使用的是FileField,但是在浏览时,渲染呈现调用fetch()的页面要花一些时间(这是它的工作方式)。

理想的解决方案是在该特定页面上导航,并在检索数据时显示加载动画。 新的asyncData()钩子似乎很合适,因为它公开了asyncData()以便检查操作状态。

现在,代码(我正在从商店的类别中检索子类别):

fetch()

这至少在客户端有效。这对正确的SSR有用吗?我的意思是,在$fetchState.pending(在服务器端被调用)中, data(){ return{ docs: [] } }, async fetch() { try{ const res = await this.$prismic.api.query(this.$prismic.predicates.at('my.category.uid', this.$route.params.sub)) const el = res.results[0] const query = await this.$prismic.api.query([this.$prismic.predicates.at('document.type','sub-category'), this.$prismic.predicates.at('my.sub-category.category', el.id)], { orderings: '[my.sub-category.position, my.sub-category.title]' }) this.docs = query.results } catch (e) { console.log(e) } } 不可访问,asyncData()也不可访问。如果这是正确的解决方案,那么在this上使用data()又有什么用呢?

3 个答案:

答案 0 :(得分:2)

如果您正在寻找一种使页面组件具有加载状态的方法,则可以将数据与asyncData一起使用,

        data(){
            return{
                loading: true
            }
        },

        async asyncData(context) {
            try{
                const res = await context.app.$prismic.api.query(context.app.$prismic.predicates.at('my.category.uid', context.app.$route.params.sub))
                const el = res.results[0]
                const query = await context.app.$prismic.api.query([context.app.$prismic.predicates.at('document.type','sub-category'), context.app.$prismic.predicates.at('my.sub-category.category', el.id)], { orderings: '[my.sub-category.position, my.sub-category.title]' })
                const docs = query.results
                const loading = false
                return {docs, el, loading}
            }   
            catch (e) {
                console.log(e)
            }
        }

如果您使用棱柱形,(并且您没有将其注册为插件),则可以通过插件将棱柱形注入上下文中

import prismic from 'prismic-javascript'

export default (inject) => {

    inject('prismic', prismic)
}

所以现在您可以在上下文中访问$ prismic。

我在处理加载状态时使用的另一种方法是使用存储模块来处理请求状态。

plugins/loading.js

export default ({store},inject) => {
    inject('changeLoading', function(){
            store.dispatch('changeLoading')
        }
    )
}

store/index.js

export const state = () => ({
    loading: false
});

export const mutations = {
    CHANGE_LOADING(state){
        state.loading = !state.loading
    }
}

export const actions = {
    changeLoading({commit}){
        commit('CHANGE_LOADING')
    }
}

export const getters = {
    getLoading(state){
        return state.loading
    }
}

现在,您将不再具有在组件内部的本地加载状态,而是在商店内部具有可更改和获取的集中状态。

        data(){
            return{
                loading: this.$store.getters['getLoading']
            }
        },

        async asyncData(context) {
            try{
                context.app.$changeLoading()
                const prismicData = await context.app.$prismic(...)
                context.app.$changeLoading()
                return {prismicData}
            }   
            catch (e) {
                context.app.$changeLoading()
                console.log(e)
            }
        }

答案 1 :(得分:1)

就SSR而言,fetch的使用方式与asyncData的使用方式相同(尽管页面转换时间有所不同)。

fetchasyncData之间的区别:

  • asyncData无权访问this,而fetch(在Nuxt> = 2.12中)有权访问。
  • asyncData的返回值设置组件的数据,而fetch的返回值不是因为fetch已经可以访问this,所以它可以直接设置data道具。
  • fetch由两个选项fetchOnServerfetchDelay控制,而asyncData没有选项。将fetchOnServer(默认为true)设置为false时,fetch挂钩仅称为客户端。
  • fetch$fetchState对象耦合,该对象提供pendingtimestamp(与获取操作的当前状态有关);和error函数(允许您显示错误消息)。请注意,asyncData参数的error函数也提供了context函数。
  • fetch允许更快的页面转换(根据RFC 27

除了上述差异之外,这两种方法的语义相同。

fetch似乎是asyncData的非正式继承者,即使两者同时存在而没有弃用通知。由于fetch提供了更多功能并解决了asyncData的问题,因此我建议只使用fetch

答案 2 :(得分:0)

已解决:Nuxt提示我一个小警告,说至少需要在2.6.0版进行“节点获取”。由于某种原因,我的位置是2.1.2。