【问题标题】:NuxtJs not passing prop to subcomponentNuxtJs 没有将 prop 传递给子组件
【发布时间】:2021-05-12 14:27:36
【问题描述】:

这是我在 pages 目录,文件夹“blogs”中名为“index.vue”的页面。

<template>
  <blog-grid :v-if="blogsList.length>0" :v-for="item in blogsList" :item="item"></blog-grid>
</template>

<script>
export default {
      async asyncData(context) {
        let $axios=context['$axios']
        let res = await $axios.$get('http://localhost:3001/blogs')
        return {
          blogsList: res.blog_items,
        }
      },
    created() {
          console.log(this.blogsList)
    }
  }
</script>

我在控制台中获得了 blogsList,一切都很好。现在我希望该组件得到它的道具“项目”,但没有。 这是 components 文件夹中的 blog-grid.vue

<template>
  <div :id="item.id"></div>
</template>

<script>
  export default {
    props: ['item'],
    data(){
      console.log(this.item)
    },
    mounted(){
      console.log(this.item)
    }
  }
</script>

我在这里得到两个 undefined 和 nuxt 错误,“item”没有正确注册。

这是一个正常的 Vue 组件行为,可以在浏览器中工作,但不能在 Nuxtjs 中工作。我通过了道具,有什么问题?

更让我烦恼的是,同样的结构也适用于另一个页面文件夹“产品”,只是不明白。

我在这里做错了什么?为什么 prop 没有通过?

UPD:如果我在 index.vue 中将变量“item”更改为“index”,则会失败并出现错误“index”未定义但在渲染期间被引用。什么鬼???

UPD:如果我将 asyncData 更改为以下内容:

return {
          blogsList: res.blog_items[0],
        }

并摆脱循环,只需传递项目然后一切顺利,没有错误。所以麻烦在于数组循环。 Typeof 显示 Object, Array 很好,我认为这里没有问题。完全被绊倒了。

UPD:我犯了最愚蠢的错误。我找到了,它就在这里

<blog-grid :v-if="blogsList.length>0" :v-for="item in blogsList" :item="item"></blog-grid>

v-if 和 v-for 是 v-bounded,不应该是。我的天哪,真是令人畏缩。

【问题讨论】:

标签: javascript node.js vue.js nuxt.js


【解决方案1】:

EDIT2:好的,这里是整个项目的github repo。它在此处的 Netlify 上托管(静态):https://use-nuxt-fetch-hook-on-api.netlify.app/
它完全是 SEO 友好的,因为它是 Nuxt 预先完成它的 SSR 工作。即便如此,它使用的是fetch() hook,你完全可以在源代码(ctrl + u)中找到,比如说“Clementina DuBuque”,因为它是在大时生成的。您还可以通过在此特定页面上禁用 Javascript 来仔细检查。

所以,总结一下你的最新评论:

  1. 因为您认为 asyncData 的劣势是错误的,因为它更适合 SEO 导向

这里的 SEO 完全相同。 SSR 部分的任何一个都没有任何好处,虽然它是构建的。

  1. 它有效且不逊色,不应仅仅因为您认为或不满意而声称其逊色。

如果您愿意,我可以在此处粘贴我自己的评论来重复我自己。在这里,一切都得到了正确的解释:
asyncdata 不如 fetch,因为它会阻塞页面,用户需要在过程中间等待,没有任何视觉反馈,也没有超级棒的体验。你可以使用 skeleton (buefy.org/documentation/骨架)和fetch,这样它将加载页面,继续加载数据并像facebook,youtube等一样显示它。您也无法访问方便的助手,您依赖自己的逻辑:更多代码,可能存在更多错误。您也不能在 asyncData 中使用它,也不能从缓存中受益 (timestamp helper)"

我之所以推荐它,是因为除了您如何处理整体数据之外,它确实具有这些好处。我对他们俩都很满意。只是说在我看来fetch 更好。不过,如果您不喜欢我的,我还是提供了两个实现的示例。 :D

  1. 我的错误不是 asyncData 与 Fetch。

您的问题确实也与 v-forv-if 有关。这就是为什么我给你写了一个没有这个错误的例子。对不起,如果我应该更多地强调它。

