前回までの記事はこちら。
【Vue】おれおれチュートリアル Ⅰ - 山崎屋の技術メモ
【Vue】おれおれチュートリアル Ⅱ - 山崎屋の技術メモ
【Vue】おれおれチュートリアル Ⅲ - 山崎屋の技術メモ
【Vue】おれおれチュートリアル Ⅳ - 山崎屋の技術メモ
そして現在の画面はこちら。

なんかのっぺらぼうですね。もうちょっとオシャレにしたくなってきました。
ということで、今回はデザインを見直していきたいと思います。
vue の単一ファイルコンポーネントで作られたおしゃれで便利な Element というライブラリも使用します。
Element の公式ページはこちら。
Element

- 作者: 川口和也,喜多啓介,野田陽平,手島拓也,片山真也
- 出版社/メーカー: 技術評論社
- 発売日: 2018/09/22
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る

- 作者: mio
- 出版社/メーカー: シーアンドアール研究所
- 発売日: 2018/05/29
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
タイトルをおしゃれにする
こちらのページで紹介されている、「シンプルなチェックマーク」というデザインを拝借します。
CSSのコピペだけ!おしゃれな見出しのデザイン例まとめ68選
Font Awesome というフォントを使うようなので、index.html の head タグに css へのリンクを追加します。index.html ですよ! Todo.vue と間違えないようにしましょう。
npm でインストール後、 .vue ファイル内で import して使えるようですが、上手くいかずに断念しました。
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/solid.css" integrity="sha384-VGP9aw4WtGH/uPAOseYxZ+Vz/vaTb1ehm1bwx92Fm8dTrE+3boLfF1SpAtB1z7HW" crossorigin="anonymous">
次に Todo.vue の style タグ内に css を追加します。
h1 { position: relative; line-height: 1.4; } h1:before { font-family: "Font Awesome 5 Free"; content: "\f00c"; font-size: 0.7em; left: 0; top: 0; color: #5ab9ff; }
これでタイトルに青いチェックが追加されました。

テキストボックスと追加ボタンをおしゃれにする
さぁここから Vue ライブラリの Element を使用していきます。
まず、コマンドプロンプトを使用して Element をインストールします。
npm install element-ui -save
次に main.js で Element をインポートして Vue.use します。あわせて locale と css もインポートするようですが、深い意味はよく分かっておらず、のちのち理解していくことにします。
4行追加しています。ソース中のコメントを参照してください。
import Vue from 'vue' import App from './App' import router from './router' import ElementUI from 'element-ui' // 追加! import locale from 'element-ui/locale/lang/ja' // 追加! import 'element-ui/lib/theme-chalk/index.css' // 追加! Vue.config.productionTip = false Vue.use(ElementUI,{locale}) // 追加! /* eslint-disable no-new */ new Vue({ el: '#app', router, render: h => h(App) })
Todo.vue を編集し、テキストボックスと追加ボタンのタグを Element 用のタグに変更します。
変更前
<input type="text" v-model="newTask" @keydown.enter="addTask"> <input type="button" value="追加" @click="addTask">
変更後
<el-input placeholder="追加するタスクを入力してください。" v-model="newTask" @keydown.enter.native="addTask"></el-input> <el-button type="primary" plain @click="addTask">追加</el-button>
Element のコンポーネントに置き換えるついでにテキストボックスに placeholder を設定しています。あと、 keydown.enter は keydown.enter.native にしないと動きません。なぜかは知りません。
それでは画面を表示してみます。

でっかくなっちゃった!
el-input タグは width を 100 % にするスタイルが適用されるようです。独自の css クラス 「task-input」を追加して css 定義を style タグに追加します。
el-input に css クラスを指定:
<el-input class="task-input" placeholder="追加するタスクを入力してください。" v-model="newTask" @keydown.enter.native="addTask"></el-input>
style タグに追記:
.task-input { width: 60% }
画面を表示するといい感じになっていることが分かります。

リスト表示をおしゃれに
Element ではストライプテーブルというコンポーネントが提供されています。これを使います。
Todo.vue のリスト部分を修正します。
変更前:
<div class="list"> <ul> <li v-for="item in list" :key="item.id"> <span :class="{ complete: item.isComplete }">{{ item.value }} </span> <input type="button" value="達成" @click="item.isComplete=true"> <input type="button" value="削除" @click="deleteTask(item)"> </li> </ul> </div>
変更後:
<el-table :data="list" stripe class="list"> <el-table-column> <template slot-scope="scope"> <span :class="{ complete: scope.row.isComplete }">{{ scope.row.value }}</span> </template> </el-table-column> <el-table-column> <template slot-scope="scope"> <el-button @click="scope.row.isComplete=true" type="primary" plain size="small">達成</el-button> <el-button @click="deleteTask(scope.row)" type="danger" plain size="small">削除</el-button> </template> </el-table-column> </el-table>
詳しくは Element の公式ページを見てください。
ざっくり説明すると el-table タグでリスト表示したい部分を囲み、:data 属性で リスト表示したいデータを指定します。stripe 属性を付与すると、行が見やすいようにしま模様になります。
el-table-column タグで列ごとに何を表示するか指定します。リスト中の各データにアクセスしたい場合は 「<template slot-scope="scope">」タグを使用し、その中で scope.row で各データにアクセスします。
ソースは載せていませんが css クラス の 「list」の幅は、60 % → 80 % に変更しました。
画面を表示すると、だいぶおしゃれじゃないですか!?

行の padding が 12 px で固定されてしまい、行の高さが少し長い気がします。いろいろ試したのですが、この padding をカスタマイズする方法がいまのところ見つからないので、とりあえずこのまま進めて、継続調査とします。
まとめ
今回は Element という Vue 用のライブラリを使って見た目をきれいにしてみました。
ここまでのソースは GitHub アップし、「oreore5」というタグを打っておきました。
https://github.com/yyama694/ore-todo
Todo.vue の全量はこちらです。
<template>
<div>
<h1>Todo List</h1>
<el-input class="task-input" placeholder="追加するタスクを入力してください。" v-model="newTask" @keydown.enter.native="addTask"></el-input>
<el-button type="primary" plain @click="addTask">追加</el-button>
<el-table
:data="list"
stripe
class="list">
<el-table-column>
<template slot-scope="scope">
<span :class="{ complete: scope.row.isComplete }">{{ scope.row.value }}</span>
</template>
</el-table-column>
<el-table-column>
<template slot-scope="scope">
<el-button @click="scope.row.isComplete=true" type="primary" plain size="small">達成</el-button>
<el-button @click="deleteTask(scope.row)" type="danger" plain size="small">削除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
list: [
{ id:1, value: "たまご買う", isComplete: false },
{ id:2, value: "図書館に本を返す", isComplete: false },
{ id:3, value: "宅急便を受け取る", isComplete: false }
],
newTask: "",
nextId: 4
}
},
methods : {
addTask() {
if(!this.newTask.trim()) {
return
}
this.list.push({
id: this.nextId++,
value: this.newTask,
isComplete: false
})
this.newTask = ""
},
deleteTask(obj) {
this.list = this.list.filter(e => e !== obj)
}
}
}
</script>
<style scoped>
.list {
width: 80%;
margin: auto;
text-align: left;
}
.complete {
text-decoration: line-through;
}
h1 {
position: relative;
line-height: 1.4;
}
h1:before {
font-family: "Font Awesome 5 Free";
content: "\f00c";
font-size: 0.7em;
left: 0;
top: 0;
color: #5ab9ff;
}
.task-input {
width: 60%
}
.el-table {
padding: 8px
}
</style>
次回は細かい機能改善をします。
【Vue】おれおれチュートリアル Ⅵ - 山崎屋の技術メモ
それではまた!

- 作者: 川口和也,喜多啓介,野田陽平,手島拓也,片山真也
- 出版社/メーカー: 技術評論社
- 発売日: 2018/09/22
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る

- 作者: mio
- 出版社/メーカー: シーアンドアール研究所
- 発売日: 2018/05/29
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る