为什么重新加载一半的时间会返回空状态?

3
我正在Nuxt 2.5中为一个兴趣项目创建一个Web商店。在Vuex store中,我有一个名为 "currentCart" 的模块,其中存储了一个带有ID和产品数组的对象。我使用js-cookie将后端返回的购物车ID存储在cookie中。
我使用nuxtServerInit从后端获取购物车,然后将其存储在state中。在组件中,我尝试获取state,并显示购物车中商品的数量,如果购物车为空,则显示“0”。这会产生奇怪的结果。有一半的时间它会正确地显示有多少个产品,但Vuex dev工具告诉我cart为null。另一半时间它显示“0”。
起初,我使用middleware触发store中的一个action来设置购物车。这完全不起作用。然后我尝试使用nuxtServerInit来设置store,这实际上是可行的。显然我更改了某些东西,因为今天它出现了所描述的问题。我找不到原因造成此问题。
nuxtServerInit:
nuxtServerInit ({ commit }, { req }) {
  let cartCookie;

  // Check if there's a cookie available
  if(req.headers.cookie) {

    cartCookie = req.headers.cookie
    .split(";")
    .find(c => c.trim().startsWith("Cart="));

    // Check if there's a cookie for the cart
    if(cartCookie)
      cartCookie = cartCookie.split("=");
    else
      cartCookie = null;
  }
  // Check if the cart cookie is set
  if(cartCookie) {

    // Check if the cart cookie isn't empty
    if(cartCookie[1] != 'undefined') {
      let cartId = cartCookie[1];

      // Get the cart from the backend
      this.$axios.get(`${api}/${cartId}`)
      .then((response) => {
        let cart = response.data;
        // Set the cart in the state
        commit("cart/setCart", cart);
      });
    }
  }
  else {
    // Clear the cart in the state
    commit("cart/clearCart");
  }
},

变异:
setCart(state, cart) {
  state.currentCart = cart;
}

获取器:
currentCart(state) {
  return state.currentCart;
}

在cart.vue文件中:
if(this.$store.getters['cart/currentCart'])
  return this.$store.getters['cart/currentCart'].products.length;
else
  return 0;

状态对象:
const state = () => ({
  currentCart: null,
});

我在各个地方都加入了console.log,以检查哪里出了问题。nuxtServerInit工作正常,提交“cart/setCart”成功并具有正确的内容。在getter中,大多数情况下我得到一个null。如果我快速重新加载页面,那么在getter中我会得到正确的购物车,并且组件会得到正确的计数器。Vue dev tool显示当前购物车状态为null,即使组件显示我预期的数据。
我将状态对象更改为“currentCart:{}”,现在它大部分时间都能正常工作,但每3/4次重新加载时都会返回一个空对象。因此,显然getter在状态设置之前触发,而状态是由nuxtServerInit设置的。是这样吗?如果是,为什么会这样,并且我该如何更改它?
我没有理解的是什么?我完全困惑了。
2个回答

2

所以,你知道在Stackoverflow上输入问题并提交后,突然有了一些新的想法要尝试吗?这就是其中之一。

我编辑了问题,告诉大家当我将state对象更改为空对象时,它有时会返回一个空对象。然后我意识到,getter有时会在nuxtServerInit之前触发。文档中指出:

注意:异步nuxtServerInit操作必须返回Promise或利用async/await使nuxt服务器等待它们。

我将nuxtServerInit更改为:

最初的回答已经被修改,请参考此处的更改内容。

async nuxtServerInit ({ commit }, { req }) {
  ...
  await this.$axios.get(`${api}/${cartId}`)
  .then((response) => {
    ...
  }
  await commit("cart/clearCart");

现在Nuxt可以等待结果了。开发工具仍然显示为空状态,但我认为这是一个错误,因为我可以在应用程序的其余部分中完美地使用存储状态。

Original Answer翻译成"最初的回答"


0

让服务器等待结果

以上是简化为语句的答案。

我和@Maurits有着相同的问题,但参数略有不同。我没有使用nuxtServerInit(),而是使用Nuxt的fetch hook。无论如何,思路基本上是:你需要让服务器等待数据抓取完成。

这是我的上下文代码;我认为对于那些使用Nuxt fetch hook的人很有帮助。为了好玩,我添加了computedmounted来帮助说明fetch hook不在methods中。

失败:

(刷新浏览器时我得到了空白页面)

computed: {
    /* some stuff */
},

async fetch() {
    this.myDataGrab()
    .then( () => {
        console.log("Got the data!")
    })
},

mounted() {
    /* some stuff */
}

工作: 我忘记在函数调用前加上await!现在服务器将在完成并发送页面之前等待此操作。

async fetch() {
    await this.myDataGrab()
    .then( () => {
        console.log("Got the messages!")
    })
},

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接