Help us understand the problem. What is going on with this article?

GASでWebアプリ「映画鑑賞記録」を作る⑤

今回やること

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

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

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

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

Vue.jsの導入

Index.html

 Vue.jsを使える様にするのは、次の参照を追加するだけです。
 ◆参考サイト 「Vue.js 公式サイト」/インストール #CDN

  <!-- 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>

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

  <!-- 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 に定義されています。

  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:に移動します。
  2. ページ表示時のsearchResults()の実行を、javascript.html からmounted:に移動します。

 ◆参考書籍のサイト 「基礎から学ぶ Vue.js」mio著 C&R研究所

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

pump33
元COBOLER、VBやって、今GASとJavaを勉強中。 趣味は、映画鑑賞。
esm
We build applications which work well and make customers happy.
http://www.esm.co.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away