首页 > 解决方案 > “无法对任意非 POJO 进行字符串化”和“无效的道具:道具的类型检查失败”警告

问题描述

在我的项目中,我正在加载一些产品类别Prismic以显示在侧边栏中。直到今天早些时候,这一切都很好,但是我现在收到以下警告:

vue.runtime.esm.js?2b0e:619 [Vue warn]: Invalid prop: type check failed for prop "category". Expected Category, got Object 

found in

---> <SidebarItem> at components/SidebarItem.vue
       <Sidebar> at components/Sidebar.vue
         <App> at pages/index.vue
           <Nuxt>
             <Layouts/default.vue> at layouts/default.vue
               <Root>

[Vue warn]: Invalid prop: type check failed for prop "category". Expected Category, got Object 

found in

---> <SidebarSection> at components/SidebarSection.vue
       <Sidebar> at components/Sidebar.vue
         <App> at pages/index.vue
           <Nuxt>
             <Layouts/default.vue> at layouts/default.vue
               <Root>

[Vue warn]: Invalid prop: type check failed for prop "category". Expected Category, got Object 

found in

---> <SidebarItem> at components/CategoryHeader.vue
       <App> at pages/index.vue
         <Nuxt>
           <Layouts/default.vue> at layouts/default.vue
             <Root>

尽管侧边栏类别按预期显示。起初,我不明白怎么会是这样。但是,我也注意到我看到了这个警告:

WARN Cannot stringify arbitrary non-POJOs Navigation

根据这个讨论,似乎贬值库在当前版本中失败,Vuex导致这些警告不正确。我的这个结论是否正确,有什么方法可以轻松解决这些警告吗?这篇文章提到创建一个插件来修改模型,但是我不确定在哪里插入它(对于 Nuxt/Vue 等来说非常新)。

如果没有办法解决这些警告,我唯一的选择是在我的 Vuex 状态下停止使用自定义类型,而是使用常规对象吗?

对于某些上下文,这是我的 Vue 文件的样子。我相信它们都是有效的。

index.vue

<template>
  <div>
    <NavBar />
    <!-- <Header /> -->
    <main>
      <div v-if="!$fetchState.pending" class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
        <div class="flex-1 min-w-0 bg-white xl:flex">
          <Sidebar :navigation="navigation" />

          <div class="bg-white lg:min-w-0 lg:flex-1"> <!-- <Parent container /> -->
            <CategoryHeader :category="navigation.categories[0]"/>

            <div class="sm:p-6">
              <ProductGrid />
            </div>
          </div>
        </div>
      </div>
    </main>
  </div>
</template>

<script lang="ts">

...

export default {
  name: 'App',
  components: {
    Sidebar,
    NavBar,
    Header,
    CategoryHeader
  },
  data() {
    return {
      navigation: Navigation
    }
  },
  async fetch() {
      await this.fetchCategories()
      this.navigation = this.$store.getters.navigation
  },
  fetchOnServer: true,
  methods: {
      ...mapActions({ fetchCategories: 'fetchCategories'})
  }
}

Sidebar.vue

<template>
    <!-- This example requires Tailwind CSS v2.0+ -->
    <div class="xl:flex-shrink-0 xl:w-64 border-r border-gray-200 pt-5 pb-4 bg-white overflow-y-auto ">
        <h3 class="text-xl font-bold text-gray-800">{{ navigation.heading }}</h3>
        <div class="mt-5 flex-grow flex flex-col">
            <nav class="flex-1 px-2 space-y-1 bg-white" aria-label="Sidebar">
                <div v-for="(category, index) in navigation.categories" :key="index">
                    <SidebarItem v-if="!category.subcategories.length" :category="category"/>

                    <SidebarSection v-else-if="category.subcategories.length" @click="toggleExpansion(index)" :category="category"/>
                </div>
            </nav>
        </div>
    </div>
</template>

<script lang="ts">

...

export default {
    name: 'Sidebar',
    props: {
        navigation: {
            type: Navigation,
            required: true
        }
    }
}
</script>

SidebarItem.vue

<template>
    <div>
        <!-- Current: "bg-gray-100 text-gray-900", Default: "bg-white text-gray-600 hover:bg-gray-50 hover:text-gray-900" -->
        <a href="#" class="bg-gray-100 text-gray-900 group w-full flex items-center pl-2 pr-2 py-2 text-sm font-medium rounded-md">
        {{ category.name }}
        </a>
    </div>
</template>

<script lang="ts">
import Category from '@/types/category'

export default {
    name: 'SidebarItem',
    props: {
        category: {
            type: Category,
            required: true
        }
    }
}
</script>

SidebarSection.vue并且CategoryHeader.vue在道具等方面几乎相同。

标签: typescriptvue.jsnuxt.jsvuex

解决方案


关于非 POJO 的警告

我解决了将类对象转换为 POJO 的 attoJSON()函数(即函数devalue库调用)的问题。所以一个例子是:

class User {
  toJSON () {
    return { ...this } // here I make a POJO's copy of the class instance
  }
}

这是一个明确的解决方案,解决警告也很有意义。

关于对象类型的问题:您从 Vuex 商店导航 getter 获取 Object,因此此时(getter)您可以设法强制navigation.categories返回Category[]


推荐阅读