
Vue.js ルーティング演習問題
基本概念まとめ 1. ルーティングの基本設定 2. ナビゲーションガード 3. 動的ルーティング 演習問題(全24問) 初級問題(6問) 基本ルーティング ナビ […]
Vue.jsには状態の扱い方として methods 、 computed 、 watch の3つの主要なオプションがあります。それぞれの特徴をまずは理解します。
オプション | 主な役割 | タイミング | 特徴 |
---|---|---|---|
methods | 関数として呼び出す処理 | 明示的に呼び出されたとき | データを変更したり処理したりするための通常の関数 |
computed | 計算結果を自動で返す | 依存するデータが変化したときに自動再評価 | キャッシュ付きのリアクティブ計算プロパティ。表示用などに最適 |
watch | 値の変化を監視して処理を実行 | 監視対象のデータが変わった瞬間に実行される副作用 | API呼び出しやログ出力など、処理をトリガーさせたいときに使う |
<template>
<div>{{ getFullName() }}</div>
</template>
<script>
export default {
data() {
return {
firstName: 'Taro',
lastName: 'Yamada'
}
},
methods: {
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
}
}
</script>
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
ディレイバウンス処理とは、メール送信時に一時的なエラーが発生した場合、システムが自動的に再送を試みる処理のことです。
computed: {
totalPrice() {
return this.items.reduce((sum, item) => sum + item.price, 0);
}
}
<template>
<button @click="increment">Count: {{ count }}</button>
</template>
<script>
export default {
data() {
return {
count: 0
}
},
methods: {
increment() {
this.count++;
}
}
}
</script>
computed: {
fullName() {
return `${this.firstName} ${this.lastName}`;
}
}
watch: {
inputValue(newVal, oldVal) {
console.log(`Input changed from ${oldVal} to ${newVal}`);
}
}
<template>
<div>{{ fullName }}</div>
</template>
<script>
export default {
data() {
return {
firstName: 'Taro',
lastName: 'Yamada'
}
},
computed: {
fullName() {
return `${this.firstName} ${this.lastName}`;
}
}
}
</script>
computed: {
filteredProducts() {
return this.products.filter(product => {
return product.price <= this.maxPrice && product.category === this.selectedCategory;
});
}
}
watch: {
email(newVal) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
this.emailValid = regex.test(newVal);
}
}
watch: {
searchQuery: {
handler(newVal) {
clearTimeout(this.debounceTimer);
this.debounceTimer = setTimeout(() => {
this.search();
}, 500);
}
}
}
computed: {
fullName: {
get() {
return `${this.firstName} ${this.lastName}`;
},
set(newValue) {
const names = newValue.split(' ');
this.firstName = names[0];
this.lastName = names[1] || '';
}
}
}
watch: {
user: {
handler(newVal) {
console.log('User data changed');
},
deep: true
}
}
watch: {
firstName: 'nameChanged',
lastName: 'nameChanged'
},
methods: {
nameChanged() {
console.log('Name changed');
}
}
コンポーネント作成時にもhandlerを実行したい場合に使用から
watch: {
propValue: {
handler(newVal) {
this.initialize(newVal);
},
immediate: true
}
}
watch: {
'user.id': {
handler(newVal) {
this.fetchUserData(newVal);
}
}
}
computed: {
[`${this.prefix}Value`]() {
return this.calculateValue();
}
}
watch: {
'$store.state.user': {
handler(newVal) {
this.localUser = { ...newVal };
},
deep: true
}
}
大きなリストのフィルタリング注意点:
例:
// 自動依存追跡 watchEffect
watchEffect(() => {
console.log(this.count + this.offset);
});
// 明示的監視 watch
watch(
() => this.count,
(newVal, oldVal) => {
// 処理
}
)
watch: {
obj: {
handler(newVal, oldVal) {
if (!this.isEqual(newVal, oldVal)) {
// 処理
}
},
deep: true
}
}
利点: パフォーマンス向上、不要なトリガー防止
import { defineComponent } from 'vue';
export default defineComponent({
computed: {
fullName(): string {
return `${this.firstName} ${this.lastName}`;
},
// ジェネリック型
itemsCount(): number {
return this.items.length;
}
}
});