「思いついたものをすぐに作れる(そしてピボットできる)(そして最悪捨てられる)」そんな力をつけていきたいものです。以前某プロダクトアワードで、プロトタイプを5時間ほどで作りエントリということをしたのですが、それから2年弱が経ち、やはり日頃磨いていない力は錆びついていくなと危機感を感じています。今年はやっていきたいです💪
実は、タイトルを「Vue.js 学びなおし」にするつもりだったのですが、私の CSS 能力が皆無でむしろここに時間を割いたので、「フロントエンド学びなおし」としています。(しばらく生の CSS の勉強をして、そのうち Bootstrap に移っていこう..)
この流れなら言える
— ketancho 🙂|Kei Kanazawa (@ketancho) March 17, 2020
久しぶりに CSS 書いてるんだけど何も分からない
子供の絵本に「乗ってる人が降りてから、電車に乗る」「人がずるをしていてもマネしない」とか書いてあって、世の中の大人どもに投げつけてやりたいと思ったんだけど、「うまくいかないことがあっても、もう少しだけ頑張ってみる」とも書いてあったので、もう少し CSS 頑張ろうと思いましたまる
— ketancho 🙂|Kei Kanazawa (@ketancho) 2020年3月17日
このシリーズでは、「こういう部品を作りたい!」という定義を行い、それを作る過程で学んだことをメモしていこうと思います。
Vue.js に関する副読本はこちらです。最終的には、書籍の検索サイトが作れるようになるようなので、粘り強くやっていく所存です。
- 作者:山田 祥寛
- 発売日: 2019/08/22
- メディア: 単行本
CSS 関連の教材はドットインストールさんの 初めての CSS です。相変わらず分かりやすい、、、オススメです!
作った部品
画像、アイテム名、数値情報、URL を持つ Item をリスト表示させる、というものです。名前をクリックしたら URL に飛ぶ、としたいです。
作ったものはこんな感じです。最低限やりたいことはできたはず。
学びメモ
v-for ディレクティブの使い方
これすら忘れていた..
<div id="app"> <div v-for="item in items" class="item"> {{ item.name }} {{ item.point }} pt </div> </div>
(function() { 'use strict'; var vm = new Vue({ el: '#app', data: { newItem: '', items: [{ name: "ピカチュウ", point: 87.3 }, { name: "チコリータ", point: 77.1 }, { name: "トゲピー", point: 64.9 }, { name: "ヒトカゲ", point: 88.8 }] } }); })();
v-if と v-show の使い分け
v-if
は条件を満たしたときに、要素そのものが破棄される。そのため、頻繁に表示/非表示が切り替わる場合は、描画コストが高まる可能性がある。それに対し、 v-show
は要素そのものは文書ツリーに残っているが、 display: none;
がついた状態になる。
- 頻繁に切り替える:
v-show
- 最初に決めた表示/非表示がめったに変わらない
v-if
CSS コーディングの進め方
ドットインストール講座で、各要素に background-color
を指定して開発を進める方式が採用されていました。スタイルがどう当たっているかが分かりやすく、今回これを真似して開発を進めてみました。
(参考)ソースコード
html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>Item List</title> <link rel="stylesheet" href="css/styles.css"> </head> <body> <header> <div class="header"> <h1> ここに Header 情報を書くよ </h1> </div> </header> <div id="app" class="itemList"> <div v-if="items.length" v-for="item in items" class="item"> <div class="itemImage"> <img v-bind:src="item.imgPath"> </div> <div class="itemDetail"> <a v-bind:href="item.url" class="itemName"> {{ item.name }} </a> <p class="itemPoint"> {{ item.point }} pt </p> </div> </div> <div v-if="!items.length">表示するものがありません</div> </div> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script src="js/main.js"></script> </body> </html>
js
(function() { 'use strict'; var vm = new Vue({ el: '#app', data: { newItem: '', items: [{ name: "ピカチュウ", url: "https://zukan.pokemon.co.jp/detail/025", imgPath: "img/IMG_7559.jpg", point: 87.3 }, { name: "チコリータ", url: "https://zukan.pokemon.co.jp/detail/152", imgPath: "img/IMG_7562.jpg", point: 77.1 }, { name: "トゲピー", url: "https://zukan.pokemon.co.jp/detail/175", imgPath: "img/IMG_7563.jpg", point: 64.9 }, { name: "ヒトカゲ", url: "https://zukan.pokemon.co.jp/detail/004", imgPath: "img/IMG_7564.jpg", point: 88.8 }] } }); })();
css
(名前の左上寄せ、数値の右下寄せをもっとカッコよく書けないのでしょうか。。)
body { color: #333; font-family: "Helvetica Neue", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", Meiryo, sans-serif; margin: 0; } header { background-color: #eeeeee; padding-top: 16px; padding-bottom: 16px; } .header { width: 500px; margin-left: auto; margin-right: auto; align-items: center; } .item { width: 500px; padding-left: 8px; padding-top: 4px; padding-bottom: 4px; margin-left: auto; margin-right: auto; align-items: center; display: flex; } .itemList { padding-top: 16px; padding-bottom: 16px; } .itemImage { padding: 4px; } .itemImage img { width: 80px; height: 80px; border-radius: 50%; } .itemDetail { position: relative; width: 380px; height: 100px; margin: auto; display: flex; } .itemName { position: absolute; margin-top: 4px; margin-left: 4px; font-size: 24px; } .itemPoint { position: absolute; bottom: 0; right: 0; margin-bottom: 4px; margin-right: 4px; font-size: x-large; }
まとめ
次は Vue Router の復習をしたい。