環境
- Vue 2.6.11
- Element UI 2.13.0
はじめに
HTMLのtableタグで作るテーブルの横幅はコンテンツの幅によって決まります。ですが、Element UIのテーブルは横幅が100%になるため、コンテンツの量が少ないとスカスカに見えてしまいます。そのため、HTMLのtableタグのようなテーブルにしたかったのですが、これが一筋縄ではいきませんでした。
テーブル全体の横幅の変更
テーブル全体の横幅はブロック要素をインライン要素に変更して、横幅の指定を初期化することによって縮めることができます。
.el-table {
display: inline-block;
width: initial;
max-width: initial;
}
HTMLのtableタグであれば、white-space: nowrap;
でセル内の折り返しを抑制できるのですが、el-tableの場合は列幅を自力で計算するしかありません。
テーブルの各列の横幅の変更
コンテンツの文字数に応じて列幅を設定するために、次のようなメソッドを作成します。
getColumnWidth (rows, headerTitle, columnName) {
let maxLength = this.getLength(headerTitle)
for (const row of rows) {
const length = this.getLength(row[columnName])
if (length > maxLength) maxLength = length
}
return maxLength * 8 + 20
}
ここで「8」は1文字の長さで「20」は左右の余白の幅です。また、全角文字は2文字とカウントしたいので、文字数を取得するメソッドも作成します。
getLength (str) {
let length = 0
for (let i = 0; i < str.length; i++) {
const c = str.charCodeAt(i)
if ((c >= 0x0 && c < 0x81) || (c === 0xf8f0) || (c >= 0xff61 && c < 0xffa0) || (c >= 0xf8f1 && c < 0xf8f4)) {
length += 1
} else {
length += 2
}
}
return length
}
ここまで作成ができたら、テーブルの各列で横幅を設定します。
<el-table-column :width="getColumnWidth(rows, '都道府県', 'prefecture')">
</el-table-column>
他の要素をテーブルの幅に合わせる
例ではページングの要素がテーブルから離れすぎているので、テーブルの右端に合わせたいです。ですが、テーブルの横幅は動的に計算しているので、事前には分かりません。こういう時はVueの$nextTick()
を使ってDOM要素がレンダリングされた後にテーブルの横幅を取得して設定します。
search () {
// テーブルに表示するデータを設定する処理
// ・・・
this.$nextTick(() => {
let width = 0
for (const child of this.$refs.table.$children) {
if (child.width) width += child.width
}
this.$refs.paging.style.width = width + 'px'
})
}
さいごに
自分でやってみて、el-tableの標準機能でできない理由が何となく分かった気がします。。