也就是说,我不知道您为什么对我为您提供的免费帮助如此积极。我只是想帮助你。如果你不想投票、接受或其他什么,你就去做。这里没有难过的感觉。当有人给你时间解决你的问题时,你确实有这种态度,这很遗憾。

也就是说,即使没有尝试我的一些解决方案,也没有提供与问题相关的代码,也没有建设性。所以,是的,不幸的是,如果你有这些反应,我可能会避免花更多时间。


编辑:不是 IMO 推荐的方式,但仍然是相同代码的 asyncData 变体:https://codesandbox.io/s/use-nuxt-async-data-hook-on-api-nisfj?file=/pages/index.vue


我在这里为你写了一个例子:https://codesandbox.io/s/use-nuxt-fetch-hook-on-api-5ymdz?file=/pages/index.vue

它向您展示了如何:

  • 使用fetch 钩子,不要与fetch("https://jsonplaceholder.typicode.com/users") 混淆!
  • 如何使用$fetchState.pending 助手
  • 我添加了一个 delay 函数,您可以更好地了解它的工作原理
  • 正确设置孩子身上的道具

index.vue

<template>
  <div class="p-4">
    <div v-if="$fetchState.pending" class="loading">Loading...</div>
    <span v-else-if="$fetchState.error">Error...</span>
    <display-item
      v-else
      v-for="item in items"
      :key="item.id"
      :item="item"
    ></display-item>
  </div>
</template>

<script>
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

export default {
  async fetch() {
    await delay(3000);
    const response = await fetch("https://jsonplaceholder.typicode.com/users");
    const json = await response.json();
    console.log("json", json);
    this.items = json;
  },
  data() {
    return {
      items: [],
    };
  },
};
</script>

DisplayItem.vue(孩子)

<template>
  <div>{{ item.name }}</div>
</template>

<script>
export default {
  props: {
    item: {
      type: Object,
      default: () => {},
    },
  },
};
</script>

【讨论】:

  • 抱歉拖了这么久。我看到您已将 asyncdata 更改为 fetch 挂钩。但为什么?异步数据有什么问题?文档说这两种方法都依赖于架构,我不明白为什么 asyncdata 不起作用。因此我还不能接受你的回答,因为我不明白我的例子有什么问题。
  • asyncdata 不如fetch,因为它会阻塞页面,用户需要在过程中间等待,没有任何视觉反馈,也没有超级棒的体验。您可以使用骨架 (buefy.org/documentation/skeleton) 和 fetch,这样它将加载页面,继续加载数据并像 facebook、youtube 等一样显示它。您也无法访问方便的助手,并且您依赖自己的逻辑:更多代码,可能出现更多错误。您也不能在asyncData 中使用this,也不能从缓存中受益(timestamp 助手)。想要asyncData 示例?
  • 这就是重点。我需要一个完整的 SSR,并且我需要在页面开始在浏览器中加载之前准备好该页面。否则我根本不会使用 NuxtJS,只是在客户端上延迟加载所有内容。我很想看看 asyncData 的例子,谢谢。
  • fetch 也在研究 SSR。实际上,您可以在构建时制作内容,但这里可能并非如此。即使你这样做了,如果你使用asyncDatafetch,它也会以同样的方式被水合+延迟加载。我给出的差异几乎是唯一的。文档中的更多详细信息:nuxtjs.org/docs/2.x/features/data-fetching/#the-fetch-hook
  • 我明白这一切,但我需要我的内容准备好服务器。因此,在我坚持另一种方法之前,我还想了解我的示例有什么问题。两种方法都受支持和推荐,没有一种是劣质的,所以如果你解释一下我的情况有什么问题。因为在另一个像这样的文件中它一切正常,我不想在理解它之前切换。否则你会说“我不知道怎么回事,就按我的方式做吧”,这里不是这样。
【解决方案2】:

我犯了最愚蠢的错误。我找到了,它就在这里

<blog-grid :v-if="blogsList.length>0" :v-for="item in blogsList" :item="item"></blog-grid>

v-if 和 v-for 是 v-bounded,不应该是。我的天哪,真是令人畏缩。

更新了我的答案

【讨论】:

    猜你喜欢
    • 2019-11-29
    • 2018-11-16
    • 2020-05-22
    • 2019-07-25
    • 1970-01-01
    • 2019-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多