Vue.js＋axios＋Sheetsonで社内のお菓子管理アプリを作った

ひょんなことから、福利厚生で社内に置いてあるお菓子のリストと、そのお菓子リストにLike機能つけることになったでその時のメモ。

**要件**

- webで閲覧可能
- お菓子登録機能
- お菓子を登録するための権限
- Likeボタンを設置して押されたLike数が見れるように
- ユーザー登録機能は無し
- Likeボタンのクリックは何回できてもいい

先日記事を読んで気になっていた「**Sheetson**」を使って、googleスプレッドシートをDB代わりにして、
フロントはVue.js、スプレッドシートとのやり取りはaxiosを使ってwebアプリを作ることに。

## Sheetson

https://sheetson.com/

参考にした記事
> 観測史上最速！GoogleスプレッドシートだけでAPIが作れる「Sheetson」
> https://entry.anypicks.jp/product-sheetson/


## Googleスプレッドシートの設定
作ったスプレッドシートをSheetsonに共有。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257123/deb796b5-2270-beda-f6d0-ebf99259f5b0.png)

共有するメールアドレス
sheetson@project-id-9647564749903618942.iam.gserviceaccount.com

これだけでAPI完成！
簡単！！

## データ取得とデータ更新
Vue.jsとaxiosはCDNを使用して呼び出してます。

dataにスプレッドシートIDとシート名等を追加。

```javascript:script/index.js
data: {
  lists: [], // スプレッドシートのデータを代入する配列
  seetId: "", // スプレッドシートのIDを記述
  seetName: "", // スプレッドシートのシート名を記述
  api: "https://api.sheetson.com/v1/sheets/", // APIのURL
  timer: null
}
```

### スプレッドシートのデータ取得
SheetsonAPIのURL + スプレッドシートのシート名 + スプレッドシートのIDを指定するだけ。
簡単！！

```javascript:script/index.js
created() {
  const sheetsonUrl = this.api + this.seetName + "?spreadsheetId=" + this.seetId;
  axios.get(sheetsonUrl)
    .then((res) => {
      this.lists = res.data.results; // 取得してきたデータをlistsに代入
    })
    .catch((err) => {
      console.log(err);
    });
}
```

### スプレッドシートのデータ更新
Likeボタンが連打されたときに連打された回数分APIと通信したくなかったので、最後に押されたLikeの値をスプレッドシートに反映するように、Likeボタンが押された時にlistsの中のデータを更新する関数と、スプレッドシートを更新する関数を分けて記述。

```javascript:script/index.js
methods: {
  // Likeボタン押したときにLike数を変更する関数
  addLike(rowIndex, likeValue, arrIndex) {
    likeValue = parseFloat(likeValue.replace(/,/g, '')); // Likeが1000を超えるとカンマ(，)が入るのでそれを除去
    let newLikeValue = Number(likeValue) + 1; // 数値に変換して+1
    newLikeValue = String(newLikeValue).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,'); // 再度カンマ(，)を追加
    this.lists[arrIndex].like = newLikeValue; // +1されたLike数を再代入
    clearTimeout(this.timer);
    let _this = this;
    this.timer = setTimeout(function() {
      _this.addLikeSeetson(rowIndex, newLikeValue); // スプレッドシートの値を更新する関数を呼び出し
    }, 500);
  },
  // スプレッドシートの値を更新する関数
  addLikeSeetson(rowIndex, likeValue) {
    const apiOptions = {
      method: "PUT",
      headers: {
        "X-Sheetson-Spreadsheet-Id": this.seetId
      },
      data: {
        like: likeValue
      },
      url: this.api + this.seetName + "/" + rowIndex
    };
    axios(apiOptions)
      .then(res => {
      })
      .catch(err => {
        console.log(err);
      });
  }
}
```

## 取得したデータを表示するためのhtmlを作成。
スタイルを整えるためにBulmaを使用。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>okashi list</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.5/css/bulma.css">
</head>
<body>
  <div id="app">
    <div class="section">
      <div class="container">
        <table class="table">
          <thead>
            <tr>
              <th>番号</th>
              <th>名前</th>
              <th colspan="2">LIKE</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(item, index) in lists" :key="index">
              <td>{{ item.rowIndex }}</td>
              <td>{{ item.name }}</td>
              <td>{{ item.like }}</td>
              <td>
                <span class="button is-primary" @click="addLike(item.rowIndex, item.like, index)">
                  Like
                </span>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.0/axios.js"></script>
  <script src="./script/index.js"></script>
</body>
</html>
```

## 完成！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257123/1971999d-26eb-bd82-d3a5-8f6a631e2997.png)

**簡単！！**

初めてSheetsonを使いましたが、簡単にスプレッドシートをAPI化できました。
Sheetsonとスプレッドシートを共有するので、Sheetsonに共有していいようなデータをAPI化するんだったらすごく楽です。便利！