前回までの記事
↓
① hello world
目次
14. classをデータにバインディングする方法(オブジェクトと配列)
テンプレート構文とは
new Vue({
el: '#app',
data: {
message: 'Hello World'
}
- Vue.jsが上記テンプレート構文をロード
- Vue.jsがhtmlを出力
- ブラウザがhtmlをロード
- 私達がブラウザで確認できる
new vueテンプレート解説
<div id = "app">
<!-- [1]文字列を出力 -->
<p>{{message}}</p>
<!-- [2]和を出力 -->
<p>{{number + 3}}</p>
<!-- [3]三項演算子 -->
<p>{{ok ? 'yes' : 'no'}}</p>
<!-- [4]メソッドを出力 -->
<p>{{ sayHi() }}</p>
</div>
new Vue({
el: '#app',
data: {
<!-- [1]文字列を出力 -->
message: 'Hello World'
<!-- [2]和を出力 -->
number: 3
<!-- [3]三項演算子 -->
ok: true
}
<!-- [4]メソッドを出力 -->
methods: {
sayHi: function() {
return: 'Hi';
}
}
})
三項演算子とは?
唯一の、3 つのオペランドをとる演算子です。
1. 条件に続いて疑問符 (?)
2. 条件が真値であった場合に実行する式
3. コロン (:) が続く
4. 条件がfalseであった場合に実行する式
が最後に来ます
注意: javascriptが出力されるのは、単一の式のみ
プロパティの種類
1. el
マウント先の要素を指定するブロック
2. data
変数を保持するブロック
3. method
関数を保持するブロック
4. computed
関数を保持するブロック
特徴として、returnを使用して返り値が必要。
そして、依存関係に基づきキャッシュされる。
5. watch
関数を保持するブロック
特徴として、returnを使用しないため非同期処理を記述できる
ディレクティブの種類
- ディレクティブとは、v-から始まるVue.jsの特別な属性
- 属性とは、htmlではhref,class,idといった要素 HTMLにおける、属性とは
1. v-text
2. v-once
3. v-html (xss脆弱性に注意)
対応:信頼のあるコンテンツしか置かないようにする。
4. v-bind
1. href
2. class
3. id
属性を与える事ができる
5. v-on
使用頻度が多い、DOMイベントを引数として発火する。
様々な関数を、起動させることが可能。
6. v-model
双方向データバインディングが可能
v-bindとは
属性を与える事ができる
<div id = "app">
<a href="url">Google</a>
</div>
new Vue ({
data: {
url: 'https://google.com',
}
})
Vueテンプレートで、url属性を与えようとする。。。
404エラーとなってしまう。
v-bind使用例
<div id = "app">
<a v-bind:href="url">Google</a>
</div>
new Vue ({
data: {
url: 'https://google.com',
}
})
v-bind省略記法
<div id = "app">
<a :href="url">Google</a>
</div>
new Vue ({
data: {
url: 'https://google.com',
}
})
v-onディレクティブ省略記法
- v-onを省略する。
<p>現在{{number}}回クリックされています</p>
<button @click="countUp">countUp</button>
省略が可能な記法(:や@)は、プロジェクト内で統一する。
v-bindを オブジェクト化 して使用する。
- hrefリンク
- class
- id
複数の属性を与えたい時、 オブジェクト化 が最適
方法
<div id = "app">
<a v-bind="objectGoogle">Google</a>
</div>
new Vue ({
data: {
objectGoogle: {
href: 'https://google.com',
class: 'sample',
id: 31
}
}
})
chromeブラウザの「検証」より、v-bindで属性が与えられているのが確認できる
v-onとは
DOMイベントが発火するタイミングで、実装した関数を実行できる
ボタンクリックで数字がカウントされる処理を実装してみる。
v-on:に指定するのは、clickイベント
<div id = "app">
<p>現在{{number}}回クリックされている</p>
<button v-on:click="countUp">カウントアップ</button>
</div>
new Vue ({
el: '#app',
data: {
number: 0
},
methods: {
countUp: function() {
this.number += 1
}
}
})
- clickイベントが発火する
- countUp関数が起動 ( 変数numberに、+1 )
- {{ number }} に反映
マウスをかざした場所の、XY軸を表示する
v-on:に指定するのは、mousemoveイベント
<div id = "app">
<p v-on:mousemove="changeMousePosition">マウスを載せてください</p>
<p>X:{{x}},Y{{y}}</p>
</div>
new Vue ({
el: '#app',
data: {
x:0,
y:0,
},
methods: {
changeMousePosition: function(event) {
this.x = event.clientX;
this.y = event.clientY;
}
}
})
DOMイベントの情報を拾うには、ルールがある
1. 引数にはeventを文字として使用。他でも格納できるがよっぽど理由がなければ変更しない。
2. 格納したeventから読み取る事。
イベント修飾子とは
- 従来のstopPropagationを、stop で実装可能
- 従来のpreventDefaultを、prevent で実装可能
処理をSTOPさせる
従来のstopPropagation
<div id = "app">
<p v-on:mousemove="changeMousePosition">マウスをかざしてください
<span v-on:mousemove="noEvent">マウスをかざしても反応させない。</span>
</p>
<p>X:{{x}},Y{{y}}</p>
</div>
new Vue ({
el: '#app',
data: {
x:0,
y:0,
},
methods: {
changeMousePosition: function(event) {
this.x = event.clientX;
this.y = event.clientY;
},
noEvent: function(event) {
event.stopPropagation()
}
})
- spanタグにnoEvent関数を追加
- noEvent関数に、stopPropagationという処理をstopさせる命令を追加
Vue.jsのすごい所
- v-on:mousemove.stopを与えるのみ!
<div id = "app">
<p v-on:mousemove="changeMousePosition">マウスをかざしてください
<span v-on:mousemove.stop>マウスをかざしても反応させない。</span>
</p>
<p>X{{x}},Y{{y}}</p>
</div>
new Vue ({
el: '#app',
data: {
x:0,
y:0,
},
methods: {
changeMousePosition: function(event) {
this.x = event.clientX;
this.y = event.clientY;
}
})
処理をpreventさせる
- preventとは、html側のデフォルト設定までも起動させない
リンクタグをクリック、飛ばないように設定。
従来のpreventDefault
<div id = "app">
<a v-on:click="noEvent" href="https://google.com">google.com</a>
</div>
new Vue ({
el: '#app',
methods: {
noEvent: function(event) {
event.preventDefault();
}
})
Vue.jsのすごい所
- html側に、v-on:mousemov.preventを与えるのみ!
<div id = "app">
<a v-on:click.prevent href="https://google.com">google.com</a>
</div>
new Vue ({
el: '#app',
})
stopとpreventを、つなげる事も可能
v-on:mousemove.stop.prevent
キー修飾子とは
キーボード入力イベントに対する修飾子
1. エンターキーを入力時点で動作させる。.enter
2. スペースキー入力時点で動作させる。.space
<div id = "app">
<input type="text" v-on:keyup.enter="myAlert">
</div>
new Vue ({
el: '#app',
methods: {
myAlert() {
alert('アラート');
}
}
})
つなげる事も可能
v-on:keyup.enter.space
v-modelとは
双方向データバインディング
1. inputにテキストを入力
2. 変数messageの内容が置き換わる。
3. data内のmessageが置き換わる。
4. h1タグのmessageも変更される。
<div id = "app">
<input type="text" v-model="message">
<h1>{{message}}</h1>
</div>
new Vue ({
el: '#app',
data: {
message: 'こんにちは',
}
})
computedプロパティとは
- dataプロパティでは、動的なデータは扱えない。(プレーンなテキストのみ)
- computedプロパティを使用する
<div id = "app">
<p>{{ counter }}</p>
<button v-on:click="countUp">+1</button>
<p>{{ lessThanThree }}</p>
</div>
new Vue ({
el: '#app',
data: {
counter: 0
},
methods: {
countUp: function() {
this.counter += 1
}
},
computed: {
lessThanThree: function() {
return this.counter > 3 ? '3より上' : '3以下'
}
}
})
computedプロパティの関数、lessThanThreeには
- 引数が必要ではない
- returnで値を返す必要がある
関数lessThanThreeは、
methodsプロパティでは実現できないのか?
結論:
できるけど、、
最適化するならComputedメソッド一択!
- computedプロパティは依存関係に基づきキャッシュされる特徴がある。
- methodsプロパティは、全く関係のないメソッドの更新にも反応する。
- 大規模になると、methodsプロパティで記述した関数が無駄に実行されてしまう。
<div id = "app">
<p>{{ counter }}</p>
<button v-on:click="countUp">+1</button>
<p>{{ lessThanThreeMethod() }}</p>
<p>{{ lessThanThreeComputed }}</p>
</div>
new Vue ({
el: '#app',
data: {
counter: 0
},
methods: {
countUp: function() {
this.counter += 1
},
lessThanThreeMethod: function() {
return this.counter > 3 ? '3より上' : '3以下'
}
},
computed: {
lessThanThreeComputed: function() {
return this.counter > 3 ? '3より上' : '3以下'
}
}
})
watchプロパティとは
- データが変わったとき、非同期処理 が実行
- 非同期処理の中では、thisが使用不可
- computedプロパティでは、returnが必要(同期処理)になる。
- 非同期処理したい場合はwatchプロパティが最適。
3秒でカウントの値(counter)が0にリセットされる非同期処理
<div id = "app">
<p>{{ counter }}</p>
<button v-on:click="countUp">+1</button>
<p>{{ lessThanThreeComputed }}</p>
</div>
new Vue ({
el: '#app',
data: {
counter: 0
},
methods: {
countUp: function() {
this.counter += 1
}
},
computed: {
lessThanThreeComputed: function() {
return this.counter > 3 ? '3より上' : '3以下'
}
},
watch: {
counter: function() {
var vm = this;
setTimeout(function(){
vm.counter = 0
}, 3000)
}
}
})
thisを理解する。
変数messageを、 関数sayHi内で 呼び出してみる。
new Vue({
el: '#app',
data: {
message: 'Hello,World!!'
},
methods: {
sayHi: function() {
<!--これはエラーになる-->
return message;
<!--正しくは、thisが必要-->
return this.message;
}
}
})
<div id = "app">
<p>{{ sayHi() }}</p>
</div>
thisとは、
Vue.jsのインスタンスにアクセスするために必要なプロキシ
括弧の使い方
computedプロパティでは、メソッド名のみを{{二重カッコ内}}に記載
computedプロパティに()を足すと、エラーとなり表示されなくなる。methodsプロパティでは、メソッド名+()を{{二重カッコ内}}に記載
methodプロパティから()を除くと、function () { [native code] }
と表示される。v-ディレクティブの引数としてメソッド名を指定する場合
()は付与してもしなくてもどちらでもOK。
引数には、javascriptコードを書いてもOK。
classをデータにバインディングする方法
{ オブジェクト }で記載
- ハイフンの記載がオブジェクト内にある場合、'bg-color'とシングルクォーテーションで括る必要あり。
<div id = "app">
<h1 :class="{red: true, 'bg-blue': false}">はろう</h1>
</div>
new Vue ({
el: '#app'
})
.red {
color: red;
}
.bg-blue {
background-color: blue;
}
ボタンを設置して、クラスの付与を分岐する。
<div id = "app">
<h1 :class="classObject">はろう</h1>
<button @click="isActive = !isActive">切り替えボタン</button>
</div>
new Vue ({
el: '#app',
data: {
isActive: true
},
computed: {
classObject: function() {
return {
red: this.isActive,
'bg-blue': !this.isActive
}
}
}
})
.red {
color: red;
}
.bg-blue {
background-color: blue;
}
[ 配列 ] で記載
<div id = "app">
<h1 :class="[color, bg]">はろう</h1>
</div>
new Vue ({
el: '#app',
data: {
color: 'red',
bg: 'bg-blue',
}
})
.red {
color: red;
}
.bg-blue {
background-color: blue;
}