Vue.js・Laravel・OpenBDで本の画像を表示！書籍管理アプリで表紙の画像が表示できるようになりました。 #BookMark

どうも、たかふみです。
Vue.jsを使って本の画像表示をやってみました。
<img width="1000" alt="詳細_変更前後.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250884/958684a5-61a0-42a7-7bbf-ed42cd52756e.png">
結果、これがこうなりまして、本の詳細画面に遷移した時に書籍画像が表示されるようになっています。

Vue.js・Laravelでの画像表示については⬇︎こちらのチュートリアルのお陰でできました！
段階的に書かれていて分かりやすかったです！

■Vue + Vue Router + Vuex + Laravelで写真共有アプリを作ろう
https://www.hypertextcandy.com/vue-laravel-tutorial-introduction/

###画面
<img width="800" alt="書籍詳細画面.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250884/1e9dd23f-08ef-dcb7-3ebe-6e31fed5e0c7.png">

###コード

####■blade(該当部分のみ)

```php:show.blade.php
<div class="card-header">詳細</div>
<book-image-component></book-image-component>
```

####■VueComponent

```vue:BookImageComponent.vue
<template>
  <div v-if="photoUrl" class="photo-detail bookimage">
    <figure class="photo-detail__pane photo-detail__image">
      <img :src="photoUrl" alt="">
    </figure>
  </div>
</template>

<script>
export default {
  data () {
    return {
      photoUrl: null
    }
  },
  methods: {
    // URLから特定のパラメータを取得
    getParam(name, url) {
      if (!url) url = window.location.href;
      name = name.replace(/[\[\]]/g, "\\$&");
      var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
          results = regex.exec(url);
      if (!results) return null;
      if (!results[2]) return '';
      return decodeURIComponent(results[2].replace(/\+/g, " "));
    },
    // isbnコードから画像URLを取得
    async fetchPhoto () {
      const isbn =this.getParam('isbn');
      const response = await axios.get('https://api.openbd.jp/v1/get?isbn='+isbn)

      if(response.data[0] == null){
        this.photoUrl = null
      } else {
        this.photoUrl = response.data[0].summary.cover;
      }
    }
  },
  watch: {
    $route: {
      async handler () {
        await this.fetchPhoto()
      },
      immediate: true
    }
  }
}
</script>
```


# コード説明

##詳細画面

###手順
1.どうやって画像表示するか考える
2.書籍の画像を表示するためのVueコンポーネントを作る
3.確認

####1.どうやって画像表示するか考える
<img width="800" alt="書籍詳細画面.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250884/e501d3bd-2b93-905a-ac63-fb0489eb694d.png">

今回、画像表示をするためにOpenBDという書籍情報取得APIを使いました。
このAPIではISBNコード(書籍のIDみたいなもの)をリクエストに書籍情報を取得することができます。レスポンス内に画像URLがあるので、これを使って画面に書籍画像を表示します。
※OpenBDについては後ほど記載します。

ISBNコードはURL内のパラメータを取得してリクエストすることにしました。

####2.書籍の画像を表示するためのVueコンポーネントを作る
書籍画像以外の情報についてはLaravelの方で実装を行っていたので、画像の部分だけコンポーネント化しています。

```vue:BookImageComponent.vue
<template>
  <div v-if="photoUrl" class="photo-detail bookimage">
    <figure class="photo-detail__pane photo-detail__image">
      <img :src="photoUrl" alt="">
    </figure>
  </div>
</template>

<script>
export default {
  data () {
    return {
      photoUrl: null
    }
  },
  methods: {
    // URLから特定のパラメータを取得
    getParam(name, url) {
      if (!url) url = window.location.href;
      name = name.replace(/[\[\]]/g, "\\$&");
      var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
          results = regex.exec(url);
      if (!results) return null;
      if (!results[2]) return '';
      return decodeURIComponent(results[2].replace(/\+/g, " "));
    },
    // isbnコードから画像URLを取得
    async fetchPhoto () {
      const isbn =this.getParam('isbn');
      const response = await axios.get('https://api.openbd.jp/v1/get?isbn='+isbn)

      if(response.data[0] == null){
        this.photoUrl = null
      } else {
        this.photoUrl = response.data[0].summary.cover;
      }
    }
  },
  watch: {
    $route: {
      async handler () {
        await this.fetchPhoto()
      },
      immediate: true
    }
  }
}
</script>
```

#####■URLから特定のパラメータを取得
URLからISBNコードを取得する必要があったので、下記のサイトで紹介されていたメソッドを使いました。

>■Javascript でURLのパラメータを取得する方法
http://www-creators.com/archives/4463

```js:URLから特定のパラメータを取得
getParam(name, url) {
  if (!url) url = window.location.href;
  name = name.replace(/[\[\]]/g, "\\$&");
  var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
      results = regex.exec(url);
  if (!results) return null;
  if (!results[2]) return '';
  return decodeURIComponent(results[2].replace(/\+/g, " "));
}
```

#####■isbnコードから画像URLを取得
上のメソッドを使い、ISBNコードを変数isbnへ入れてから、openBDのAPIへリクエストを行います。`response.data[0].summary.cover`で画像urlがレスポンスされるので`this.photUrl`へ入れます。

```js:openBDへリクエスト
async fetchPhoto () {
  const isbn =this.getParam('isbn');
  const response = await axios.get('https://api.openbd.jp/v1/get?isbn='+isbn)
  if(response.data[0] == null){
    this.photoUrl = null
  } else {
    this.photoUrl = response.data[0].summary.cover;
  }
}
```

#####■photUrlをvindして画像を表示

上のメソッドで画像urlがphotUrlへ入るので、画面上に書籍画像が表示されます。

```html:photUrlをvindして画像を表示
<figure class="photo-detail__pane photo-detail__image">
  <img :src="photoUrl" alt="">
</figure>
```

####3.確認
表示されていれば成功です。

<img width="600" alt="詳細_変更後.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250884/4cf2f4eb-d56a-c16f-01b3-ba3ad777ef9f.png">


#OpenBDとは
書籍情報の取得ができるAPIです。
書籍APIにはAmazonや楽天のAPIもあるのですが、「会員登録が不要・レスポンスが高速・レスポンスに画像URLを含んでいる」ことからOpenBDに決めました。

■openBD
https://openbd.jp/

#まとめ：チュートリアルの復習にもなって良かった。
画像が表示できたことで見たい本が探しやすくなりました。
今回の実装でこちらのサイトを参考にしました。チュートリアルの復習にもなったので良かったです。

本記事の書籍管理アプリ「BookMark」は引き続き開発中です！
⬇︎こちらから実際の画面を確認できます。
https://bookmark-tm.herokuapp.com/

それでは！

# 参考URL
■Laravel + Vue での画像表示について
・Vue + Vue Router + Vuex + Laravelで写真共有アプリを作ろう
https://www.hypertextcandy.com/vue-laravel-tutorial-introduction/

■書籍APIについて
・書籍検索APIのリクエストパラメータ・取得値考察
　https://qiita.com/kanary/items/5ec45bbc01efd4388fdb

・国立国会図書館サーチが提供する書影API
https://iss.ndl.go.jp/information/api/api-lists/thumbnail_info/