Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
はじめてのVue.jsハンズオン
Search
taiga533
August 05, 2019
Programming
0
41
はじめてのVue.jsハンズオン
社外向け勉強会用に作成した資料です。
taiga533
August 05, 2019
Tweet
Share
More Decks by taiga533
See All by taiga533
ブラウザ拡張機能が ぱぱっと作れるいい時代になりました。
taiga533
1
760
実用Docker入門
taiga533
0
68
DockerをいじれるWebGUIを作った話
taiga533
0
68
Other Decks in Programming
See All in Programming
MCP with Cloudflare Workers
yusukebe
2
230
技術的負債と向き合うカイゼン活動を1年続けて分かった "持続可能" なプロダクト開発
yuichiro_serita
0
160
短期間での新規プロダクト開発における「コスパの良い」Goのテスト戦略」 / kamakura.go
n3xem
2
180
103 Early Hints
sugi_0000
1
260
「Chatwork」Android版アプリを 支える単体テストの現在
okuzawats
0
180
ドメインイベント増えすぎ問題
h0r15h0
2
440
Zoneless Testing
rainerhahnekamp
0
120
開発者とQAの越境で自動テストが増える開発プロセスを実現する
92thunder
1
200
ChatGPT とつくる PHP で OS 実装
memory1994
PRO
2
130
数十万行のプロジェクトを Scala 2から3に完全移行した
xuwei_k
0
360
Monixと常駐プログラムの勘どころ / Scalaわいわい勉強会 #4
stoneream
0
300
AppRouterを用いた大規模サービス開発におけるディレクトリ構成の変遷と問題点
eiganken
1
190
Featured
See All Featured
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
Site-Speed That Sticks
csswizardry
2
190
No one is an island. Learnings from fostering a developers community.
thoeni
19
3k
A better future with KSS
kneath
238
17k
Embracing the Ebb and Flow
colly
84
4.5k
Designing on Purpose - Digital PM Summit 2013
jponch
116
7k
Reflections from 52 weeks, 52 projects
jeffersonlam
347
20k
Agile that works and the tools we love
rasmusluckow
328
21k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
Imperfection Machines: The Place of Print at Facebook
scottboms
266
13k
Why Our Code Smells
bkeepers
PRO
335
57k
Designing Experiences People Love
moore
138
23k
Transcript
はじめてのVue.jsハンズオン Todoリストの作成を通してVue.jsに 触れてみよう!
まずは自己紹介 2
名前:川﨑 大河 所属:株式会社ラクーンホールディングス 技術戦略部 開発チーム 主な仕事:BtoB卸売りサイト スーパーデリバリーの開発 3
好きなこと • キャンプ • ビリヤード • プログラミング 4
今回の目標 Vue.jsを使ってTodoリストを作成し、 Hello, worldの2歩先を行く 5
みなさんが目標を達成できるように • JavaScriptが苦手な方でも進められるよう、ゆっく りやります • コードを写していただくようなところは間を開けま す ご理解ご協力お願いします。 6
今日やること 7
1. Vue.jsのいいところを知ろう 2. 環境構築をしよう 3. Vueを使って見た目を変えよう 4. todoリストを作ってみよう 5. 最後に
8
Vue.jsのいいところ • 学習コストが低い ◦ 見た目に関わる部分はほぼHTMLで書くことができる ◦ 日本語の資料が多い • かゆいところに手が届く ◦
UI・ビジネスロジックに関係ない部分の実装がすでに組み込まれてい る ◦ 独自テンプレート構文でHTMLに動きを付けることができる • 関連ライブラリが豊富 ◦ うまく使えば開発工数を短縮できる 9
環境構築をしよう① 今回はnpm(node package manager)は使いません。 gitをインストールされている方は git clone https://github.com/taiga533/vue-todomvc.git を実行し、cloneしたフォルダの中に入ってください。 10
環境構築をしよう② git入れてないよ~!という方は 1. こちらのURLを開いて 2. 3. ダウンロードしたzipを解凍 4. 解凍したフォルダを開く 11
Clone or download をクリック
ディレクトリ構成 • /js/app.js ◦ vue.jsのロジックを書くところ • /index.html ◦ todoリストのHTML 主にこの2つのファイルを編集します。
12
Vue.jsを読み込む index.htmlのheadタグ内部の任意の場所に <script src="vendor/js/vue.js"></script> と書きましょう。 現時点だとvue.jsを読み込んだだけなので、見た目は何も変わりません。 CDNから読み込む場合は、headタグ内部の任意の場所に <script src="https://cdn.jsdelivr.net/npm/
[email protected]
/dist/vue.js"></script> と書きます。
13
app.jsを開いて以下のように編集します。 (function (window) { 'use strict'; // この下から追記 window.app =
new Vue({ el: '#app', }); // この上まで追記 })(window); ←① ←② 14 app.js Vue.jsを使う範囲を決めよう!
Check Point!✅ • ①の行 ◦ Vueの機能を使用するために、Vueオブジェクトを作成している。 ◦ Vueで使う変数や関数を{}で囲い、オブジェクトとして引数に渡している。 ◦ 基本的にVueを使うときはJavaScriptにnew
Vue({ });を必ず書く。 15
Check Point!✅ • ②の行 ◦ Vueの独自テンプレート構文を使える DOM要素を指定しています ◦ ②の場合だとid=”app”とタグに書かれたDOM要素がVueオブジェクトと結びつく ◦
指定したDOM要素の内部でのみVueの独自テンプレート構文が使える <section> <h1>foo</h1> <div id="app"> <p>bar</p> </div> </section> el=”#app”と書いた場合 Vue.js独自の記述はこの中でしか 機能しない 16 HTML
app.jsを開いて以下のように編集します。 (function (window) { 'use strict'; window.app = new Vue({
el: '#app', // この下から追記 data: { title: 'Hello, World', }, // この上まで追記 }); })(window); ←① 17 app.js Vue.jsを使って見た目を変えよう!
Check Point!✅ • ①の行 ◦ data: {変数名: 値}という形のオブジェクトを定義している ◦ 基本的にVueテンプレートで使う変数はdata:{}の中で定義する
◦ vueの独自テンプレート内部でのみ使うことができる ◦ ①の場合だとtitleという名前で値が’Hello, World’という変数を定義したことになる <section> <h1>{{foo}}</h1> <div id="app"> <p>{{foo}}</p> </div> </section> new Vue({ el: "#app", data: { foo: 'Hello, World' } } この部分でしかtitle変数は 使えない 18 HTML JS
index.htmlを下記のように書き換えましょう。 <header class="header"> <!-- この下から上書き --> <h1>{{ title}}</h1> <!-- この上まで上書き
--> <input class="new-todo" placeholder="なにかやるべきことは?" autofocus> </header> 19 index.html
Check Point!✅ • vueのテンプレート構文では{{}}(ムスタッシュ構文)で変数名や関数名を囲うことで 変数の値や関数の戻り値を表示することができます。 ◦ {{}}で使えるのはnew Vue({ });の{}内部で定義された変数や関数だけで す。
20
21 <header class="header"> <h1>title</h1> <input class="new-todo" placeholder・・・> index.html <header class="header">
<h1>{{ title + ‘a’ }}</h1> <input class="new-todo" placeholder・・・> index.html {{}}をつけなかった場合 {{}}の中で式を使った場合 <header class="header"> <h1>{{ title }}</h1> <input class="new-todo" placeholder・・・> index.html {{}}をつけた場合
app.jsを以下のように変更しましょう。 ・・・ el: "#app", data: { title: 'Hello, World', //
この下から追記 // 追加されたTodoをリストで保持する変数 todos: [], // 新しいTodoタイトルを保持する変数 newTodo: "", // この上まで追記 }, ・・・ 22 Todoを追加できるようにする app.js
data: { ・・・ }, // この下から追記 methods: { addTodo() {
if (!this.newTodo) return; this.todos.push({id: (new Date()).getTime(), title: this.newTodo, completed: false}); this.newTodo = ""; }, }, // この上まで追記 } ←① ←② 23 app.js
Check Point!✅ • ①の行:new Vue({ });の{}内部にmethods:{}を用意すると{}の中にvueテンプ レートの内部で使える関数を定義できる。 ⚠注意⚠ new Vue({
});の{ }の中でdata: {/* 色々 */},で定義した変数を使うときは、 必ず this.定義した変数名 とする。 24
Check Point!✅ • ②の行:追加されるtodoにはid, title, completedというプロパティを持たせている 各プロパティの役割 • id ◦
配列todosに格納されるtodoそれぞれに一意性(同じものが存在しないという 性質)をもたせる • title ◦ todoの文字列を保持する • completed ◦ todoが完了したかどうかを真偽値(true/false)で保持する 25
index.htmlを以下のように変更しましょう。 <header class="header"> <h1>{{ title }}</h1> <!-- この下から上書き --> <input
class="new-todo" placeholder="なにかやるべきことは?" autofocus v-model="newTodo" v-on:keyup.enter="addTodo"> <!-- この上まで上書き --> </header> <!-- footerはtodoが何もないときは非表示で・・・・ --> ←① ←② 26 index.html
Check Point!✅ • ①の行:v-modelディレクティブ(サンプル) v-model=”foo” と書いたinputタグ 変数foo v-model=”foo” と書いたinputタグ 変数foo
変数fooが変更されたとき v-model=”foo”と書いたinputタグのvalueが変更されたとき Valueの値を代入 fooの値をvalueに設定 双方の変更が双方に適用される便利な機能 双方向バインディング 27
Check Point!✅ • ②の行:v-onディレクティブ(サンプル) ◦ ユーザーの入力(イベント)があったときに実行する関数を設定できる v-on:keyup.enter=”bar” と書いたinputタグ 関数bar() v-on:keyup.enterが設定された要素でエンターキーが押された時
呼び出し 28
29 <label for="toggle-all">すべて完了にする</label> <ul class="todo-list"> <!-- これらは単にtodoアイテムの構造を示すサンプルです。 --> <!-- リストアイテム(li)要素は編集時は'editing'、・・・
--> <!-- この下から上書き --> <li v-for="todo in todos"> <div class="view"> <input class="toggle" type="checkbox"> <label>{{ todo.title }}</label> <button class="destroy"></button> </div> <input class="edit" value="Rule the web"> </li> <!-- この上まで上書き --> </ul> </section> index.html ←① 追加したTodoを表示できるようにする
Check Point!✅ • ①の行:v-forディレクティブ ◦ 配列の数だけDOM要素を繰り返し生成する機能 ◦ v-for=”配列の要素が入る変数名 in 配列名”
◦ v-for=”todo in todos”が書かれた要素とその子要素た ちは、変数todoを参照することができる 30
コードで説明すると・・・ // todosの中身がこのような場合に todos: [ 'チャーハンを食べる', 'ラーメンを食べる', '刺し身を食べる' ] <!--
このようなコードが生成される --> <li> チャーハンを食べる </li> <li> ラーメンを食べる </li> <li> 寿司を食べる </li> <!-- vueの独自テンプレートを このように書くと --> <li v-for="todo in todos"> {{ todo }} </li> 31 JS HTML HTML
Todoの状態を完了にできるようにしよう 次にTodoを完了の状態にできるようにしましょう。 <ul class="todo-list"> <!-- この下から上書き --> <li v-for="todo in
todos" v-bind:class="{completed: todo.completed}"> <div class="view"> <input class="toggle" type="checkbox" v-model="todo.completed"> <!-- この上まで上書き --> <label>{{ todo.title }}</label> ・・・ ←① ←② 32 index.html
Check Point!✅ • ①の行:v-bindディレクティブ ◦ v-bind:class=”{completed: todo.completed}”と書くとtodo変数の completedプロパティがtrueのときのみcompletedクラスがHTML要素に付 与される 例:<div
class="{test: foo}">と書くと 変数fooがtrueのとき <div class="test"> 変数fooがfalseのとき <div> 33
Check Point!✅ • ②の行:type=”checkbox”のときのv-model ◦ input要素のtype属性がcheckboxの場合はv-modelに割り当てられた変数 にtrueかfalseが入る 例:<input type="checkbox" v-model="bar"
/>と書いたとき ✔ チェックがつくと・・・ チェックがないと bar = true bar = false 34
Todoを削除できるようにしよう 35 addTodo() { ・・・ }, // この下から追記 deleteTodo(deleteTarget) {
// 削除対象のtodoの添字を取ってくる const deleteTargetIndex = this.todos.indexOf(deleteTarget); const deleteCount = 1; // 削除対象のtodoをtodosから削除 this.todos.splice(deleteTargetIndex, deleteCount); }, // この↑まで追記 } app.js todoを削除する関数
<div class="view"> <input class="toggle" type="checkbox" v-model="todo.completed"> <label>{{ todo.title }}</label> <!--
この下から上書き --> <button class="destroy" v-on:click="deleteTodo(todo)"></button> <!-- この上まで上書き --> </div> クリックしたときTodoを削除す る関数が呼ばれる 36 index.html
Todoを編集できるようにしよう 37 el: "#app", data: { ・・・ newTodo: "", //
この下から追記 // 編集対象のtodoを保存する変数 editTargetTodo: null, // 編集対象のtodo.title文字列を保存する変数 editTargetTodoTitle: "", // この上まで追記 }, ・・・ app.js
38 deleteTodo(deleteTarget) { ・・・ }, // この下から追記 editTodo(editTarget) { this.editTargetTodo
= editTarget; this.editTargetTodoTitle = editTarget.title; }, updateTodo(updateTarget) { updateTarget.title = this.editTargetTodoTitle; this.editTargetTodo = null; this.editTargetTodoTitle = ""; }, // この上まで追記 }, 編集内容を保存する変数 編集対象のtodoを設定する 関数 app.js
<ul class="todo-list"> <!-- この下から上書き --> <li v-for="todo in todos" v-bind:class="{completed:
todo.completed, editing: editTargetTodo === todo}"> <div class="view"> <input class="toggle" type="checkbox" v-model="todo.completed"> <label v-on:dblclick="editTodo(todo)">{{ todo.title }}</label> <button class="destroy" v-on:click="deleteTodo(todo)"></button> </div> <input class="edit" v-model="editTargetTodoTitle" v-on:keyup.enter="updateTodo(todo)"> </li> <!-- この上まで上書き --> </ul> </section> ↓① ダブルクリックしたとき、編集 するTodoを設定する関数が 呼ばれる。 todo編集中にエンターを押さ れると、編集内容を確定する 関数が呼ばれる。 39 Todoタイトル編集欄の内容 と、変数editTargetTodoTitleを 結びつける index.html
Check Point!✅ • ①の部分:編集対象のTodoとそれぞれのliタグに割り当てられたTodoが等しいと きだけclass=”editing”になるようにしている <li> 配列1番目 </li> <li class="editing">
配列2番目 </li> editTarget = 配列2番目の要素の場合 <li v-for"todo in todos" v-bind:class="{editing: editTarget === todo}"> {{ todo.title }} </li> Vueテンプレート側 出力されるHTML 40 HTML HTML
Todoの件数を加工して表示しよう todoの残り件数をカンマ区切りで表示するようにしましょう。 41
42 editTargetTodoTitle: "" }, // この下から追記 computed: { todoCount() {
const COMMA_SPLIT_REGEX = /(\d)(?=(\d{3})+$)/g // todosの要素数をカンマ区切りにして返す return this.todos.length.toString().replace(COMMA_SPLIT_REGEX, '$1,'); }, }, // この上まで追記 methods: { ・・・ app.js ←①
Check Point!✅ • ①の行:new Vue({ });の{}内部にcomputed:{}を用意すると{}の中にvueテン プレートの内部で使える計算済みプロパティが定義できる。 計算済みプロパティとは data:{}に登録されている変数に処理を加えてVueテンプレート側で表示できる。 data:
{ // todoが1000個入ったtodos todos: [...] }, computed: { todoCount() { // todoCountをカンマ区切りにして返す } } <h1>{{ todoCount }}</h1> <h1>1,000</h1> 43 HTML HTML JS
44 <footer class="footer"> <!-- 通常は'残り0項目' --> <!-- この下から上書き --> <span
class="todo-count">残り<strong>{{ todoCount }}</strong>項目</span> <!-- この上まで上書き --> <!-- あなたがルーティングを実装しない場合は削除 --> <ul class="filters"> index.html
要素の表示非表示を切り替えられるように しよう Todoリストに何も存在しないときは、 □の部分を表示しないようにしましょう。 45
app.jsを以下のように編集します。 computed: { todoCount() { const COMMA_SPLIT_REGEX = /(\d)(?=(\d{3})+$)/g //
todosの要素数をカンマ区切りにして返す return this.todos.length.toString().replace(COMMA_SPLIT_REGEX, '$1,'); }, // この下から追記 existsTodo() { return this.todos.length > 0; }, // この上まで追記 }, 46 todoリストにtodoが存在したと きにtrueを返す app.js
index.htmlを以下のように編集します。 </section> <!-- footerはtodoが何もないときは非表示・・・ → <!-- この下から上書き --> <section class="main"
v-if="existsTodo"> <!-- この上まで上書き --> ・・・ </ul> </section> <!-- footerはtodoが何もないときは・・・ → <!-- この下から上書き --> <footer class="footer" v-if="existsTodo"> <!-- この上まで上書き --> ←① 47 index.html ←①
Check Point!✅ • ①の行:v-ifディレクティブ ◦ HTMLタグにv-if=”条件式”と書くと条件式を満たした場合のみ、v-if=”条件 式”を書いたHTML要素が表示されるようになる。 <section> <div v-if="foo">
見えますか? </div> </section> Vueテンプレートをこのように書 くと・・・ <section> <div> 見えますか? </div> </section> foo = trueの場合に出力される HTML <section> </section> foo = falseの場合に出力される HTML 48 HTML HTML HTML
最後に まだまだ完成とはいえませんが、時間の都合上ここまでとさせていただきます。 2時間お付き合いいただき、誠にありがとうございます。 多少はVue.jsのお勉強のお役に立てたでしょうか? この勉強会を機会に、みなさんがVue.jsに興味を持っていただけたら幸いです。 49
実は・・・ • このTodoリストにはもっと詳細な機能要件があります。 ◦ readme.mdに書いてあります。更に実装してみたい方は読んでみてくださ い。 • このTodoリストのテンプレートはTodoMVCという名前で、githubに公開されてい るものです。(オープンソース) 50
アンケートの回答をよろしくお願いします。 51 https://forms.gle/UP8yxFfebhoMjwwFA