Vue.js完全に理解した
はじめに
昨年の夏に株式会社いい生活という会社で行われたインターンシップに参加してVue.jsとAPIを使ったWEBアプリを1週間で作成しました。
そのときの開発経験が最高に良かったので、インターンシップが終わった秋頃からVue.jsでなにかしらのWEBアプリを作ろうと思い、とりあえず試しに読書管理アプリを作成してみました。
まだまだ使ったりしたいVue.jsの仕様などもありましたが、あまりたくさんのことを一つのプロジェクト内で試したくはないので、一旦このプロジェクトは区切りとし、次に作るWEBアプリで使ったみたかった仕様などを活用していきたいと思っています。
アーキテクチャについて
ユーザーがフロントエンド側から楽天の商品検索APIを呼ぶと、フロントエンド側にJSON形式でデータが返ってくるので、それをパースしてリスト表示されるようにしています。
また、ユーザーが書籍をリストに登録するなどの動作を行った際にはCloud Firestoreにデータが保存されるようにしています。
詰まったところ
初めての本格的なフロントエンド開発だったので色々と詰まってしまったところがあるが、自分が記録していた部分で詰まっていた箇所を書いてみようと思います。
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;
ここで検索して返ってくるデータを代入しているつもりだったのですが、うまく表示されなくて結構悩まされました。 Twitterでフロントエンドに強そうなイメージを持っている @uzimaru0000 君にgistを投げて対応してもらいました。
list-of-books - JSONの表示 · GitHub
結果的に以下のように書いて検索したデータを代入しています。
this.items = data.Items;
ちなみにテンプレート側で呼び出す時は、
<p>タイトル:{{ item.Item.title }}</p>
このようにしています。
$emitとpropsの使い方について
子コンポーネントを作成し、親から呼び出してデータのやりとりをする必要があったのですが、そこで$emitとpropsを活用することにしました。(これも @uzimaru0000 君に教えてもらった気がします。)
正直なことをいうと、コンポーネントの親子関係について、しっかりと理解できていなかったため、どっちで$emitを書くのか、もしくは、どっちにpropsを書くのか、しばらく悩み続けました。
Vue.jsのドキュメントはわかりやすかったのですが、このコンポーネント間のやりとりに関してのドキュメントは僕にはわかりにくかった模様です。
いろいろと調べたのち、以下のようなコードを書いてみました。これは子のコードで、親のコードを貼るのは流石に長すぎると思ったので、先述のソースコードを参照してください。
<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>
$emitで子から親で実行したい関数を呼び出し、propsで親から子に渡して欲しいデータを受け取っています。
感触の違いについて
インターンシップでVue.jsを触った際は、もちろん開発経験は楽しかったのですが、(インターンシップのブログ記事にも書いてますが)ドキュメントをしっかり活用できてなかったという後悔がありました。
なので今回はしっかりとドキュメントを見て、コードを書くことを意識し、なるべくサンプルコードに頼らない開発を行いました。
ドキュメントを活用することによって、わからないことが出てきてもドキュメントを熟読すれば大体のことは解決するようになりました。
そして、なにより、コードを書く際に「ドキュメントをみる」という一呼吸置く作業をすることによって勢いに任せたコードを書くことが減り、自分の考えを持ってコードを書けるようになったので、なにかしらのエラーが起きた際に、「どこでエラーがでてきたのか」ということがすぐにわかるようになりました。
これからについて
Vue.jsはこれからも触っていきたいですし、Laravelとの相性もいいのでLaravelのフロント側に利用したいなとは思っています。
そしてフロントエンドについても、Webpackやパフォーマンスチューニングなど、もっと勉強したいなと思うことができたのでそちらについても学んでいきたいと思います。