Upgrade to Pro — share decks privately, control downloads, hide ads and more …

はじめてのVue.jsハンズオン

 はじめてのVue.jsハンズオン

社外向け勉強会用に作成した資料です。

taiga533

August 05, 2019
Tweet

More Decks by taiga533

Other Decks in Programming

Transcript

  1. Vue.jsのいいところ • 学習コストが低い ◦ 見た目に関わる部分はほぼHTMLで書くことができる ◦ 日本語の資料が多い • かゆいところに手が届く ◦

    UI・ビジネスロジックに関係ない部分の実装がすでに組み込まれてい る ◦ 独自テンプレート構文でHTMLに動きを付けることができる • 関連ライブラリが豊富 ◦ うまく使えば開発工数を短縮できる 9
  2. app.jsを開いて以下のように編集します。 (function (window) { 'use strict'; // この下から追記 window.app =

    new Vue({ el: '#app', }); // この上まで追記 })(window); ←① ←② 14 app.js Vue.jsを使う範囲を決めよう!
  3. 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
  4. app.jsを開いて以下のように編集します。 (function (window) { 'use strict'; window.app = new Vue({

    el: '#app', // この下から追記 data: { title: 'Hello, World', }, // この上まで追記 }); })(window); ←① 17 app.js Vue.jsを使って見た目を変えよう!
  5. 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
  6. index.htmlを下記のように書き換えましょう。 <header class="header"> <!-- この下から上書き --> <h1>{{ title}}</h1> <!-- この上まで上書き

    --> <input class="new-todo" placeholder="なにかやるべきことは?" autofocus> </header> 19 index.html
  7. 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 {{}}をつけた場合
  8. app.jsを以下のように変更しましょう。 ・・・ el: "#app", data: { title: 'Hello, World', //

    この下から追記 // 追加されたTodoをリストで保持する変数 todos: [], // 新しいTodoタイトルを保持する変数 newTodo: "", // この上まで追記 }, ・・・ 22 Todoを追加できるようにする app.js
  9. data: { ・・・ }, // この下から追記 methods: { addTodo() {

    if (!this.newTodo) return; this.todos.push({id: (new Date()).getTime(), title: this.newTodo, completed: false}); this.newTodo = ""; }, }, // この上まで追記 } ←① ←② 23 app.js
  10. Check Point!✅ • ①の行:new Vue({ });の{}内部にmethods:{}を用意すると{}の中にvueテンプ レートの内部で使える関数を定義できる。 ⚠注意⚠ new Vue({

    });の{ }の中でdata: {/* 色々 */},で定義した変数を使うときは、 必ず this.定義した変数名 とする。 24
  11. Check Point!✅ • ②の行:追加されるtodoにはid, title, completedというプロパティを持たせている 各プロパティの役割 • id ◦

    配列todosに格納されるtodoそれぞれに一意性(同じものが存在しないという 性質)をもたせる • title ◦ todoの文字列を保持する • completed ◦ todoが完了したかどうかを真偽値(true/false)で保持する 25
  12. 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
  13. Check Point!✅ • ①の行:v-modelディレクティブ(サンプル) v-model=”foo” と書いたinputタグ 変数foo v-model=”foo” と書いたinputタグ 変数foo

    変数fooが変更されたとき v-model=”foo”と書いたinputタグのvalueが変更されたとき Valueの値を代入 fooの値をvalueに設定 双方の変更が双方に適用される便利な機能 双方向バインディング 27
  14. 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を表示できるようにする
  15. Check Point!✅ • ①の行:v-forディレクティブ ◦ 配列の数だけDOM要素を繰り返し生成する機能 ◦ v-for=”配列の要素が入る変数名 in 配列名”

    ◦ v-for=”todo in todos”が書かれた要素とその子要素た ちは、変数todoを参照することができる 30
  16. コードで説明すると・・・ // todosの中身がこのような場合に todos: [ 'チャーハンを食べる', 'ラーメンを食べる', '刺し身を食べる' ] <!--

    このようなコードが生成される --> <li> チャーハンを食べる </li> <li> ラーメンを食べる </li> <li> 寿司を食べる </li> <!-- vueの独自テンプレートを このように書くと --> <li v-for="todo in todos"> {{ todo }} </li> 31 JS HTML HTML
  17. 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
  18. 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を削除する関数
  19. <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
  20. Todoを編集できるようにしよう 37 el: "#app", data: { ・・・ newTodo: "", //

    この下から追記 // 編集対象のtodoを保存する変数 editTargetTodo: null, // 編集対象のtodo.title文字列を保存する変数 editTargetTodoTitle: "", // この上まで追記 }, ・・・ app.js
  21. 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
  22. <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
  23. 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
  24. 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 ←①
  25. 44 <footer class="footer"> <!-- 通常は'残り0項目' --> <!-- この下から上書き --> <span

    class="todo-count">残り<strong>{{ todoCount }}</strong>項目</span> <!-- この上まで上書き --> <!-- あなたがルーティングを実装しない場合は削除 --> <ul class="filters"> index.html
  26. 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
  27. index.htmlを以下のように編集します。 </section> <!-- footerはtodoが何もないときは非表示・・・ → <!-- この下から上書き --> <section class="main"

    v-if="existsTodo"> <!-- この上まで上書き --> ・・・ </ul> </section> <!-- footerはtodoが何もないときは・・・ → <!-- この下から上書き --> <footer class="footer" v-if="existsTodo"> <!-- この上まで上書き --> ←① 47 index.html ←①
  28. 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