Vue.js+element uiでTableUIを遊び倒す

この記事は、[「NJC Advent Calendar 2019」](https://qiita.com/advent-calendar/2019/njc) 12月23日の記事です。
# はじめに
Vue.js＋element uiで開発をした際、element uiのTableコンポーネントを色々触ったので備忘録として書きます。~~備忘録ですみません。正直な話良いネタが思いつかなかったです~~
また、実現したいことが日本のドキュメントであまりなかったので記事で残してたら需要あるかなと。。。


# 環境
Vue.js 2.6.10
element-ui 2.13.0

#環境構築
今回は、Codepenで作成していくのでそちらの環境作成手順です。
①Settingsを開きます。
②JavaScriptタブで設定をします。
③Add External Scripts/Pensで以下のワードで検索して追加します。
　・vue
　・element-ui
⑤以下画面になっていればsave & Closeを押して設定を保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222088/68e8bf92-f043-e571-b0f0-9f32f8ee020a.png)

実際の開発環境については先人の方々の資料を参考にしてください。
・Vue.js環境構築参考
https://qiita.com/yoshi0518/items/76195d52b794c4b81816
・Elemnt UI環境構築参考
https://qiita.com/Sa2Knight/items/7386a83c2058e53f0eef

# 実際に作成してみる
今回は以下二種類の機能を実装する。
・①RowクリックイベントでRowの詳細を出す機能
・②各Rowの文字が改行しないで「...」にする機能
##簡単なTable
Basic tableをそのまま作成する。公式サイト参考[Table](https://element.eleme.io/#/en-US/component/table)


```html:html
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<div id="app">
  <template>
    <el-table
      :data="tableData"
      style="width: 100%"
  >
      <el-table-column
        prop="date"
        label="Date"
        width="180">
      </el-table-column>
      <el-table-column
        prop="name"
        label="Name"
        width="180">
      </el-table-column>
      <el-table-column
        prop="address"
        label="Address">
      </el-table-column>
    </el-table>
  </template>
</div>
```
```css:CSS
#app{
  width: 600px;
}
```
```javascript:main.js
Vue.config.devtools = true;

new Vue({
  el: '#app',
   data() {
        return {
          tableData: [{
            date: '2016-05-03',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles'
          }, {
            date: '2016-05-02',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles'
          }, {
            date: '2016-05-04',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles'
          }, {
            date: '2016-05-01',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles'
          }]
        }
      }
});

```
## ①RowクリックイベントでRowの詳細を出す
###やりたいこと
[expandable-row](https://element.eleme.io/#/en-US/component/table#expandable-row)を用いることで以下画像のように各Rowに詳細の表示切替ができる。しかし、公式サイトの情報は赤枠部分のクリックで実現している情報のみである。
**これを各Row全体がクリックされても表示切替ができるようにする。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222088/481863a3-3ff6-12e7-119e-e002d2eb3275.png)

###実装
```html:html
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<div id="app">
  <template>
    <el-table
      :data="tableData"
      style="width: 100%"
      @row-click="rowClicked"
      ref="tableData"
      id="clickable-rows"
    >
      <el-table-column type="expand">
        <template slot-scope="props">
          Old: {{ props.row.details.old }}<br>
          Like: {{ props.row.details.like }}<br>
          DisLike: {{ props.row.details.dislike }}<br>
        </template>
      </el-table-column>
      <el-table-column
        prop="date"
        label="Date"
        width="180">
      </el-table-column>
      <el-table-column
        prop="name"
        label="Name"
        width="180">
      </el-table-column>
      <el-table-column
        prop="address"
        label="Address">
      </el-table-column>
    </el-table>
  </template>
</div>
```
```css:css
#app{
  width: 600px;
}
.clickable-rows {
  tbody tr td {
    cursor: pointer;
  }
}
.el-table__expanded-cell {
    cursor: default;
  }
}
```
```javascript:main.js
Vue.config.devtools = true;

new Vue({
  el: '#app',
  methods: {
      rowClicked(row) {
        this.$refs.tableData.toggleRowExpansion(row);
      }
   },
   data() {
        return {
          tableData: [{
            date: '2016-05-03',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles',
            details: {
              old: '16 years old',
              like: 'play Baseball',
              dislike: 'Math'
            }
          }, {
            date: '2016-05-02',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles',
            details: {
              old: '16 years old',
              like: 'play Baseball',
              dislike:'Math'
            }
          }, {
            date: '2016-05-04',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles'
          }, {
            date: '2016-05-01',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles',
            details: {
              old: '16 years old',
              like: 'play Baseball',
              dislike: 'Math'
            }
          }]
        }
      }
});
```
###解説
`<el-table-column type="expand">`でexpandを設定して、そのタグ内に`<template slot-scope="props">`を記載することで、Rowクリック時に下に表示させる部分を準備する。**実際はこの時点で`type="expand"`を設定したカラムに詳細行の表示切替実装できている**が、Row全体のクリックイベントではない。
Row全体に表示切替機能を実装するには、`<el-table>`で設定した`@row-click="rowClicked"`、`ref="tableData"`を用いる。
`@row-click="rowClicked"`イベントで呼び出される際にメソッド側で選択したRow情報が引数として使用することができる。
メソッド内で`this.$refs.tableData.toggleRowExpansion(row);`を実行することによりクリックしたRowの詳細切替を実装することができる。

##②各Rowの文字が改行させないで「・・・」にする
###やりたいこと
以下画像のように文字数がカラムの幅を超えた場合に、改行せずに`「・・・」`と省略するように実装する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222088/c0ce4406-d356-71bb-27f8-914bbea7750c.png)
###実装
htmlとCSSを変更していく。

