一、計算プロパティ computed#
1. 例#
<div id="app">
<div>{{message}}</div>
<div>{{revermessage}}</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'hello,wolrd'
},
computed: {
revermessage: function() {
return this.message.split('').reverse().join('')
}
}
})
</script>
計算プロパティsevermessage
を宣言し、computed
内でmessage
に対していくつかのメソッド操作を行った後の戻り値に指し示します。
この時vm.severmessage
はvm.message
の変化に依存し、message
のデータが変更されるとsevermessage
が更新されます。
2. 計算プロパティのキャッシュとメソッド#
式内でメソッドを呼び出すことで、望む効果を得ることもできます。
<div id="app">
<div>{{message}}</div>
<div>{{revermessage()}}</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'hello,wolrd'
},
methods: {
revermessage: function() {
return this.message.split('').reverse().join('')
}
}
})
</script>
テストの結果、両者の結果は同じです。
同じ関数を計算プロパティではなくメソッドとして定義することもできます。最終的な結果は確かに完全に同じです。
違いは:計算プロパティはその応答性依存に基づいてキャッシュされ、応答性依存、つまりmessage
が変更された時のみ再評価されます。これは、message
が変更されない限り、revermessage
計算プロパティに何度アクセスしても以前の計算結果のキャッシュを返すだけで、計算プロパティの関数を直接実行することはありません。
一方、メソッドは、再描画がトリガーされるたびに、メソッドを呼び出すと関数が一度実行されます。これには追加のオーバーヘッドがあります。
なぜキャッシュが必要なのでしょうか?性能オーバーヘッドが大きい計算プロパティ A があり、それが巨大な配列を遍歴し大量の計算を行う必要があると仮定します。その後、他の計算プロパティが A に依存している可能性があります。キャッシュがなければ、A のゲッターを何度も実行することは避けられません!キャッシュを望まない場合は、メソッドを使用してください。
3. 計算プロパティとウォッチプロパティ#
vue には、vue インスタンス上のデータの変化を観測するもう一つの方法があります:ウォッチプロパティ--watch。
<div id="app">
{{fullname}}
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
firstname: 'a',
lastname: 'b',
fullname: 'ab'
},
watch: {
firstname: function(val) {
this.fullName = val + ' ' + this.lastName
},
lastname: function(val) {
this.fullName = this.firstName + ' ' + val
}
}
})
</script>
使用過程は非常に煩雑で繰り返しが多いので、計算プロパティを使ってみましょう。
<div id="app">
{{fullname}}
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
firstname: 'a',
lastname: 'b'
},
computed: {
fullname: function() {
return this.firstname + this.lastname
}
}
})
</script>
非常に簡単かつ迅速に、我々が望む関数表現を得ることができました。
4. 計算プロパティの setter#
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
今、コンソールにvm.fullName = 'John Doe'
と入力すると、ページが反応し、setter
が呼び出され、vm.firstname
とvm.lastname
もそれに応じて更新されます。
二、class と style のバインディング#
1. オブジェクト構文#
v-bind:class
にオブジェクトを渡すことで、動的にclass
を切り替えることができます。
<div v-bind:class="{active: ok}"></div>
ok
のブール値を制御することで、動的に class を制御できます。
複数のフィールドを作成することもでき、通常のclassName
の存在に影響を与えません。
html:
<div
class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }"
></div>
data:
data{
isActive: true,
hasError: false
}
結果は:
<div class="static active"></div>
isActive
またはhasError
が変化すると、class リストがそれに応じて更新されます。例えば、hasError
の値がtrue
の場合、class リストは"static active text-danger"
に変わります。
バインディングするデータオブジェクトは、インラインテンプレート内に直接書く必要はありません。
<div id="app">
<div v-bind:class="classobject"></div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
classobject: {
active: true,
'text-danger': true
}
},
})
</script>
<!-- <div class="active text-danger"></div> -->
className
に特殊な記号がある場合は、必ず引用符''
または""
を付ける必要があります。
2. 配列構文#
配列をv-bind:class
に渡すことで、class リストを適用できます。
<div v-bind:class="[activeClass, errorClass]"></div>
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
レンダリング結果は:
<div class="active text-danger"></div>
3. コンポーネントでの使用#
カスタムコンポーネントでclass
プロパティを使用する場合、これらの class はそのコンポーネントのルート要素に追加されます。この要素に既に存在する class は上書きされません。
Vue.component('my-component', {
template: '<p class="foo bar">Hi</p>'
})
そして使用時にいくつかのclass
を追加します:
<my-component class="baz boo"></my-component>
html は次のようにレンダリングされます:
<p class="foo bar baz boo">Hi</p>
データバインディングされたclass
にも同様に適用されます。
<my-component v-bind:class="{ active: isActive }"></my-component>
isActive
が truthy の場合、HTML は次のようにレンダリングされます:
<p class="foo bar active">Hi</p>
4. インラインスタイル style のバインディング#
v-bind:style
のオブジェクト構文は非常に直感的で、CSS に非常に似ていますが、実際には JavaScript オブジェクトです。CSS プロパティ名はキャメルケース
または引用符付きのハイフン
で命名できます。
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
js:
data: {
activeColor: 'red',
fontSize: 30
}
または、オブジェクトに直接バインドすることで、テンプレートをより明確にすることができます。
<div v-bind:style="styleObject"></div>
js:
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
複数のオブジェクトを一つの要素に適用することもできます。
<div v-bind:style="[baseStyles, overridingStyles]"></div>
自動的にプレフィックスを追加
v-bind:style
がブラウザのプレフィックスを使用する必要がある場合、例えば-webkit-
など、vue は自動的に検出し、適切なプレフィックスを生成します。