Answer a question

Codepen: https://codepen.io/codingkiwi_/pen/XWMBRpW

Lets say you have a class:

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

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

And in a component you get an instance of that class:

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
    };
  }
}

The myobject.entries array in the DOM will display the entries "a" and "b", but not "c"

Answers

The myobject.entries array in the DOM will display the entries "a" and "b", but not "c"

This is because "a" was already in the array as we made the instance reactive and the push of "b" happened from outside the object, through the Proxy.

To be clear: the const myobject does not contain the MyClass instance, it contains a Proxy of the instance which handles/wraps the original instance! And it is the proxy which is passed to the DOM / Template.

The push of "c" happened from inside the object, not through the proxy. So "c" will be pushed to the array, but no reactivity change will be triggered.

Fix:

Mark the array that we change from inside the class explicitly as reactive like this:

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

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

Alternatively try to only work with the proxied object like the docs suggest:

The best practice here is to never hold a reference to the original raw object and only work with the reactive version:

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

Logo

前往低代码交流专区

更多推荐