VUE 3反应性不是从类实例内部触发的

代码:https://codepen.io/codingkiwi_/pen/XWMBRpW

假设您有一个类:

class MyClass {
  constructor(){
    this.entries = ["a"];

    //=== example change triggered from INSIDE the class ===
    setTimeout(() => {
      this.entries.push("c");
    }, 1000);
  }
}

在组件中,您将获得该类的一个实例:

const { reactive } = Vue;

const App = {
  setup() {
    const myobject = reactive(new MyClass());

    //=== example change triggered from OUTSIDE the class ===
    setTimeout(() => {
      myobject.entries.push("b");
    }, 500);
    
    return {
      myobject
    };
  }
}

DOM中的my对象条目数组将显示条目"a""b",但不显示"c"


解决方案

DOM中的my对象条目数组将显示条目"a""b",但不显示"c"

这是因为"a"已在数组中,因为我们使实例成为反应性实例,并且"b"的推送从对象外部通过代理发生。

明确:const myobject不包含MyClass实例,它包含处理/包装原始实例的实例的Proxy!并且它是传递给DOM/模板的代理。

"c"的推送是从对象内部进行的,而不是通过代理。因此"c"将被推送到阵列,但不会触发反应性更改。

修复:

将我们从类内部显式更改的数组标记为reactive,如下所示:

class MyClass {
  constructor(){
    this.entries = reactive(["a"]);

    //=== example change triggered from INSIDE the class ===
    setTimeout(() => {
      this.entries.push("c");
    }, 1000);
  }
}

或者像文档建议的那样只使用代理对象:

这里的最佳实践是永远不要持有对原始原始对象的引用,而只使用被动版本:

单据:https://v3.vuejs.org/guide/reactivity.html#proxy-vs-original-identity

相关文章