Vue.jsの基本3(Vueの機能確認2)

目次

本項ではVue.js v.2のドキュメントに従い、言語の仕様を試します。
Vue.js v.2 日本語ドキュメント
https://jp.vuejs.org/v2/guide/

1.Vueの動作環境
(1)動作環境
 ・Windows 10 Pro
・XAMPP Control Panel v3.2.4
(2)Vueの導入
 Vueは下記のcdnからコードを読み込んで使用します。
・開発版(コンソールへの警告文が含まれている)<script src=”https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js”></script>
・本番版(サイズと高速化のため最適化されている)<script src=”https://cdn.jsdelivr.net/npm/vue@2.6.14″></script>

(3)動作確認方法
 Webサーバ(XAMPP)のドキュメントルート(”C:/xampp/htdocs”)にindex.html、javascript(.js)などのファイルを置き、XAMPPのApacheを起動してブラウザ(http://localhost)で確認します。

2.算出プロパティ
(1)算出プロパティ
 算出プロパティでテンプレートで使うロジックを作成します。
sample12
index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Vue.js App</title>
  <link href="main.css" rel="stylesheet">
</head>
<body>
  <div id="app-12">
    <p>Original message: "{{ message }}"</p>
    <p>Computed reversed message: "{{ reversedMessage }}"</p>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  <script src="main.js"></script>
</body>
</html>

main.js

var app12=new Vue({
  el: '#app-12',
  data: {
    message:"Hello"
  },
  computed: {
    // 算出 getter 関数
    reversedMessage: function () {
      // `this` はapp12インスタンスを指します
      return this.message.split('').reverse().join('')
    }
  }
})

 ここで宣言した算出プロパティreversedMessageはプロパティapp12.reversedMessage に対するgetter 関数として利用されます。
 app12.reversedMessage の値は、常にapp12.messageの値に依存しているので、app12.messageの値が変わるとapp12.reversedMessage の値も変わります。

(2)メソッド
 上記(1)の算出プロパティをメソッドに変えても同じ結果が実現できます。
sample13
index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Vue.js App</title>
  <link href="main.css" rel="stylesheet">
</head>
<body>
  <div id="app-13">
    <p>Original message: "{{ message }}"</p>
    <p>Computed reversed message: "{{ reversedMessage() }}"</p>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  <script src="main.js"></script>
</body>
</html>

・ここではreversedMessageはメソッドなので()を付けて、reversedMessage()とします。

main.js

var app13=new Vue({
  el: '#app-13',
  data: {
    message:"Hello"
  },
  methods: {
     reversedMessage: function () {
     return this.message.split('').reverse().join('')
    }
  }
})

3.クラスとスタイルのバインディング
 v-bind:class にオブジェクトを渡すことでクラスを動的に切り替えることができます:<p v-bind:class=”{クラス名: 真偽値, クラス名: 真偽値, …}”>
sample14
index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Vue.js App</title>
  <link href="main.css" rel="stylesheet">
</head>
<body>
  <div
    class="static"
    v-bind:class="{ active: isActive, 'text-danger': hasError }"
  ></div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  <script src="main.js"></script>
</body>
</html>

・’text-danger’のように、クラス名にハイフンを含む場合は”(シングルクォート)で囲む。

main.js

var app14=new Vue({
  el: '.static',
   data: {
     isActive: true,
     hasError: false
   }
})

データプロパティの真偽値を変えることで、クラスを切り替えることができます。

4.条件付きレンダリング
(1)2つのブロックの切り換え
 v-if ディレクティブは、ブロックを条件に応じて描画したい場合に使用されます。ブロックは、ディレクティブの式が真を返す場合のみ描画されます。
sample15
index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Vue.js App</title>
  <link href="main.css" rel="stylesheet">
</head>
<body>
  <div id="app-15">
    <h1 v-if="awesome">Vue is awesome!</h1>
    <h1 v-else>Oh no 😢</h1>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  <script src="main.js"></script>
</body>
</html>

main.js

var app15=new Vue({
  el: '#app-15',
  data: {
     awesome: true
   }
})

コンソールから「app15.awesome=false」を入力

(2)3つ以上のブロックの切り換え
sample16
index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Vue.js App</title>
  <link href="main.css" rel="stylesheet">
</head>
<body>
  <div id="app-16">
    <h1 v-if="type==='A'">Type is A</h1>
    <h1 v-else-if="type==='B'">Type is B</h1>
    <h1 v-else>Type Not A/B/C</h1>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  <script src="main.js"></script>
</body>
</html>

main.js

var app16=new Vue({
  el: '#app-16',
  data: {
     type:"A"
   }
})

コンソールから「app16.type=”B”」を入力

コンソールから「app16.type=”C”」を入力

コンソールから「app16.type=”D”」を入力

5.リストレンダリング
(1)v-forで配列に要素をマッピングする
 配列に基づいて、アイテムのリストを描画するために、v-for ディレクティブを使用することができます。v-for ディレクティブは item in items の形式で、ソースデータの配列itemsから配列要素を反復してitemに入れます。
sample17
index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Vue.js App</title>
  <link href="main.css" rel="stylesheet">
</head>
<body>
  <ul id="app-17">
    <li v-for="item in items" :key="item.message">
      {{ item.message }}
    </li>
  </ul>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  <script src="main.js"></script>
</body>
</html>

main.js

var app17=new Vue({
  el: '#app-17',
  data: {
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
})

(2)オブジェクトのプロパティに対してv-for を使って反復処理
 オブジェクトのプロパティに対して、v-for を使って反復処理することができます。
sample18
index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Vue.js App</title>
  <link href="main.css" rel="stylesheet">
</head>
<body>
  <ul id="app-18">
    <li v-for="item in object">
      {{ item }}
    </li>
  </ul>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  <script src="main.js"></script>
</body>
</html>

main.js

var app18=new Vue({
  el: '#app-18',
  data: {
    object: {
      title: 'How to do lists in Vue',
      author: 'Jane Doe',
      pubslishedAt: '2016-04-10'
    }
  }
})

6.イベントハンドリング
(1)イベントハンドラ
 v-on ディレクティブを使うことでイベント発生時の JavaScript の実行が可能になります。
sample19
index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Vue.js App</title>
  <link href="main.css" rel="stylesheet">
</head>
<body>
  <div id="app-19">
    <button v-on:click="counter += 1">Add 1</button>
    <p>The button above has been clicked {{ counter }} times.</p>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  <script src="main.js"></script>
</body>
</html>

main.js

var app19=new Vue({
  el: '#app-19',
  data: {
    counter: 0    
  }
})

(2)メソッドイベントハンドラ
 上記(1)ではv-on 属性の値に JavaScript 式を記述しましたが、ここではメソッドを呼び出す形に改造します。
sample20
index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Vue.js App</title>
  <link href="main.css" rel="stylesheet">
</head>
<body>
  <div id="app-20">
    <button v-on:click="countup">Add 1</button>
    <p>The button above has been clicked {{ counter }} times.</p>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  <script src="main.js"></script>
</body>
</html>

main.js

var app20=new Vue({
  el: '#app-20',
  data: {
    counter: 0
  },
  methods: {
countup:function(){
 //このインスタンスを示すthisを付ける
      this.counter += 1
    }
  }
})

呼出し時

「Add 1」ボタン押下

7.フォーム入力バインディング
 formのinput要素やtextarea要素、select要素に双方向 データバインディングを作成するにはv-modelディレクティブを使用することができます。
(1)テキストの入力と表示
<input v-model=”message” ・・・>
sample21
index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Vue.js App</title>
  <link href="main.css" rel="stylesheet">
</head>
<body>
  <div id="app-21">
	<input v-model="message" placeholder="edit me">
	<p>Message is: {{ message }}</p>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  <script src="main.js"></script>
</body>
</html>

main.js

var app21=new Vue({
  el: '#app-21',
  data: {
    message : ''
  }
})

(2)複数行テキストの入力と表示
<textarea v-model=”message” ・・・></textarea>
sample22
index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Vue.js App</title>
  <link href="main.css" rel="stylesheet">
</head>
<body>
  <div id="app-22">
    <span>Multiline message is:</span>
    <p>{{ message }}</p>
    <br>
    <textarea v-model="message" placeholder="add multiple lines"></textarea>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  <script src="main.js"></script>
</body>
</html>

main.js

var app22=new Vue({
  el: '#app-22',
  data: {
    message : ''
  }
})

(3)チェックボックス
 単体のチェックボックスはboolean値で初期値をchecked:falseとする。
sample23
index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Vue.js App</title>
  <link href="main.css" rel="stylesheet">
</head>
<body>
  <div id="app-23">
    <input type="checkbox" id="checkbox" v-model="checked">
    <label for="checkbox">{{ checked }}</label>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  <script src="main.js"></script>
</body>
</html>

main.js

var app23=new Vue({
  el: '#app-23',
  data: {
    checked : false
  }
})

8.コンポーネントの基本
(1)コンポーネントの作成と利用
sample24
index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Vue.js App</title>
  <link href="main.css" rel="stylesheet">
</head>
<body>
  <div id="app-24">
	<button-counter></button-counter>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  <script src="main.js"></script>
</body>
</html>

main.js

// button-counter と呼ばれる新しいコンポーネントを定義します
Vue.component('button-counter', {
  data: function () {
    return {
      count: 0
    }
  },
  template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})

var app24=new Vue({
  el: '#app-24',
})

・コンポーネントの data オプションは、各インスタンスが返されるデータオブジェクトの独立したコピーを保持できるように、関数でなければなりません。

(2)プロパティを使用した子コンポーネントへのデータの受け渡し
 props オプションを使用して、このコンポーネントが受け入れるプロパティのリストに含めることで、HTML要素からカスタム属性としてデータを渡すことができる。
sample24_2(HTMLのカスタム属性でデータを渡す例)
index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Vue.js App</title>
  <link href="main.css" rel="stylesheet">
</head>
<body>
  <div id="app">
    <blog-post title="My journey with Vue"></blog-post>
    <blog-post title="Blogging with Vue"></blog-post>
    <blog-post title="Why Vue is so fun"></blog-post>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  <script src="main.js"></script>
</body>
</html>

main.js

Vue.component('blog-post', {
  props: ['title'],
  template: '<h3>{{ title }}</h3>'
})

new Vue({
  el: '#app',
})

sample24_3(Vueインスタンスのデータを読み込んで渡す例)
 Vueインスタンスの配列データをv-forで読み込んだオブジェクトをv-bind を使って動的にプロパティを渡すことができる。
 index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Vue.js App</title>
  <link href="main.css" rel="stylesheet">
</head>
<body>
  <div id="app">
    <blog-post
      v-for="post in posts"
      v-bind:key="post.id"
      v-bind:title="post.title">
    </blog-post>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  <script src="main.js"></script>
</body>
</html>

main.js

Vue.component('blog-post', {
  props: ['title'],
  template: '<h3>{{ title }}</h3>'
})

new Vue({
  el: '#app',
  data: {
    posts: [
      { id: 1, title: 'My journey with Vue' },
      { id: 2, title: 'Blogging with Vue' },
      { id: 3, title: 'Why Vue is so fun' }
    ]
  }
})

(3)コンポーネントの再利用

sample25
Index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Vue.js App</title>
  <link href="main.css" rel="stylesheet">
</head>
<body>
  <div id="app-25">
	<button-counter></button-counter>
    <button-counter></button-counter>
    <button-counter></button-counter>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  <script src="main.js"></script>
</body>
</html>

9.コンポーネントの登録
(1)コンポーネントの登録
 コンポーネントの登録は Vue.component の第一引数にコンポーネント名を書き、次の様式で書く。
 Vue.component(‘my-component-name’, { /* … */ })
 コンポーネント名を定義する時、ケバブケース(文字の区切りにハイフンを使う)とパスカルケース(最初の文字を大文字にしたキャメルケース)の両方が使える。ケバブケースではコンポーネントの登録とカスタム要素の参照ともにケバブケースを使う。

(2)グローバル登録とローカル登録 
 Vue.componentだけを使ってコンポーネントを作成するとグローバルコンポーネントとなり全てのルートVueインスタンス(new Vue)のテンプレート内で使用できますが、使用しないときも最終ビルドに含まれてJavaScriptのファイルサイズを不要に増加させてしまいます。
 ローカル登録することでJavaScriptのファイルサイズを不要に増加させることを防ぐことができます。
 ローカル登録ではコンポーネントを素のJavaScript オブジェクトとして定義して、Vueインスタンスのcomponentsオプション内に使いたいコンポーネントを定義します。

sample26(コンポーネントのグローバル登録)
 index.htmlファイル

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Vue.js App</title>
  <link href="main.css" rel="stylesheet">
</head>
<body>
  <div id="app-26">
    <ol>
      <component-a></component-a>
      <component-b></component-b>
      <component-c></component-c>
    </ol>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  <script src="main.js"></script>
</body>
</html>

main.js

// コンポーネントの定義
Vue.component('component-a', {
  template: '<li>This is a COMPONENT A</li>'
})
Vue.component('component-b', {
  template: '<li>This is a COMPONENT B</li>'
})
Vue.component('component-c', {
  template: '<li>This is a COMPONENT C</li>'
})

var app26=new Vue({
  el: '#app-26',
})

sample27(コンポーネントのローカル登録)
index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Vue.js App</title>
  <link href="main.css" rel="stylesheet">
</head>
<body>
  <div id="app-27">
    <ol>
      <component-a></component-a>
      <component-b></component-b>
      <component-c></component-c>
    </ol>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  <script src="main.js"></script>
</body>
</html>

main.js

// コンポーネントの定義
var ComponentA = {
  template: '<li>This is a COMPONENT A</li>'
}
var ComponentB = {
  template: '<li>This is a COMPONENT B</li>'
}
var ComponentC = {
  template: '<li>This is a COMPONENT C</li>'
}

var app27=new Vue({
  el: '#app-27',
  components: {
    'component-a': ComponentA,
    'component-b': ComponentB,
    'component-c': ComponentC
  }
})

The end