Vueまとめパート4(小技集)
こちらの記事は、Adnan Babakan 氏によりDev.to上で公開された『 Vue advanced tricks cheat sheet 』の邦訳版です(原著者から許可を得た上での公開です)
DEV.toコミュニティの皆さん、こんにちは!
普通にVueで開発をしていると、解決するべき多くの問題に遭遇しますが、開発者にとって長時間苛立たせる問題を解決することほど気持ちいいことはないなと感じています!
ここで、私はいくつかの問題を解決するために使用したいくつかの小技を書いています。これを読んでいるあなたにもいつか役立つかもしれません。
vm.$forceUpdate()
- 強制的再レンダリング
場合によっては仮想DOMの一部の変更を反映できないことがあるため、このような場合ではVueにコンポーネントを再レンダリングさせる必要がある。
このような場合には他にもv-if
を使うなどいくつか方法があるが、forceUpdate
メソッドを使うのが正しいとされている。
export default {
methods: {
forceUpdateMyComponent() {
this.$forceUpdate()
},
},
}
Vueインスタンスでこのメソッドを使用するためには$
をメソッド名の前につける必要があることに注意。
使ってみるとわかるがどの算出プロパティも更新されず、コンポーネントのビューが強制的に再レンダリングされるだけだ。
ネストされたデータの監視
場合によっては、ネストされたデータを監視したい場合もあるだろう。このような場合は.
チェーンで実現できる。
export default {
data() {
return {
myInfo: {
firstName: 'Adnan'
}
}
},
// `myInfo.firstName`とつなげることで監視プロパティにできる
watch: {
'myInfo.firstName'() {
console.log('Here')
}
}
}
上記のコードは、オブジェクト内の監視するプロパティどれかがわかっている場合に使える。
しかし、オブジェクト全体とその値を監視したい場合はどうすればいいか?
その場合は次のようにする。
export default {
data() {
return {
myFruits: {apple: 'red', banana: 'yellow'}
}
},
methods: {
changeIt() {
this.myFruits.apple = 'green'
}
},
watch: {
myFruits: {
// `deep`, `handler`プロパティを追加する
deep: true,
handler() {
console.log('Fruits updated!')
}
}
}
}
監視プロパティを関数としてではなくオブジェクトとして定義し、deep
キーとその値をtrue
にセットする。これによってオブジェクト全体を監視でき、handler
と呼ばれる関数内にデータが変更されたときに発生させたいことを書くことができる。
v-modelをサポートするカスタム(子)コンポーネント
ご存じのとおりv-model
はコンポーネント(input要素)とデータプロパティを介した双方向バインディングを実現するために使われる。
カスタム(子)コンポーネントを作成し、v-model
をサポートさせたい場合は、input
キーワードを発行し、最初にコンポーネントに渡されるものをv-model
で受け取るために、value
と呼ばれるpropを取得する必要がある。
より理解しやすくするために、次のコードを見てみよう。
<template>
<div>
<label>My custom test input: <input :value="inputValue" @input="emitTheData" /></label>
</div>
</template>
<script>
export default {
props: ['value'],
data() {
return {
inputValue: value
}
},
methods: {
emitTheData() {
this.$emit('input', this.inputValue)
}
}
}
</script>
この単純なコンポーネントは、渡されたデータを2つの方向にバインドする。
注:ご覧の通り、value
というpropをinputValue
というデータに割り当てて、それをinputタグで使用した。propをinput要素に直接渡すことができると思うかもしれないが、Vue公式で言われている通り、propsは直接変更しない方がよい。
関数型コンポーネント
監視プロパティまたは算出プロパティとメソッドのないコンポーネントがあると想像してみよう。それを使うだけで、props
を使ってコンポーネントをレンダリングすることが可能だ。これが可能であれば、ライフサイクルメソッドもないため描画時間を短縮することができる。
それが関数型コンポーネントだ。
関数型コンポーネントは次のように定義できる。
<!-- `template`要素の中に`functional`含めると関数型コンポーネントになる -->
<template functional>
<div>{{ props.foo }}</div>
</template>
このコンポーネントは関数型コンポーネントであるため、this
コンテキストは使えないことに注意。
Vueの関数型コンポーネントの詳細については、以下のリンクから確認できる。