GASでWebアプリ｢映画鑑賞記録｣を作る⑤ ／ Vue.jsでダイアログボックスを表示する（前編）

# 今回やること
　今まで、本アプリの機能をBootstrapとjQueryで実現していましたが、Vue.jsに変更します。

　クライアント側（画面表示）の変更になるので、サーバ側（GAS）の修正はありません。
　変更は次の項目に沿って行いますが、今回は「サーバから…」までに対応します。

- **Vue.jsの導入**
- **サーバから取得したデータの処理を変更**
- ダイアログボックスの変更

　今回追加するファイルは、**Vuejs.html** のみです。

# Vue.jsの導入
#### Index.html
　Vue.jsを使える様にするのは、次の参照を追加するだけです。
　**◆参考サイト** [「Vue.js 公式サイト」／インストール #CDN](https://jp.vuejs.org/v2/guide/installation.html#CDN)

```html
  <!-- Vue.js -->
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.js"></script> 
```

　不要になったBootstrapとjQueryの記述は削除します。

```
  <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/themes/redmond/jquery-ui.css" />
  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/jquery-ui.min.js"></script>

  <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
```

　次のスタイルシートだけ残しておきます。

```html
  <!-- Bootstrap -->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
```

# サーバから取得したデータの処理を変更
#### javascript.html

　`searchResults()`（サーバからデータを取得する処理）の実行が成功した後に実行される`drawTable()`を、下記の様に修正します。
　以前の処理では、HTMLを意識していたので複雑でしたが、Vue.jsを使用する事により凄くシンプルになりました。
　勿論、HTMLファイル側では意識する必要がありますが、Javascriptではデータや処理を意識するだけで良いので分かりやすくなったと思います。
　`app.records`は、後述の **Vuejs.html** に定義されています。 

```javascript
  function drawTable(data) {
    let records = JSON.parse(data)
    app.records = records;
  }
```

```:以前のコード
  function drawTable(data) {
    var records = JSON.parse(data)
    var tag = '';
    for(var i = 0; i < records.length; i++) {
      tag += '<tr data-toggle="modal" data-target="#exampleModal" data-processing-type="記録更新" data-data-id="' + records[i][0] + '" ';
      tag += 'data-viewing-date="' + records[i][1] + '" data-movie-name="' + records[i][2] + '" data-first-look="' + records[i][3] + '" ';
      tag += 'data-viewing-type="' + records[i][4] + '" data-theater-name="' + records[i][5] + '">';
      tag += '<td class="col01">'+ records[i][0] + '</td>';      
      tag += '<td class="col02">'+ convDate(records[i][1]) + '</td>';
      tag += '<td class="col03">'+ records[i][2] + '</td>';
      tag += '<td class="col04">'+ records[i][3] + '</td>';
      tag += '<td class="col05">'+ records[i][4] + '</td>';
      tag += '<td class="col06">'+ records[i][5] + '</td>';
      tag += '</tr>';
    }
    $('#resultList tbody').html(tag);
  }
```
#### Vuejs.html

　Vue.jsの肝となるコードです。
　Vue.jsの詳しい説明については、他のサイトや書籍を参照してください。 :sweat_smile: 

1. 「鑑賞日」の表示変換に使用していた`convDate(date)`を、**javascript.html** から`filters:`に移動します。
1. ページ表示時の`searchResults()`の実行を、**javascript.html** から`mounted:`に移動します。

　**◆参考書籍のサイト** [「基礎から学ぶ Vue.js」mio著 C&R研究所](https://www.c-r.com/book/detail/1230)

```html
<script>  
var app = new Vue({
  el: '#app',
  data: {
    message: 'テスト',
    records: []
  },
  mounted: function() {
    searchResults();
  },
  filters: {
    convDate: function(date) {
      let day = moment(date);
      let res = (day.month() + 1) + '/' + day.date();
      return res;
    }
  }
})
</script>  
```
```:以前のコード
  $(document).ready(function() {
    searchResults();
  });
```

#### Index.html
　次の修正を行います。

1. `<body>`内全体を`<div id="app">`で括ります。
1. `<tbody>`を修正します。   
`<tr v-for="(record, index) in records"…`の`records`は、**Vuejs.html** の`records`を参照しています。    
`records`（2次元配列のデータ）を繰り返し処理する事によりテーブルを作成します。   
`record`に1行分のデータがセットされます。   
`index`に配列の添字がセットされます。使用しない場合は記述する必要はありません。   
`v-bind:key="…"`には、一意となる値をセットします。  
`<td class="col02">{{ record[1] | convDate }}</td>`の`convDate`は、Vue.jsのフィルターで **Vuejs.html** の`convDate`が実体です。
1. 今回作成した **Vuejs.html** の取込みを一番下に追加します。

```html
  <body>
    <div id="app">
    <p></p>
    <div class="container-fluid">
    <table id="resultList" class="table-striped table-bordered table-headerfixed">
        ：
      <tbody class="scrollBody">
        <tr v-for="(record, index) in records" v-bind:key="record[0]">
          <td class="col01">{{ record[0] }}</td>
          <td class="col02">{{ record[1] | convDate }}</td>
          <td class="col03">{{ record[2] }}</td>
          <td class="col04">{{ record[3] }}</td>
          <td class="col05">{{ record[4] }}</td>
          <td class="col06">{{ record[5] }}</td>
        </tr>
      </tbody>
    </table>
    </div>
      ：
      ：
  <?!= HtmlService.createHtmlOutputFromFile('Vuejs').getContent(); ?>
  
  </body>
```
```:以前の記述
  <body>
    <p></p>
    <div class="container-fluid">
    <table id="resultList" class="table-striped table-bordered table-headerfixed">
        ：
      <tbody class="scrollBody"></tbody>
    </table>
    </div>
```
# 結果
　一覧表示が完成しました。

![映画鑑賞記録.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510221/c8ea666d-cb7b-9d05-6352-87a328e3d099.png)

**◆前の記事** [GASでWebアプリ｢映画鑑賞記録｣を作る④](https://qiita.com/pump33/items/2bfcffba7a8c7be7dee3)
**◆次の記事** [GASでWebアプリ｢映画鑑賞記録｣を作る⑥](https://qiita.com/pump33/items/1ff127ad8e371cf67154)

**◆索引** [GASでWebアプリ｢映画鑑賞記録｣を作る《索引》](https://qiita.com/pump33/items/8ded0e6fd3c336e705f4)