【问题标题】:Initial state from Nuxt Store is undefined when using SSR使用 SSR 时未定义 Nuxt Store 的初始状态
【发布时间】:2021-01-18 21:15:42
【问题描述】:

我为我的索引页面创建了一个 Nuxt 存储,目的是初始化状态并从 API 获取一些数据以改变状态。

这是我的商店的代码,包括初始状态、突变和动作。

import Axios from "axios";

//a controller has a store that it interfaces with

// set initial state of the store
const initState = () => ({
  message: "init"
})

// make the state usable from other components
export const state = initState

//when you need to change the state
//for mutations you do commits
export const mutations = {
  setMessage(state, message) {
    state.message = message
  }, //can define more functions here
  reset(state) {
    Object.assign(state, initState())
  }
}

//when you have to do API calls (async)
//commit parameter allows us to invoke the mutation functions
//for actions you do dispatch
export const actions = {
    async nuxtServerInit({commit}) {
      const message = await Axios.get("http://localhost:5000/api/home").data;
      console.log(message);
      commit("setMessage", message) //put name of mutation as parameter + payload
    }
}

在我的 index.vue 文件中,我从 vuex 导入所需的函数并映射状态。

import Logo from '~/components/Logo.vue'
import VuetifyLogo from '~/components/VuetifyLogo.vue'
import Axios from "axios";
import {mapState, mapActions, mapMutations} from 'vuex'

export default {
  components: {
    Logo,
    VuetifyLogo
  },
  computed: mapState({
    message: state => state.message
  }),
  methods: mapMutations([
    "reset",
    "setMessage"
  ])

但是,当我加载页面(使用 Vue 开发工具)时,我的状态开始是未定义的。我可以通过“重置”方法改变状态,但没有调用我的 API 来获取数据。我在控制台中没有收到任何错误,所以我不确定是什么原因造成的。我的 API 也已启动并运行。

如何确保在加载页面时调用了 nuxtServerInit 操作?

【问题讨论】:

  • 你为什么将 nuxtServerInit 放在操作中?
  • nuxtServerInit 是一个钩子,可用于在服务器初始化时初始化某些内容,您可以从那里填充存储,也可以在页面级组件中使用 fetch 或 asyncData 钩子来执行此操作,调用来自上述钩子的存储操作将在服务器上填充您的存储。

标签: javascript vue.js vuex nuxt.js


【解决方案1】:

我相信 nuxtServerInit 操作被正确调用。我敢打赌message 的值总是未定义,因为Axios.get("http://localhost:5000/api/home") 返回的promise 没有属性data。您必须先等待结果,然后再获取它的数据。

// note extra parentheses
const message = await (Axios.get("http://localhost:5000/api/home")).data;

此外,您可能希望将 axios 调用包装在 try-catch 中,否则如果调用失败,您将获得带有堆栈跟踪的默认 Nuxt 错误页面。

  async nuxtServerInit ({ commit }: any) {
    try {
      const message = (await Axios.get('http://localhost:5000/api/home')).data;
      console.log(message);
      commit('setMessage', message); // put name of mutation as parameter + payload
    } catch (error) {
      // you could redirect to custom error page for instance
      console.error(error);
    }
  }

【讨论】:

  • 谢谢,这对我有用!用括号包装你的 Axios.get() 调用以确保承诺包含所需的属性是标准的吗?
  • 很高兴听到它:) 这是关于评估的顺序。当您拥有await Axios.get("...").data; 时,点访问器会在 await 关键字之前进行评估。所以你试图从一个类型为Promise<AxiosResponse<any>> 的对象访问data,这将不起作用。通过在括号中用 await 包装调用,您将解决承诺,结果是 AxiosResponse<any>,它具有 data 属性。如果您碰巧使用 VS Code,我建议您尝试使用 Vetur 工具,它可以立即指出此类错误。
猜你喜欢
  • 2018-02-14
  • 2018-08-22
  • 2016-04-04
  • 2020-05-09
  • 2019-07-12
  • 2021-08-10
  • 1970-01-01
  • 2019-05-08
  • 1970-01-01
相关资源
最近更新 更多