VueJS在渲染数据前等待Apollo[英] VueJS Wait on Apollo before rendering data

本文是小编为大家收集整理的关于VueJS在渲染数据前等待Apollo的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

另一个帖子中的裸露示例...

new Vue({
  el: '#app',
  data: {
    filters: {
      id: '',
      issuedBy: '',
      issuedTo: ''
    },
    items: [{id:1234,issuedBy:'Operator',issuedTo:'abcd-efgh'},{id:5678,issuedBy:'User',issuedTo:'ijkl-mnop'}]
  },
  computed: {
    filtered () {
      const filtered = this.items.filter(item => {
        return Object.keys(this.filters).every(key =>
            String(item[key]).includes(this.filters[key]))
      })
      return filtered.length > 0 ? filtered : [{
        id: '',
        issuedBy: '',
        issuedTo: ''
      }]
    }
  }
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css"/><link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.css"/><script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.min.js"></script><script src="//unpkg.com/babel-polyfill@latest/dist/polyfill.min.js"></script><script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script>

<div id="app">
<b-table striped show-empty :items="filtered">
  <template slot="top-row" slot-scope="{ fields }">
    <td v-for="field in fields" :key="field.key">
      <input v-model="filters[field.key]" :placeholder="field.label">
    </td>
  </template>
</b-table>
</div>

现在,我明白了它的工作原理,但是我还将Apollo集成了GraphQl查询.我有阿波罗居民.

所以我添加了阿波罗和安装(阻止)

    new Vue({
      el: '#app',
      apollo: {
        searchPersons: GET_PERSON
      },
      data: {
        filters: {
          name: '',
          location: '',
          relocate: ''
        },
      },
      computed: {
        filtered () {
          const filtered = this.items.filter(item => {
            return Object.keys(this.filters).every(key =>
                String(item[key]).includes(this.filters[key]))
          })
          return filtered.length > 0 ? filtered : [{
            name: '',
            location: '',
            relocate: ''
          }]
        }
      },
      mounted: function () {
          this.$apollo.queries.searchPersons.refetch().then((results) => {
            this.totalRows = results.data.searchPersons.length
            this.items = results.data.searchPersons
          })
      },
    })

如果您想知道

,这是我的get_person graphql
import { gql } from "apollo-boost";

export const GET_PERSON = gql`
  query {
    searchPersons(keyword: "", fromSource: false){
      name
      location
      relocate
      currentSalary
      resumeBody
      personemailSet {
        email
      }
      personphoneSet {
        phoneType
        verified
        number
      }
      personskillsSet {
        term
        score
        weight
      }
      personresumeattachmentSet {
        attachment
      }
      personworkplacepreferenceSet{
        name
        label
      }
    }
  }
`;

所以发生的是,该表试图加载(很好),但是它试图在返回数据之前过滤和抓住数据,因此我留下了一个错误 vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Cannot read property 'filter' of undefined"

老实说,我觉得安装可能不是正确的方法吗?

我感谢任何帮助.

谢谢!

推荐答案

因此,将其定义为一个空数组.

  data: {
    filters: {
      name: '',
      location: '',
      relocate: ''
    },
    items : []
    //---^-----
  },

本文地址:https://www.itbaoku.cn/post/1938100.html

问题描述

Bare-bones example from another post...

new Vue({
  el: '#app',
  data: {
    filters: {
      id: '',
      issuedBy: '',
      issuedTo: ''
    },
    items: [{id:1234,issuedBy:'Operator',issuedTo:'abcd-efgh'},{id:5678,issuedBy:'User',issuedTo:'ijkl-mnop'}]
  },
  computed: {
    filtered () {
      const filtered = this.items.filter(item => {
        return Object.keys(this.filters).every(key =>
            String(item[key]).includes(this.filters[key]))
      })
      return filtered.length > 0 ? filtered : [{
        id: '',
        issuedBy: '',
        issuedTo: ''
      }]
    }
  }
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css"/><link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.css"/><script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.min.js"></script><script src="//unpkg.com/babel-polyfill@latest/dist/polyfill.min.js"></script><script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script>

<div id="app">
<b-table striped show-empty :items="filtered">
  <template slot="top-row" slot-scope="{ fields }">
    <td v-for="field in fields" :key="field.key">
      <input v-model="filters[field.key]" :placeholder="field.label">
    </td>
  </template>
</b-table>
</div>

Now I get how this works, but I am also integrating apollo for a graphql query. I have apollo populate items..

So I add apollo and a mounted (to block)

    new Vue({
      el: '#app',
      apollo: {
        searchPersons: GET_PERSON
      },
      data: {
        filters: {
          name: '',
          location: '',
          relocate: ''
        },
      },
      computed: {
        filtered () {
          const filtered = this.items.filter(item => {
            return Object.keys(this.filters).every(key =>
                String(item[key]).includes(this.filters[key]))
          })
          return filtered.length > 0 ? filtered : [{
            name: '',
            location: '',
            relocate: ''
          }]
        }
      },
      mounted: function () {
          this.$apollo.queries.searchPersons.refetch().then((results) => {
            this.totalRows = results.data.searchPersons.length
            this.items = results.data.searchPersons
          })
      },
    })

here is my GET_PERSON graphql if you were wondering

import { gql } from "apollo-boost";

export const GET_PERSON = gql`
  query {
    searchPersons(keyword: "", fromSource: false){
      name
      location
      relocate
      currentSalary
      resumeBody
      personemailSet {
        email
      }
      personphoneSet {
        phoneType
        verified
        number
      }
      personskillsSet {
        term
        score
        weight
      }
      personresumeattachmentSet {
        attachment
      }
      personworkplacepreferenceSet{
        name
        label
      }
    }
  }
`;

So what happens is, the table tries to load (which is fine), but its trying to filter and grab the data before it has been returned so i am left with an error of vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Cannot read property 'filter' of undefined"

and honestly I feel like mounted may not be the right way to do this?

I appreciate any help.

Thanks!

推荐答案

So iitially define it as an empty array.

  data: {
    filters: {
      name: '',
      location: '',
      relocate: ''
    },
    items : []
    //---^-----
  },