山崎屋の技術メモ

IT業界で働く中でテクノロジーを愛するSIerのシステムエンジニア👨‍💻 | AndroidとWebアプリの二刀流🧙‍♂️ | コードの裏にあるストーリーを綴るブログ執筆者✍️ | 日々進化するデジタル世界で学び続ける探究者🚀 | #TechLover #CodeArtisan、気になること、メモしておきたいことを書いていきます。

【Vue】おれおれチュートリアル Ⅴ


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


なんかのっぺらぼうですね。もうちょっとオシャレにしたくなってきました。
 
ということで、今回はデザインを見直していきたいと思います。

vue の単一ファイルコンポーネントで作られたおしゃれで便利な Element というライブラリも使用します。

Element の公式ページはこちら。
Element
 

Vue.js入門 基礎から実践アプリケーション開発まで

Vue.js入門 基礎から実践アプリケーション開発まで

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

基礎から学ぶ Vue.js

タイトルをおしゃれにする

 
こちらのページで紹介されている、「シンプルなチェックマーク」というデザインを拝借します。
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;
}

これでタイトルに青いチェックが追加されました。

f:id:yyama1556:20181005171823p:plain

テキストボックスと追加ボタンをおしゃれにする

さぁここから 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 にしないと動きません。なぜかは知りません。
 
 
それでは画面を表示してみます。
f:id:yyama1556:20181007104008p:plain
 
でっかくなっちゃった!
 
 
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%
}

 
 
画面を表示するといい感じになっていることが分かります。
f:id:yyama1556:20181007105003p:plain

 

リスト表示をおしゃれに

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 % に変更しました。

画面を表示すると、だいぶおしゃれじゃないですか!?
f:id:yyama1556:20181007114827p:plain

行の 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】おれおれチュートリアル Ⅵ - 山崎屋の技術メモ


それではまた!
 

Vue.js入門 基礎から実践アプリケーション開発まで

Vue.js入門 基礎から実践アプリケーション開発まで

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

基礎から学ぶ Vue.js