Vue.js完全に理解した

2021-02-14

この記事は過去にはてなブログに書いていた記事の移植です。

はじめに

昨年の夏に株式会社いい生活という会社で行われたインターンシップに参加してVue.jsとAPIを使ったWEBアプリを1週間で作成しました。 その際行っていた開発体験がとても良かったので、インターンシップが終わった秋頃からVue.jsでなにかしらのWEBアプリを作ろうと思い、とりあえず試しに読書管理アプリを作成してみました。

https://vooks-4f56b.web.app/

https://github.com/jdkfx/vooks

まだ使えていないVue.jsの仕様などもありましたが、あまりたくさんのことを一つのプロジェクト内で試したくはないので、一旦このプロジェクトは区切りとし、次に作るWEBアプリで使ったみたかった仕様などを活用していきたいと思っています。

アーキテクチャについて

アーキテクチャ画像

ユーザーがフロントエンド側から楽天の商品検索APIを呼ぶと、フロントエンド側にjson形式で検索結果のデータが返ってきます。返ってきた検索結果のデータをパースしてリスト表示されるようにしています。ユーザーが書籍を読みたいリストや読了リストに登録する動作を行った際は、Cloud Firestoreにデータが保存されるようにしています。

詰まったところ

初めての本格的なフロントエンド開発でしたので、いろいろと詰まってしまうことがありました。特に、検索結果として返ってきたjsonのリスト表示と、emitやpropsを用いた親子コンポーネント間でのデータの受け渡しには苦戦しました。

jsonの表示

OnSearch: async function(search_form) {
  let queryOfKeyword = "";
  if(search_form['keyword'] !== null){
    this.queryOfKeyword = `&title=${search_form['keyword']}`;
  } else {
    this.queryOfKeyword = "null";
  }

  let queryOfAuthor = "";
  if(search_form['author'] !== null){
    this.queryOfAuthor = `&author=${search_form['author']}`;
  } else {
    this.queryOfAuthor = "null";
  }

  const getUrl = `https://app.rakuten.co.jp/services/api/BooksBook/Search/20170404?format=json&applicationId=${process.env.VUE_APP_RAKUTEN_API_APP_ID}${queryOfKeyword}${queryOfAuthor}`
  await this.$axios.get(getUrl).then(response => {
    console.log(response.data);
    this.items = response.data.Items;
  })
}

this.items = response.data.Items;部分で、検索して返ってくるjsonデータを代入しているつもりだったのですが、実際に動かしてみても意図した挙動に至りませんでした。そこで、友人の知恵を借り、動かせる挙動に持っていくことができました。ありがとうございます!

// 検索APIへのアクセス
callSearchAPI(query) {
  const getURL = `${baseURL}&${queryBuilder(query)}`;
  return this.$axios.get(getURL);
},

// キーワードを検索
async searchByKeyword() {
  const { data } = await this.callSearchAPI({ title: this.keyword });
  this.items = data.Items;
},

// 著者で検索
async searchByAuthor() {
  const { data } = await this.callSearchAPI({ author: this.author });
  this.items = data.Items;
},

// キーワード、著者で検索
async search() {
  const { data } = await this.callSearchAPI({
    title: this.keyword,
    author: this.author
  });
  this.items = data.Items;
},

emitとpropsの使い方について

実装していく中で、親コンポーネントから子コンポーネントを呼び出してデータのやりとりをする必要がありました。そこでemitとpropsを活用することにしました。コンポーネント間のデータのやり取りについてはドキュメントを読んでもなかなか理解が進まず、大きな悩みの種となっていました。

試行錯誤と調査の末、以下のようなコードを書いてみました。これは子コンポーネントのコードで、emitで子コンポーネントから親コンポーネントで実行したい関数を呼び出し、propsで親コンポーネントから子コンポーネントに渡して欲しいデータを受け取っています。

<template>
  <v-container fluid>
    <v-btn color="blue" v-on:click="addWishList()">読みたいリストに追加</v-btn>
    <v-dialog v-model="wishDialog" max-width="300">
      <v-card>
        <v-card-text v-if="toPropsWishFlag">{{ toPropsTitle }}」が読みたい本のリストに追加されました</v-card-text>
        <v-card-text v-else>{{ toPropsTitle }}」は既に読みたい本のリストに追加されています</v-card-text>
      </v-card>
    </v-dialog>
  </v-container>
</template>

<script>
import firebase from 'firebase';
export default {
  name: "WishButton",
  components: {},
  props: ['toPropsTitle', 'toPropsWishFlag'], // ここで親から渡してもらいたいデータをpropsでもらっている
  data() {
    return {
      wishDialog: false,
    }
  },
  methods: {
    async addWishList() {
      firebase.auth().onAuthStateChanged((user) => {
        if(user) {
          this.$emit('wish-button'); // ここでemitを使い、親で行う関数を呼び出している
          return this.wishDialog = true;
        } else {
          alert("サインインしてください");
        }
      });
    },
  },
}
</script>

感触の違いについて

インターンシップでVue.jsを触った際は、ドキュメントをしっかり活用できてなかったという後悔がありました。そこで、今回はしっかりとドキュメントを読んでコードを書くことを意識し、なるべくサンプルコードに頼らない開発を行いました。ドキュメントを活用することによって、わからないことが出てきてもドキュメントを熟読すれば大体のことは解決するようになりました。

コードを書く際に「ドキュメントをみる」という一呼吸置く作業をすることによって勢いに任せたコードを書くことが減りました。自分の考えを持ってコードを書けるようになったので、なにかしらのエラーが起きた際に「どこでエラーがでてきたのか」ということがすぐにわかるようになりました。

これからについて

Vue.jsはこれからも触っていきたいですし、Laravelとの相性もいいのでLaravelのフロント側に利用したいなと思っています。そしてフロントエンドについても、Webpackやパフォーマンスチューニングなど、もっともっと勉強したいと思うことができたのでそちらについても学んでいきたいと思います。

Article written by.
Written by
Haruki Tazoe
November 17, 1999

Copyright © 2025 - All right reserved