MeWrite Docs

Vue computed property not updating

Vue.jsでcomputedプロパティが更新されない場合の原因と解決方法

概要

Vue.jsでcomputedプロパティが依存データの変更時に更新されない問題は、リアクティビティの仕組みを理解していないことが原因です。

問題のパターン

1. 配列のインデックス直接変更(Vue 2)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// NG: Vue 2ではリアクティブにならない
export default {
  data() {
    return {
      items: ['a', 'b', 'c']
    };
  },
  methods: {
    updateItem() {
      this.items[0] = 'x'; // リアクティブでない
    }
  }
}

解決策:

1
2
3
4
5
6
7
// Vue 2
this.$set(this.items, 0, 'x');
// または
this.items.splice(0, 1, 'x');

// Vue 3
this.items[0] = 'x'; // OK(Proxyベース)

2. オブジェクトへの新規プロパティ追加(Vue 2)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// NG: 新規プロパティはリアクティブにならない
export default {
  data() {
    return {
      user: { name: 'John' }
    };
  },
  methods: {
    addAge() {
      this.user.age = 30; // リアクティブでない
    }
  }
}

解決策:

1
2
3
4
5
6
7
// Vue 2
this.$set(this.user, 'age', 30);
// または
this.user = { ...this.user, age: 30 };

// Vue 3
this.user.age = 30; // OK

3. computedで非リアクティブな値を参照

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// NG: 外部変数はリアクティブでない
let externalVar = 0;

export default {
  computed: {
    doubled() {
      return externalVar * 2; // 変更を検知しない
    }
  }
}

解決策:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
export default {
  data() {
    return {
      reactiveVar: 0
    };
  },
  computed: {
    doubled() {
      return this.reactiveVar * 2;
    }
  }
}

4. Vue 3 Composition APIでの問題

1
2
3
4
5
// NG: refをunwrapせずにアクセス
import { ref, computed } from 'vue';

const count = ref(0);
const doubled = computed(() => count * 2); // count.valueを使うべき

解決策:

1
2
3
4
import { ref, computed } from 'vue';

const count = ref(0);
const doubled = computed(() => count.value * 2);

5. 非同期処理内でのリアクティビティ

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// NG: 非同期処理後にリアクティビティが失われる
export default {
  data() {
    return {
      user: null
    };
  },
  async mounted() {
    const data = await fetchUser();
    // これは動作する
    this.user = data;
  }
}

6. refとreactiveの混同(Vue 3)

1
2
3
4
5
// NG: reactiveオブジェクトの再代入
import { reactive } from 'vue';

let state = reactive({ count: 0 });
state = reactive({ count: 1 }); // リアクティブ接続が切れる

解決策:

1
2
3
4
5
6
7
// プロパティを更新
state.count = 1;

// または ref を使用
import { ref } from 'vue';
const state = ref({ count: 0 });
state.value = { count: 1 }; // OK

7. watchで深いネストを監視

1
2
3
4
5
// NG: ネストした変更を検知しない
watch(
  () => state.nested,
  (newVal) => console.log(newVal)
);

解決策:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
watch(
  () => state.nested,
  (newVal) => console.log(newVal),
  { deep: true }
);

// または
watch(
  () => state.nested.value,
  (newVal) => console.log(newVal)
);

デバッグ方法

1
2
3
4
5
6
7
8
9
// Vue DevToolsを使用
// または
watch(
  () => state,
  (newVal, oldVal) => {
    console.log('State changed:', newVal, oldVal);
  },
  { deep: true }
);

関連エラー

関連エラー

Vue の他のエラー

最終更新: 2025-12-17