如何修复使用Vue Apollo的应用中的零星错误?

时间:2019-08-22 17:35:52

标签: laravel vue.js apollo vue-apollo

我偶尔会收到以下错误:

  

vue.runtime.esm.js?2b0e:619 [Vue警告]:渲染错误:“ TypeError:   无法读取未定义的属性“书””

位于

  

--->在src / views / Home.vue在src / App.vue发出警告@ vue.runtime.esm.js?2b0e:619 logError @ vue.runtime.esm.js?2b0e:1884   globalHandleError @ vue.runtime.esm.js?2b0e:1879 handleError @   vue.runtime.esm.js?2b0e:1839 Vue._render @   vue.runtime.esm.js?2b0e:3544 updateComponent @   vue.runtime.esm.js?2b0e:4060获取@ vue.runtime.esm.js?2b0e:4473运行@   vue.runtime.esm.js?2b0e:4548 flushSchedulerQueue @   vue.runtime.esm.js?2b0e:4304(匿名)@   vue.runtime.esm.js?2b0e:1980 flushCallbacks @   vue.runtime.esm.js?2b0e:1906 Promise.then(异步)...

在使用Vue Apollo的应用中。

包含错误的视图为Home.vue,如下所示:

<template>
    <div class="home">
        <ApolloQuery :query="categoriesQuery">
            <template slot-scope="{ result: { data, loading }, isLoading }">
                <div v-if="isLoading">Loading...</div>
                <div v-else>
                    <a href="#" @click.prevent="selectCategory('all')" class="link-margin">All</a>
                    <a href="#" @click.prevent="selectCategory('featured')" class="link-margin">Featured</a>
                    <a href="#" v-for="category of data.categories" @click.prevent="selectCategory(category.id)" class="link-margin">
                        {{ category.id }}. {{ category.name }}
                    </a>
                </div>
            </template>
        </ApolloQuery>

        <div>
            <ApolloQuery :query="query" v-if="selectedCategory === 'all'">
                <template slot-scope="{ result: { data, loading }, isLoading }">
                    <div v-if="isLoading">Loading...</div>
                    <div v-else>
                        <div v-for="book of data.books" :key="book.id">
                            {{ book.id }}. {{ book.title }}
                        </div>
                    </div>
                </template>
            </ApolloQuery>

            <ApolloQuery :query="query" :variables="{ featured: true }" v-else-if="selectedCategory === 'featured'">
                <template slot-scope="{ result: { data, loading }, isLoading }">
                    <div v-if="isLoading">Loading...</div>
                    <div v-else>
                        <div v-for="book of data.booksByFeatured" :key="book.id">
                            {{ book.id }}. {{ book.title }}
                        </div>
                    </div>
                </template>
            </ApolloQuery>

            <ApolloQuery :query="query" :variables="{ id: selectedCategory }" v-else>
        <template slot-scope="{ result: { data, loading }, isLoading }">
          <div v-if="isLoading">Loading...</div>
          <div v-else>
            <div v-for="book of data.category.books" :key="book.id">
              {{ book.id }}. {{ book.title }}
            </div>
          </div>
        </template>
      </ApolloQuery>
        </div>
    </div>
</template>

<script>
// @ is an alias to /src
import categoriesQuery from '@/graphql/queries/Categories.gql'
import categoryQuery from '@/graphql/queries/Category.gql'
import booksQuery from '@/graphql/queries/Books.gql'
import booksFeaturedQuery from '@/graphql/queries/BooksFeatured.gql'


export default {
    name: 'home',
    components: {
    },
    data() {
        return {
            categoriesQuery,
            categoryQuery,
            booksQuery,
            booksFeaturedQuery,
            selectedCategory: 'all',
            query: booksQuery,
            categories: []
        }
    },
    methods: {
        selectCategory(category) {
            this.selectedCategory = category

            if (category === 'all') {
                this.query = booksQuery
            } else if (category === 'featured') {
                this.query = booksFeaturedQuery
            } else {
                this.query = categoryQuery
            }
        }
    },
}
</script>

<style>
    .link-margin {
        margin-right: 24px;
    }
</style>

因此,如果您使用默认名称(即“全部”)开始并单击“精选”,则它将显示精选书籍。如果在单击“功能”之后尝试单击任何其他类别,则视图将不会更新,但是可以在Vue开发工具中看到数据。控制台窗口中没有错误。

刷新并从默认设置开始,然后单击任何类别,将过滤并显示该类别中的书籍。但是,如果您单击类别,然后尝试单击“功能”,则会收到错误消息和永久的“正在加载...”消息。

这就是我尝试多种方式时得到的行为。

我尝试删除“功能”部分,尝试更改逻辑,但无济于事。查询似乎不是问题。

我也在Laracasts上问了这个问题,但尚未收到回复,所以以为我会在这里发布。

GitHub链接:

前端:https://github.com/matthew-spire/booksql-vue 后端:https://github.com/matthew-spire/booksql-laravel

1 个答案:

答案 0 :(得分:0)

Austio here.

回答了这个问题

他的答案:

In this scenario you are calling some property on something that is undefined. You can use lodash/get to prevent some of this. On our end we have created our own ApolloQuery component where we pass lodash get up as a slot prop.

<div v-for="book of data.books" :key="book.id">
<div v-for="book of data.category.books" :key="book.id">

// become this assuming that _get is the accessible lodash/get function
<div v-for="book of _get(data, 'books', [])" :key="book.id">
<div v-for="book of _get(data, 'category.books', [])" :key="book.id">