vuejs/vue

When ref and reactive are used together with computed and watch, computed loses its effect.

milletlovemouse opened this issue · 2 comments

Version

2.7.16-beta.2

Reproduction link

codesandbox.io

Steps to reproduce

Go to the reproduction link and first open the console to see the print information.
computed relies on ref or reactive, and watch relies on computed. At this time, computed loses its effect and cannot get the latest data. The following code replaces reactive with ref and has the same effect.

import { ref, reactive, computed, watch } from "vue";
const state = reactive({});
const com1 = computed(() => state.a || []);
const com2 = computed(() => state.b || []);
watch(
  () => com1.value,
  () => {
    console.log(com1.value, com2.value, "watch");
  }
);
window.setTimeout(() => {
  const data = { a: [{ code: 1 }], b: [{ code: 2 }] };
  Object.keys(data).forEach((key) => {
    state[key] = data[key];
  });
  console.log(com1.value, com2.value, "test");
}, 1000);

What is expected?

// print:
[Object] [Object] test
[Object] [Object] watch

What is actually happening?

print:
[] [Object] test

In Vue 2.7, **all Vue 2 change detection caveats still apply.

This means reactive({}) creates an empty object that won't track newly added properties. To ensure properties can be tracked, you need to initialize them with null or undefined values just like in data().

In Vue 2.7, **all Vue 2 change detection caveats still apply.

This means reactive({}) creates an empty object that won't track newly added properties. To ensure properties can be tracked, you need to initialize them with null or undefined values just like in data().

I thought vue2.7 would be the same as vue3🥰