DataTablesを使って遊戯王カードの表を作る!(2)

# はじめに
こんにちは。hyです。
前回、[前の記事]()ではDatatablesを用いて遊戯王カードを表示する表を表示するアプリを作りました。
今回はそのアプリのコードについて解説していこうと思います。

# 使う技術
- DataTables
    - 簡単に綺麗な表や機能を追加できるjQueryライブラリ
- Mustache.js
    - javascriptのテンプレートエンジンで,今回は主にDataTableと併用して使います。
- Vue.js
    - javascriptのフレームワークの一つ。学習コストが低いことが特徴
- Yu-Gi-Oh! API by YGOPRODeck
    - 遊戯王カードの画像や効果などの情報を取得できるAPI
    
# 作成したアプリ
<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="hgaiji" data-slug-hash="LYpgZNX" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="datatable-app">
  <span>See the Pen <a href="https://codepen.io/hgaiji/pen/LYpgZNX">
  datatable-app</a> by higakin (<a href="https://codepen.io/hgaiji">@hgaiji</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
# 解説

以下がDataTableで表を表示するためのコードです。

```html:html
<table id="ygo_table" class="table table-bordered">
  <thead>
    <tr>
      <th>name</th>
      <th>desc</th>
    </tr>
  </thead>
  <tbody>
      
  </tbody>
</table>
```

```javascript:javascript

makeTables : function() {
      const self = this;
      const options = {
        serverSide: true,
        ajax: {
          url:"https://db.ygoprodeck.com/api/v7/cardinfo.php?level=4",
          dataSrc:function(json) {
            return json.data.slice().sort(function(){ return Math.random() - 0.5; }).slice(0, 3);
          },
        },
        columns:[
          {data:"name",render: self.renderName},
          {data:"desc"},
        ]
      }
     
      $("#ygo_table").DataTable(options);
    },
    renderName :function(data, type, row, meta) {
            const template = '<div class="container">'
                     + '  <div class="row">'
                     + '    <div class="card" style="width: 18rem;">'
                     + '      <img src={{renderSrc}} class="card-img-top" alt="カード画像">'
                     + '        <div class="card-body">'
                     + '          <p class="card-text">{{cardInfo.name}}</p>'
                     + '        </div>'
                     + '      </div>'
                     + '  </div>'
                     + '</div>';
      const view = {
        cardInfo: row,
        renderSrc :function() {
          return this.cardInfo.card_images[0].image_url;
        }
      };
      return Mustache.render(template,view);
    }
  }
```
## Datatablesで表を表示する
```javascript
 $("#ygo_table").DataTable(options);
```
この部分の記述で指定いたIDのtableに対して表を表示します。
また、表を表示する時にオプションを設定することができます。

```javascript
//Datatablesのオプションんの設定
const options = {
        serverSide: true,
        ajax: {
          url:"https://db.ygoprodeck.com/api/v7/cardinfo.php?level=4",
          dataSrc:function(json) {
            return json.data.slice().sort(function(){ return Math.random() - 0.5; }).slice(0, 3);
          },
        },
        columns:[
          {data:"name",render: self.renderName},
          {data:"desc"},
        ]
      }
     
```

それぞれのオプションについて解説します。

- [serverSide](https://datatables.net/reference/option/serverSide)
    - 表のデータの取得などをサーバ側で処理するためのオプション 
   
- [ajax](https://datatables.net/reference/option/ajax)
    - jOuery.ajaxの機能をほとんど引き続いて使用できるオプション

- [ajax.dataSrc](https://datatables.net/reference/option/ajax.dataSrc)
    - サーバから取得したデータを好きに編集するためのオプション
    - ajax.urlで取得したいサーバーのURLなどを設定
    - ex) `url:"https://db.ygoprodeck.com/api/v7/cardinfo.php?level=4"`
    - サーバから得たデータを一部だけ使用するなどが可能
    
- [columns](https://datatables.net/reference/option/columns)
    - 表の列を設定するためのオプション
    - 各列の詳細な設定を定義することができる
- [columns.render( data, type, row, meta)](https://datatables.net/reference/option/columns.render)
    - 列のデータの表示の仕方をより詳細に設定できる
    - 例えば、取得したデータの一部をリンクにするなど
    - このrender関数で Mustache.jsを使用している
    
## columns.renderとMustache.jsの併用
Datatablesのrender関数とMustache.jsを併用して使うことでより詳細なデータの設定ができます。
該当コードは以下の通りです。

```javascript
renderName :function(data, type, row, meta) {
            const template = '<div class="container">'
                     + '  <div class="row">'
                     + '    <div class="card" style="width: 18rem;">'
                     + '      <img src={{renderSrc}} class="card-img-top" alt="カード画像">'
                     + '        <div class="card-body">'
                     + '          <p class="card-text">{{cardInfo.name}}</p>'
                     + '        </div>'
                     + '      </div>'
                     + '  </div>'
                     + '</div>';
      const view = {
        cardInfo: row,
        renderSrc :function() {
          return this.cardInfo.card_images[0].image_url;
        }
      };
      return Mustache.render(template,view);
    }
```
- [`Mustache.render(template,view)`](https://github.com/janl/mustache.js/)
    - template: {{}}(口髭)を含んだテンプレート
    - view: テンプレートにレンダリングするためのデータオブジェクト
<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="hgaiji" data-slug-hash="abvPoPp" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Mustache.js sample">
  <span>See the Pen <a href="https://codepen.io/hgaiji/pen/abvPoPp">
  Mustache.js sample</a> by higakin (<a href="https://codepen.io/hgaiji">@hgaiji</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## Vue.jsの中でjQueryを使うには？
いろいろなやり方があるのですが・・
以下のように、基本的には`mounted`の中にjQueryの処理を書いてやればいいです。
`mounted`はVue.jsのライフサイクルでVueインスタンスがマウントされた(マウントされたDOMが生成された)ちょうど後に呼ばれます。なので　JQueryのようなidなどを指定して操作を行う物はこのライフサイクルフックに入れてやればいいんです。

```javascript

new Vue({
  el:"#app",
  data: {
  },
  mounted:function(){
    this.makeTables();
  },
  ///////
}
```

# まとめ
- Datatablesの表の表示方法
- Datatablesのオプションについて
- datatablesとMustache.jsの併用について
- vueとJqueryの共存方法などについて

# 最後に
何かわからないこと疑問点など会ったら気軽にコメントお願いします。
また、もっとこんなコードにしたらいいんじゃないと言うコメントがあればそちらもぜひお願いいたします。