(アウトプット編)Vue.jsでグルメ検索サイトを作ってみた!

ウェブカツ

こんにちはぱるこです。

X-HACKの勉強会で習った「ぐるなびAPI」を使用してグルメ検索サイトを作成してみました。
まだ、不具合が多々ありますが、一旦終了します。バグは就職活動始めるまでに修正していきたいと思います

完成品

Vue.jsでグルメ検索
ぐるなびAPIを使ったグルメ検索サイトです(Ф∀Ф)

作品名:『Vue.jsでグルメ検索』

作成の流れ

制作にかかった時間(TOTAL:約24h)

まず、制作にかかった時間です。

1.ワイヤーフレーム 15m
2.デザイン(spのみ) 1h
3.コーディング(html/cssのみ) 1.5h
4.APIをVueで使うための方法を調べる(axios) 2h
5.Vue-cliでの実装作業 18h
6.イラストを描く 1h
7.サーバーアップ作業 30m

 

完成デザイン

TOPページ
お気に入りページ
最初はイラストを表示させます!
お気に入り登録がされていない時も
イラストを表示させます

作品の仕様

仕様

・ぐるなびAPIを使用(今回必要なAPIのデータは、【ID・店名・画像1枚・場所】)
・検索フォームに「フリーワード」を入力をすると初めは12件表示される、検索する度に追加される
・検索前やお気に入りがない時はイラストを表示させる
・お気に入りの登録・解除
・お気に入りにするとお気に入りリストに登録される
お気に入りのページでリロードすると、バグが起きる
 …TODOリストと同様ハッシュタグでリンクを取得しているのでそれが原因だと思われる
再度検索を押すと、表示されるお店が入れ替わると同時に、お気に入りリストからも消える
→再度検索し直しても、お気入りリストは保持される
・同じものを検索すると重複してしまう
・ローカルストレージを保存方法として使用しているので、同じブラウザであればデータが保持できる

本来したかった仕様

最初の仕様案

・お気に入りリストに追加したお店は、他を検索しても、お気に入りリストには保存されたままにする

お気に入りのリストに保存するために試したこと

shops[]・・・APIから取得したデータを格納する配列(今回は12件のみ)
myFavoriteShops[]・・・お気に入りに登録したお店のデータを格納する配列

APIデータが格納されている配列(shops[])と別に、お気に入りリストの配列(myFavoriteShops[])を作り、その配列にお気に入りに追加したお店データ(ID・店名・画像1枚・場所)を追加していく。

良さそうに思えたが、、、

・もう一度同じジャンルの検索し同じものを登録した時にダブって登録されてしまう。
・すでにお気に入りに登録済みのIDと同じIDを保存させないようにすることはできるが、TOPページとお気に入りリストの連動はできない。TOPページでどれがお気に入りなのか判断できない。
→結果、最初の仕様は諦めた。

コンポーネント分け

App.vue
[componetns]
-ShopSearch.vue(検索機能)
-ShopList.vue(リスト全体)
-ShopItem.vue(リストの1つ1つの部分)

苦戦した箇所

最初の仕様がそもそもまずかった。今の私のレベルでは作れなかった。
実装可能かどうかの判断が必要だと感じた。

(簡単にできると思っていた・・・)

もしいい方法があれば教えてくださいm(_ _)m

axiosを使用して、APIを持ってくる方法

ちなみに、APIからデータを持ってくること自体は、axiosを使用すれば案外簡単だった。

お天気アプリで学ぶVue.jsのAPI連携 | Tips Note by TAM
TAM のテクニカルチームがお届けする WEB技術ブログ!
Vue.jsとAxiosなら驚くほど簡単に作れる!外部APIを使ったWebアプリの実例
ReactやAngularと並び、ここのところ人気が高まっているVue.js。Axiosを組み合わせれば外部A…
Vue-CLIのプロジェクトでaxiosを使ってAPIや外部リソースからのデータを取得する | オウンドメディア | 大阪市天王寺区SOHOホームページ制作 | デザインサプライ-DesignSupply.-
webアプリケーションを作成するときに、APIなどからデータを取得するなどの要件が含まれることもあるかと思います。今回はVueのプロジェクトをVue-CLIを使って開発するときにAPIからデータを取得する例をまとめていき…

検索ボタンを押した時のメソッドのコード↓

  methods: {
    shopSearch(value){
      const params = { 
        keyid: 'ぐるなびAPIのKEYをここに入れる',
        hit_per_page: 12, ・・・HIT件数
        freeword: value,  ・・・検索フォーム入力したものを引数にとって入れてる
      };
      axios.get('https://api.gnavi.co.jp/RestSearchAPI/v3/',{params})
      .then(response => {
        this.shops = response.data.rest;
        for(let i = 0; i < this.shops.length; i++) {
          this.$set(this.shops[i], "liked", false);  ・・・shops配列に入れる時にお気に入りを追加
        }
      }).catch( error => { console.log(error); });    
    }
  }

ただし、
shops配列に格納されている店(shop)のオブジェクトに、お気に入りデータを持たせる時に注意が必要だった。

連想配列にはpushが使えない!!

todoリストを作る時は、タスクを追加するときは配列に追加することになるので、pushを使えばよかった。
しかし今回の、連想配列(オブジェクト)にプロパティを追加する場合は、pushは使えないようだ。

