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

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

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

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

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

Avatar for taiga533

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