Google Books APIsで本や漫画の表紙画像を検索   / Nuxt


一年前に作ったブックレビューアプリの検索の精度を上げてポートフォリオを強化しようと思ったら2021年現在あまりにも関連情報が溢れているため、完成させてもポートフォリオとしては価値が無いと思ったので途中だけど供養します。

### [Nuxt-bookreview](https://goofy-kepler-b307aa.netlify.app/search/)

↑本のタイトルを検索し表紙を表示するところまで作ってます。

表示された画像はボタンになっていて、押すとその画像だけが表示されます。
特に意味はないのですが、これから色々と遊んでみようと思います。

![スクリーンショット 2021-03-14 19.05.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501141/b74bff84-5be7-906b-bc7c-4a8004681684.png)



# 見た目


```
<template>
  <div class="">
    <div class="text-center">
      <input class="ex-form" v-model="bookTitle" />
      <button class="ex-btn_default" @click="search">検索</button>
    </div>

    <img
      style="width:200px"
      class="m-auto mt-48 justify-center"
      v-if="buttonImage"
      v-bind:src="buttonImage"
    />

    <div v-else>
      <div class="flex-wrap justify-center">
        <div class="m-5 inline-flex" v-for="(booksArray, key) in booksArray" :key="key">
          <img
            class="inline-block ex-test"
            style="width: 150px; min-width: 150px"
            @click="doAction(booksArray)"
            v-bind:src="booksArray"
          />
        </div>
      </div>
    </div>
  </div>
</template>
```


# スクリプト

```
<script>
const axios = require("axios");
let url = "https://www.googleapis.com/books/v1/volumes?&maxResults=30&q=";
export default {
  data: function() {
    return {
      json_data: {},
      items: [],
      bookTitle: "",
      booksArray: [],
      buttonImage: ""
    };
  },
  methods: {
    doAction: function(booksArray) {
      this.buttonImage = booksArray;
    },
    list: function() {
      let booksArray = [];
      let book = [];
      for (let i = 0; i < 30; i++) {
        if (!this.items[i].volumeInfo.imageLinks) {
          continue;
        }
        book = this.items[i].volumeInfo.imageLinks.thumbnail;
        booksArray[i] = book;
        this.booksArray.push(booksArray[i]);
        console.log(booksArray);
      }
    },
    search: function() {
      this.booksArray = [];
      this.buttonImage = "";
      axios
        .get(url + this.bookTitle)
        .then(response => ((this.items = response.data.items), this.list()));
    }
  }
};
</script>
```
1. 入力フォームにタイトルを入力
1. 検索ボタンを押すとsearchメソッドが発火
1. axios.getでjson取得
1. レスポンスを変数itemsに格納
1. listメソッドを発火

## listメソッドについて

items以下に複数のvolumeinfoカラムがある。for文でそれぞれ展開し、配列booksArrayに格納する。
imageLinks以下を持たないカラムもあるので、その場合はスキップする。

## listメソッドの他の書き方
whileを使う。

```
    list: function() {
      this.booksArray = [];
      let booksArray = [];
      let book = [];
      let i = -1;
      while (true) {
        i += 1;
        if (!this.items[i].volumeInfo.imageLinks) {
          continue;
        }
        book = this.items[i].volumeInfo.imageLinks.thumbnail;
        booksArray[i] = book;
        this.booksArray.push(booksArray[i]);

        if (i == 30) {
          break;
        }
      }
    },
```

# CSS
基本はTailwindcssだが、ボタンやフォームなどのパーツはcssで書く。
Tailwindcssと差別化するために自作のcssは名前に"ex-"をつける。

```
<style>
.t-book-w {
  max-width: 150%;
}

.ex-test {
  display: flex;
  flex-wrap: wrap;
}

/* 入力フォーム */
.ex-form {
  height: 36px;
  background-color: #efefed;
  border-radius: 5px;
  font-family: "Noto Sans JP", sans-serif;
  line-height: 1.5;
  letter-spacing: 0.05em;
  padding: 8px 16px;
  outline: none;
  font-size: 14pt;
  color: #444444 !important;
  margin-top: 50px;

  width: 50% !important;
}
.ex-form:focus {
  box-shadow: 0 0 0 2px #ebd800;
  background-color: #ffffff;
}

/* ボタン */
.ex-btn_default {
  border-radius: 5px;
  background-color: #98f0ff;
  min-height: 40px;
  min-width: 160px;
  width: 160px;
  font-family: "M PLUS Rounded 1c", sans-serif;
  font-weight: Bold;
  font-size: 18px;
  letter-spacing: 0.05em;
  filter: drop-shadow(1px 3px 5px rgba(68, 68, 68, 0.1));
  outline: none;
  border-radius: 30px;
  color: white;
  padding: 1px 30px 1px 30px;
}

.ex-btn_default:hover {
  background-color: #77e6fa;
  filter: drop-shadow(1px 3px 5px rgba(68, 68, 68, 0.2));
}

.ex-btn_default:focus {
  outline: none;
}
</style>
```

# 感想
JavaScript書くの楽しい。
アニメーションとか入れて遊んでみよう、という気持ちになってきました。
<br>