Vue.js はまったポイントメモ(APIでデータ取得)


Vue.jsを始めて1ヶ月
色んな記事やブログのソースを参考にして、
基本をおろそかにしたらツケが回ってきたので、自戒を込めてメモにします。

親子コンポーネントでのデータ受け渡し → pagesでの表示

作りたい形

   (親コンポーネント)           (子コンポーネント)
API叩いてデータ取得(json) → 親からデータを受け取り、templateで整形
      ↑                  |
(pages A) request 'A'       返却   ← 
(pages B) request 'B'     返却   ←
(pages C) request 'C'     返却   ←
  • ページ(A~C)にアクセスしたら、親コンポーネントにリクエストを通知
  • 親コンポーネントはAxiosでサーバー側APIを叩いてデータを取得
  • 取得したデータを子コンポーネントに渡して、templateを適用してviewに返却

下記で紹介されているファクトリパターンAPIを参考にして、小規模アプリを作っています。
【Vue.js】Web API通信のデザインパターン (個人的ベストプラクティス)

ハマったポイント 「親comp → 子comp → pagesの流れでpropsすると思った」

index.vue
<template>
  <div id="app">
      <p>index.vueの内容です</p>
      <child-component/>
  </div>
</template>

<script>
  import Child from '../components/Child.vue';

  export default {
    components: {
      'child-component': Child,
    }
  }
</script>

pages配下のindex.vueではChildをimportしてきて・・・

Child.vue
<template>
  <p>子コンポーネントの内容です</p>
  <p>{{ info }}</p>
</template>

<script>
  export default  {
    name: 'child',
    props: ['info']
  }
</script>

ChildはParentからpropsで受け取って・・・

apiComponent.vue
<!--親コンポーネント-->
<template>
    <child :info="info" />
</template>

<script>
  import SpotList from './SpotList.vue'
  import Child from './Child.vue';

  import {RepositoryFactory} from '../api/RepositoryFactory'
  const SpotsRepository = RepositoryFactory.get('spots');

  export default {
    name: "api-component",
    components: {
      'spotlist': SpotList,
      'child': Child,
    },
    data() {
      return {
        isLoading: false,
        info: [], //取得したデータはinfoに格納する
      };
    },
    created() {
      this.fetch()
    },
    methods: {
      async fetch() {
        this.isLoading = true;
        const {data} = await SpotsRepository.get(); // データ取得
        this.isLoading = false;
        this.info = data;
      }
    }
  }
</script>

親はAPIから取得したデータを配列に入れて、v-bindすれば・・・

なにも表示されない(悲)

結論としてはpages側のImportを親コンポーネントに変えると表示されました。

index.vue
<template>
  <div id="app">
    <api-component />
  </div>
</template>

<script>
  import ApiComponent from '../components/apiComponent.vue';

  export default {
    components: {
      'api-component': ApiComponent,
    }
  }
</script>

キャメルケース、ケバブケースなど記載の仕方が違う?
データ反映をmountedにする?など、色々試したのですが上手く行かず、時間を費やしました。

v-bindなどが絡む場所は、コンポーネント間の関係に気をつけないといけませんね。。。