【问题标题】:Nuxt page HTML is loaded before dataNuxt 页面 HTML 在数据之前加载
【发布时间】:2022-01-17 20:13:22
【问题描述】:

我有一个加载产品详细信息的动态页面,但是 html 是在数据之前加载的。

因此,当我尝试使用像图像这样的静态元素时,我收到一条错误消息,指出对象“产品”不存在。

为了解决这个问题,我给了每个动态元素 v-if="product != undefined",它确实有效,但似乎不是解决这个问题的好方法。

我正在像这样通过商店初始化我的数据

在我的页面中:

async mounted() {
  await this.fetchProducts()
},
computed: {
  product() {
    return this.$store.state.products.producten.filter(product => product.id == this.$route.params.id)[0]
  }
}

然后在我的商店:

export const state = () => ({
  producten: []
})

export const mutations = {
  setProducts(state, data) {
    state.producten = data
  }
}

export const actions = {
  async fetchProducts({ commit }) {
    await axios.get('/api/products')
      .then(res => {
        var data = res.data
        commit('setProducts', data)
      })
      .catch(err => console.log(err));
  }
}

我尝试将mounted() 替换为: beforeMount(), created(), fetch() 但似乎没有一个工作。

我也试过了:

fetch() {return this.$store.dispatch('fetchProducts')}

Loader(v-if="$fetchState.pending")
Error(v-if="$fetchState.pending")
.product(v-else)
  // Product details...

【问题讨论】:

  • 如果你尝试v-if="product.length" 会怎样(检查你是否有一个填充的数组)。如果您有一个空数组,v-if 中的条件将是虚假的,并且不会显示任何内容。此外,更喜欢在您的商店中使用async/await,而不是.then(已弃用)。最后,您需要等待数据被填充,而您的模板是同步的,并且不会在空的内容上循环。 $fetchState.pending 是一个非常好的解决方案。还有asyncData.
  • 为什么我会使用v-if="product.length" 而不是v-if="product != undefined" 更好?因为他们都工作。我只是觉得这是解决这个问题的一种非常丑陋的方式。
  • 因为产品永远不会是undefined 查看filter method 返回的内容。另一种解决方案是使用来自 lodash 的isEmpty。通常,有一个基本的虚假条件就足够了。这很丑陋,因为 JavaScript 中的类型强制很糟糕,而且我们缺乏真正的核心库来处理这类事情。
  • 如果您认为我在这里以某种方式提供了帮助,请随时对第一条评论中链接的答案投赞成票。

标签: javascript vue.js nuxt.js pug store


【解决方案1】:

您可以使用fetch hook 调度fetchProducts

<script>
export default {
  fetch() {
    return this.$store.dispatch('fetchProducts')
  }
}
</script>

在您的模板中,使用$fetchState.pending 标志来防止渲染数据元素直到准备好:

<template>
  <div>
    <Loader v-if="$fetchState.pending" />
    <Error v-else-if="$fetchState.error" />
    <Product v-else v-for="product in products" v-bind="product" />
  </div>
</template>

demo

【讨论】:

  • 我没有收到错误,但我的动态元素没有被渲染,但页面的其余部分也在 .product 内。我已经用新代码编辑了我的问题。请注意它是用哈巴狗写的。
  • @MarnixElling 我们可能需要在这里了解您的应用的实际状态。也许你在某个地方有错误?你有minimal reproducible example 或 github 链接吗?
  • @MarnixElling 您发布的小信息不足以重现问题。您可以编辑答案中的演示链接以创建复制品吗?
  • @MarnixElling 确实,如果您可以在此处复制问题而不是同步阻止我们并要求在我们的白天进入您的项目并修复问题,那会很好。
  • 好的,所以我已将我的商店文件重命名为 index.js 而不是 products.js。然后我编辑了我的计算属性以使用新名称并出于某种原因修复了它。这很奇怪,因为该对象之前确实有效,因为我可以在 vue-devtools 中看到它。
猜你喜欢
  • 1970-01-01
  • 2021-07-05
  • 2014-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-01
  • 1970-01-01
相关资源
最近更新 更多