【问题标题】:vue js axios cannot read property 'data' of undefinedvue js axios无法读取未定义的属性“数据”
【发布时间】:2020-08-08 12:15:35
【问题描述】:

我试图让 json 在搜索后显示在卡片或列表中。搜索部分似乎正在工作,因为我可以看到对 API 的调用以及在控制台的搜索框中写入的文本。但没有显示任何内容,我收到此错误 TypeError: Cannot read property 'data' of undefined。我认为我的 json 路径不正确。

app.vue

  <template>
  <div id="app">
    <Header/>
    <SearchForm v-on:search="search"/>
    <SearchResults
      v-if="results.length > 0"
      v-bind:results="results"
      v-bind:reformattedSearchString="reformattedSearchString"
    />
    <Pagination
      v-if="results.length > 0"
      v-bind:prevPageToken="api.prevPageToken"
      v-bind:nextPageToken="api.nextPageToken"
      v-on:prev-page="prevPage"
      v-on:next-page="nextPage"
    />
  </div>
</template>

<script>
import Header from './components/layout/Header';
import SearchForm from './components/SearchForm';
import SearchResults from './components/SearchResults';
import Pagination from './components/Pagination';
import axios from 'axios';

export default {
  name: 'app',
  components: {
    Header,
    SearchForm,
    SearchResults,
    Pagination
  },

   data() {
    return {
      results: [],
      reformattedSearchString: '',
      api: {
        baseUrl: 'https://geodeepdive.org/api/v1/articles?',
        max: 10,
        q: '',
        prevPageToken: '',
        nextPageToken: ''
      }
    };
  },


   methods: {
    search(searchParams) {
      this.reformattedSearchString = searchParams.join(' ');
      this.api.q = searchParams.join('+');
      const { baseUrl, q, max} = this.api;
      const apiUrl = `${baseUrl}&term=${q}&title=${q}&max=${max}`;
      this.getData(apiUrl);

    },

    prevPage() {
      const { baseUrl, q, max, prevPageToken } = this.api;
      const apiUrl = `${baseUrl}&term=${q}&title=${q}&max=${max}&pageToken=${prevPageToken}`;
      this.getData(apiUrl);
    },

    nextPage() {
      const { baseUrl, q, max,nextPageToken } = this.api;
      const apiUrl = `${baseUrl}&term=${q}&title=${q}&max=${max}&pageToken=${nextPageToken}`;
      this.getData(apiUrl);
    },

    getData(apiUrl) {
      axios
        .get(apiUrl)

        .then(res => {
          this.results = res.success.data;
          this.api.prevPageToken = res.success.data.prevPageToken;
          this.api.nextPageToken = res.success.data.nextPageToken;
        })
        .catch(error => console.log(error))
    }

  }
};
</script>

搜索结果

<template>
  <div class="container mb-3">
    <div class="d-flex mb-3">
      <div class="mr-auto">
        <h3>Search Results for "{{ reformattedSearchString }}"</h3>
      </div>
      <div class="btn-group ml-auto" role="group">
        <button
          @click="changeDisplayMode('grid')"
          type="button"
          class="btn btn-outline-secondary"
          v-bind:class="{ active: displayMode === 'grid' }"
        >
          <i class="fas fa-th"></i>
        </button>
        <button
          @click="changeDisplayMode('list')"
          type="button"
          class="btn btn-outline-secondary"
          v-bind:class="{ active: displayMode === 'list' }"
        >
          <i class="fas fa-list"></i>
        </button>
      </div>
    </div>

    <div class="card-columns" v-if="displayMode === 'grid'">
      <div class="card" v-bind:key="result.link.url" v-for="result in results">
        <ArticleGridItem v-bind:result="result"/>
      </div>
    </div>
    <div v-else>
      <div class="card mb-2" v-bind:key="result.link.url" v-for="result in results">
        <ArticleListItem v-bind:result="result"/>
      </div>
    </div>
  </div>
</template>

<script>
import ArticleListItem from './ArticleListItem';
import ArticleGridItem from './ArticleGridItem';

export default {
  name: 'SearchResults',
  components: {
    ArticleListItem,
    ArticleGridItem
  },
  data() {
    return {
      title: 'Search Results',
      displayMode: 'grid'
    };
  },
  methods: {
    changeDisplayMode(displayMode) {
      this.displayMode = displayMode;
    }
  },
  props: ['results', 'reformattedSearchString']
};
</script>

json

{
success: {
    v: 1,
    data: [
       {
         type: "article",
         _gddid: "5ea0b2b3998e17af826b7f42",
         title: "The current COVID-19 wave will likely be mitigated in the second-line European countries",
         volume: "",
         journal: "Cold Spring Harbor Laboratory Press",
         link: [
            {
               url: "https://www.medrxiv.org/content/10.1101/2020.04.17.20069179v1",
               type: "publisher"
             }
         ],
         publisher: "bioRxiv",
         author: [
            {
               name: "Samuel Soubeyrand"
             }

         ],
        pages: "",
        number: "",
        identifier: [
          {
              type: "doi",
              id: "10.1101/2020.04.17.20069179"
           }
        ],
       year: "2020"
      }
    ]
 }

}

【问题讨论】:

  • axios 在响应对象上有自己的名为data 的属性。所以你需要像this.results = res.data.success.data;这样的东西。
  • 如果我没记错 res 对象包含数据对象,所以你需要像 res.data.success.data 一样访问
  • 太棒了!谢谢你的工作。如果分页部分正确,您有什么想法吗?

标签: javascript json vue.js axios


【解决方案1】:

你缺少 res.data 对象

    this.results = res.data.success.data;
    this.api.prevPageToken = res.data.success.data.prevPageToken;
    this.api.nextPageToken = res.data.success.data.nextPageToken;

【讨论】:

  • 是的,我解决了这个问题,但按钮无法正常工作。
猜你喜欢
  • 2021-06-29
  • 2019-07-13
  • 1970-01-01
  • 2020-10-09
  • 2021-08-28
  • 2018-05-08
  • 2017-04-21
  • 2022-10-19
  • 1970-01-01
相关资源
最近更新 更多