【问题标题】:NuxtJS - Cannot read property 'title' of undefined - Strange BehaviourNuxtJS - 无法读取未定义的属性“标题” - 奇怪的行为
【发布时间】:2020-05-05 01:06:52
【问题描述】:

我有一个 NuxtJS 项目链接到 DatoCMS。将显示帖子列表,单击帖子标题等并转到显示更多信息的_slug.vue 页面。当我点击帖子标题时,我被带到_slug.vue 页面,在那里我被告知'无法读取未定义的属性'标题''。但是,如果我刷新该页面,它工作正常。我可以毫无问题地在主页和帖子页面之间来回切换,直到我查看不同的帖子页面,然后问题再次发生,直到我重新加载页面。我不知道发生了什么。

页面目录中的index.vue

<template>
    <main>
        <div v-for="(post, index) in allPosts" :key="index">
            <div>
                <h3>Generic Header</h3>
                <p>Introduction paragraph</p>
            </div>
            <div>
                <div>
                    <div
                        v-for="(post, index) in allPosts">
                        <ProductCard :post="post"/>
                    </div>
                </div>
            </div>
        </div>
    </main>
</template>

<script>
import ProductCard from "@/components/ProductCard";

import gql from "graphql-tag";

export default {
    components: {
        ProductCard
    },
    apollo: {
        allPosts: gql`
            {
                allPosts {
                    title
                    text
                    slug
                }
            }
        `
    }
};
</script>

上面调用的 Components 目录中的 productCard.vue 组件在底部脚本标记中没有代码,只有一个指向 _slug.vue 文件的 nuxt 链接。

<nuxt-link :to="post.slug" prefetch>{{ post.title }}</nuxt-link>

_slug.vue 文件:

<template>
    <div>
        <h1>{{ post.title }}</h1>
        <p>{{ post.text }}</p>
    </div>
</template>

<script>
import gql from "graphql-tag";
export default {
    apollo: {
        post: {
            query: gql`
                query Post($slug: String!) {
                    post(filter: { slug: { eq: $slug } }) {
                        title
                        text
                    }
                }
            `,
            prefetch({ route }) {
                return {
                    slug: route.params.slug
                };
            },
            variables() {
                return {
                    slug: this.$route.params.slug
                };
            }
        }
    }
};
</script>

这是控制台的输出:

TypeError: Cannot read property 'title' of undefined
    at Proxy.render (webpack-internal:///./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./pages/_slug.vue?vue&type=template&id=286199e1&:9)
    at VueComponent.Vue._render (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:3542)
    at VueComponent.updateComponent (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:4049)
    at Watcher.get (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:4473)
    at new Watcher (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:4462)
    at mountComponent (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:4067)
    at VueComponent.Vue.$mount (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:8405)
    at init (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:3115)
    at merged (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:3298)
    at createComponent (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:5968)

我已经检查了有关“无法读取未定义的属性“标题”的其他答案,但不幸的是,它们在这种情况下没有帮助。

非常感谢您的帮助。 ??? 马特

【问题讨论】:

  • 之前没有使用过 apollo,但是这样的消息通常意味着数据还没有加载。在您的情况下,当您访问 post.title 时,它​​位于 _slug.vue 中。 apollo 会在 nuxt 渲染组件之前加载数据吗?如果不是,则必须将数据初始化为空对象。
  • @matt-hesington 你解决了吗?我也有这个错误。
  • @AdrianoResende 嗨,阿德里亚诺,很遗憾,我没有。
  • 我用其他方式解决了,我使用链接原生而不是来刷新页面。

标签: vue.js nuxt.js


【解决方案1】:

能否提供ProductCard.vue 组件的代码?

我的第一个假设基于您的问题:如果script 标记中没有代码,您将无法在template 部分中使用 post 属性。

script 部分添加这个sn-p:

export default {
    name: 'ProductCard',
    props: {
        post: Object
    }
}

在此处查找更多信息:https://vuejs.org/v2/guide/components-props.html

【讨论】:

    【解决方案2】:

    您不能打印未初始化的帖子对象。为避免此错误,只需通过v-if="post" 包装即可

    <template>
      <div v-if="post">
        <h1>{{ post.title }}</h1>
        <p>{{ post.text }}</p>
      </div>
    </template>
    
    

    【讨论】:

      【解决方案3】:

      我有同样的错误,我来你的帖子寻找答案 但我只是修复了它从我的 _slug.vue 中删除这部分

      data() {
        return {
          categories: [],
        }
      },
      

      这是我的链接组件

      <template>
        <div>
          <div
            class="grid w-full grid-cols-1 2xl:grid-cols-4 xl:grid-cols-4 lg:grid-cols-3 sm:grid-cols-2 gap-x-6 gap-y-12"
          >
            <!-- Product Tile Start -->
            <div v-for="link in links" :key="link.id">
              <div>
                <div class="bg-white border rounded-t-lg shadow-sm">
                  <div class="relative pb-146/3">
                    <img
                      class="absolute object-cover w-full h-full rounded-t-lg"
                      :src="getStrapiMedia(link.thumbnail.formats.large.url)"
                    />
                  </div>
      
                  <div class="relative w-full p-4 bg-white">
                    <a
                      :href="link.url"
                      target="_blank"
                      class="mb-2 text-base font-medium text-gray-800 truncate hover:text-indigo-500"
                    >
                      <p class="truncate">{{ link.title }}</p>
                    </a>
                    <p class="text-xs text-gray-600 truncate">
                      {{ link.description }}
                    </p>
                    <div class="flex flex-wrap items-center mt-6 justify-starts">
                      <span
                        v-for="tag in link.tags"
                        :key="tag.id"
                        class="px-2 py-1 mr-1 text-xs leading-none text-indigo-600 bg-indigo-200 rounded"
                        >{{ tag.name }}</span
                      >
                    </div>
                  </div>
                </div>
              </div>
            </div>
      
            <!-- Product Tile End -->
          </div>
        </div>
      </template>
      
      <script>
      import { getStrapiMedia } from '../utils/medias'
      
      export default {
        props: {
          links: {
            type: Array,
            default() {
              return []
            },
          },
        },
        methods: {
          getStrapiMedia,
        },
      }
      </script>
      

      还有我的页面/_slug.vue 我解决了这个问题

      <template>
        <div v-if="categories">
          <h1 class="w-full mb-4 text-2xl font-light text-left text-gray-600">
            {{ categories[0].name }}
          </h1>
          <Links :links="categories[0].links || []"></Links>
        </div>
      </template>
      
      <script>
      import linksQuery from '~/apollo/queries/link/categories'
      export default {
        // REMOVING THIS DATA ELEMENT FIXED MY ISSUE
        // data() {
        //   return {
        //     categories: [],
        //   }
        // },
        apollo: {
          categories: {
            prefetch: true,
            query: linksQuery,
            variables() {
              return { slug: this.$route.params.id }
            },
          },
        },
      }
      </script>
      
      

      我希望这个参考可以帮助任何其他用户

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-01-17
        • 1970-01-01
        • 2020-11-18
        • 2021-07-25
        • 1970-01-01
        • 2019-06-15
        相关资源
        最近更新 更多