```HTML:html
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<div id="app">
  <template>
    <el-table
      :data="tableData"
      style="width: 100%"
      @row-click="rowClicked"
      ref="tableData"
      id="clickable-rows"
    >
      <el-table-column type="expand">
        <template slot-scope="props">
          Old: {{ props.row.details.old }}<br>
          Like: {{ props.row.details.like }}<br>
          DisLike: {{ props.row.details.dislike }}<br>
        </template>
      </el-table-column>
      <el-table-column
        prop="date"
        label="Date"
        width="180">
      </el-table-column>
      <el-table-column
        prop="name"
        label="Name"
        width="180">
      </el-table-column>
      <el-table-column
        label="Address">
        <template slot-scope="scope">
          <div id="textOver">
              {{ scope.row.address }}
          </div>
        </template>
      </el-table-column>
    </el-table>
  </template>
</div>
```

```css:css
#app{
  width: 600px;
  list-style: none;
}
#textOver {
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
}
.clickable-rows {
  tbody tr td {
    cursor: pointer;
  }
}
.el-table__expanded-cell {
    cursor: default;
  }
}
```
###解説
CSSで設定する。`#textOver`の設定で「・・・」を実装できる。
~~※「・・・」のやり方は調べれば結構情報落ちてます。~~
cssで設定した`#textOver`をhtmlに反映させるために、以下のように`el-table-column`を変更します。
`template slot-scope="scope"`とすることにより`el-table`で渡された`:data="tableData"`をscopeとして受け取ることでtemplateタグ内で様々なデザインを可能にすることができます。

```html:変更部分
<el-table-column
    prop="address"
    label="Address">
</el-table-column>

↓↓↓下記のように変更↓↓↓
 <el-table-column label="Address">
  <template slot-scope="scope">
    <div id="textOver">
      {{ scope.row.address }}
  　</div>
  </template>
</el-table-column>
 ```

#成果物
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="js,result" data-user="Kento-GREEN" data-slug-hash="qBEmaVJ" 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="qBEmaVJ">
  <span>See the Pen <a href="https://codepen.io/Kento-GREEN/pen/qBEmaVJ">
  qBEmaVJ</a> by Kento_tj (<a href="https://codepen.io/Kento-GREEN">@Kento-GREEN</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

#最後に
Element UIは部品が豊富な印象を受けました。
また、実装のやりやすさであまり工数をかけたくないとか、簡単なフロントの作成に向いているなと感じました。
ただ、ちょっとしたデザインを実装する際は日本のドキュメントは少ないなと。。。
実装の方法とか忘れそうなんで、他のElement UIの部品も備忘録として残そうかと思います！！
批判、アドバイス等大歓迎です。
~~お手柔らかにお願いします。~~

#おまけ
**「②各Rowの文字が改行させないで「・・・」にする」**に関して補足。
今回の実装では、Safariで確認すると文字省略、改行せずに文字がカラムを抜きぬけて表示されるみたいです。
なぜかはわからないですが、、、
回避方法としては、それぞれの`el-table-column`にwidthをpxで設定してあげることが必要みたいです。