【JavaScript入門】pushで配列に要素を追加する方法(連想配列/pop) | 侍エンジニア塾ブログ(Samurai Blog) - プログラミング入門者向けサイト
こんにちは、ライターのマサトです!今回は、配列の要素を追加するのによく使われる「push」メソッドを学習していきましょう! この記事では、 「push」とは? 配列に要素を追加する方法 「push」の返り値について という基本的な内容から、連想配列へのデータの追加方法、配列へのオブジェクトの追加方法、「push」「po...

なので、次に私がしたのはこれだ。

this.shops = [
 {
   id:123456,
    name: 'カフェA',
    area: '東京',
    image: 'sampleA.img',
    liked; false
 },
 {
   id:546372,
    name: 'カフェB',
    area: '埼玉',
    image: 'sampleB.img',
    liked; false
 },
 {
   id:999999,
    name: 'カフェC',
    area: '神奈川',
    image: 'sampleC.img'
 }
]
for(let i = 0; i < this.shops.length; i++) {
 this.shops[i].liked = false;
}

このようにしても、ちゃんとそれぞれのオブジェクトに「liked」プロパティを追加することできた。
console.log見ても、likedプロパティの切り替え「true」⇄「false」を確認することもできた。

なのに、なぜか、表示されない。

getとsetがないことが原因だった

console.logでshopsのデータを確認してみると追加した「likedプロパティ」以外は、全てget name、set nameというものがあった。

つまりpushメソッドで追加すると、ゲッター(get)やセッター(set)も勝手に追加されるが、私が行った方法ではされないようだ。
(ウェブカツで習ったのかもしれないが、覚えていない。)

Vue.jsでビューの変更がされないときに疑うこと+主な解決策方法 - Qiita
これはcloudpack あら便利カレンダー 2018 の記事です。 Vue.jsでDOMが更新されない問題はわりとよくあたります。 ちょうど昨日社内で相談されたので、せっかくなので記事にまとめてみました。 ビューが更新されない...

上記のQiita記事を参考にすると、今回は連想配列でpushメソッドは使えないため、$setを使えば良さそうだ。

this.$set(this.shops[i], "liked", false);

こうすることで、追加したlikedプロパティにもgetとsetが追加され、表示の切り替えも行えるようになった。

改めて、アウトプットはいろんな学びがあるな〜と感じました。

追加してもお気に入りが維持できるように修正【追記(11/3)】

前回までは、shops配列に直接、APIから取得してきたデータを入れただけだったので、検索する度に消えてしまっていた。

①一時的にAPIのデータを入れるapidata配列をdataに追加で定義した。

この時、dataでapidata配列を定義しないとゲッターとセッターが追加されない(vue.jsで監視できず表示されない)ので、注意が必要。

②appdata配列に格納されているお店のデータに「お気に入りプロパティ」を追加する。
連想配列にはpushは使えないので、$setを使用。

③shop配列のデータとapidata配列を合体させる。

下記ブログに書かれている「Array.prototype.push.apply」は表示できなかったので、
concat」を使用した。

JavaScriptの配列の使い方まとめ。要素の追加,結合,取得,削除。 - Qiita
はじめに ここではJavaScriptの配列である、Arrayの基本的な使い方をまとめました。主な内容としては、要素の追加、結合、取得、削除となります。 JavaScriptの最新情報などの技術系のみをつぶやくTwitterを...

④最新のものを上に表示するために、reverseメソッドを使用

Array.prototype.reverse()
reverse() メソッドは、配列の要素を In-place アルゴリズムで反転させます。最初の要素が最後の要素に、最後の要素が最初の要素になります。
書き換えたコードがこちら
  data(){
    return{
      apidata:[] ...apiデータを入れるための一時的な配列データを追記(11/3追記分)
    }
  },  
 methods: {
    shopSearch(value){
      const params = { 
        keyid: 'ぐるなびAPIのKEYをここに入れる',
        hit_per_page: 12, ・・・HIT件数
        freeword: value,  ・・・検索フォーム入力したものを引数にとって入れてる
      };
      axios.get('https://api.gnavi.co.jp/RestSearchAPI/v3/',{params})
      .then(response => {
        this.apidata = response.data.rest;
        for(let i = 0; i < this.apidata.length; i++) {
          this.$set(this.apidata[i], "liked", false);
        }  
        this.shops = this.shops.concat(this.apidata);
        this.shops.reverse();
      }).catch( error => { console.log(error); });    
    }
  }

できていない箇所&修正箇所(11/3時点)

⬇︎転職活動始めるまでにこれらのバグを修正します!

見出し

・各ブラウザでの確認作業(主要なブラウザくらいで)
・お気に入りでリロードするとTOPのデータになってしまう。
…おそらく現在、URLのハッシュタグで切り替えを行なっているので、それを/(ルートにしたら良さそうな気がする。)
・画像がない店がある。その時はダミーの画像にするようにする
・iPhoneのアドレスバーを含めた高さを取得できていない
・検索するたびにAPIで取得したデータが消えてしまうけど、もうこのような仕様にするしかないのか??

こだわりポイント

・イラストを描いた!!(下手くそなんです。)
↓私のような下手な人間でも、書けそうなサイトを真似て描きました!

可愛い絵・イラストを書く方法!絵が苦手な人でも書けるコツとは! / 【スタディサプリ進路】高校生に関するニュースを配信
スタディサプリ進路では進路や高校生に関するニュース&コラムを配信してます。奨学金・就職・入試などの情報を、進路情報に精通した専門ライターがわかりやすく解説します。

まとめ

誰か知らん人
誰か知らん人

Vue.jsは「学習効率は非常に高い」です。

ぱるこ
ぱるこ

え、なんて?

タイトルとURLをコピーしました