Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/476.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Vue 3不是从类实例内部触发的_Javascript_Vue.js_Vuejs3_Vue Composition Api_Vue Reactivity - Fatal编程技术网

Javascript Vue 3不是从类实例内部触发的

Javascript Vue 3不是从类实例内部触发的,javascript,vue.js,vuejs3,vue-composition-api,vue-reactivity,Javascript,Vue.js,Vuejs3,Vue Composition Api,Vue Reactivity,代码笔: 假设你有一门课: class-MyClass{ 构造函数(){ this.entries=[“a”]; //==从类内部触发的示例更改=== 设置超时(()=>{ 这个.entries.push(“c”); }, 1000); } } 在组件中,您可以得到该类的一个实例: const{reactive}=Vue; 常量应用={ 设置(){ const myobject=reactive(新的MyClass()); //==从类外部触发的示例更改=== 设置超时(()=>{ myobj

代码笔:

假设你有一门课:

class-MyClass{
构造函数(){
this.entries=[“a”];
//==从类内部触发的示例更改===
设置超时(()=>{
这个.entries.push(“c”);
}, 1000);
}
}
在组件中,您可以得到该类的一个实例:

const{reactive}=Vue;
常量应用={
设置(){
const myobject=reactive(新的MyClass());
//==从类外部触发的示例更改===
设置超时(()=>{
myobject.entries.push(“b”);
}, 500);
返回{
肌体
};
}
}
DOM中的myobject.entries数组将显示条目
“a”
“b”
,但不显示
“c”

DOM中的myobject.entries数组将显示条目
“a”
“b”
,但不显示
“c”

这是因为
“a”
已经在数组中,因为我们使实例处于反应状态,
“b”
的推送是从对象外部通过代理进行的

要清楚
const myobject
不包含
MyClass
实例,它包含处理/包装原始实例的实例的
代理
!它是传递给DOM/模板的代理

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

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

class-MyClass{
构造函数(){
this.entries=反应性([“a”]);
//==从类内部触发的示例更改===
设置超时(()=>{
这个.entries.push(“c”);
}, 1000);
}
}
或者,尝试仅使用代理对象,如文档建议的:

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


文档:

另一个答案解释道,
反应性
创建代理对象以启用反应性
构造函数中的此
引用原始的
MyClass
实例,而不是代理,因此它不能是被动的

这表示代码中的问题<代码>反应式考虑在
MyClass
构造函数中发生的同步操作。在构造函数中执行异步副作用是一种反模式,原因包括使用这种构造函数的代码可能带来的影响

这可以通过以下方法解决:

class MyClass {
  constructor(){
    // synchronous stuff only
    this.entries = ["a"];
  }

  init() {
    // asynchronous stuff, probably return a promise
    setTimeout(() => {
      this.entries.push("c");
    }, 1000);
  }
}


非常感谢。构造函数中的反模式实际上就在示例中:)在实际代码中,我遇到了这个问题,我在构造函数中定义了一个侦听器函数
this.listener=()=>{this.entities.push();}
(以后可以取消订阅),因此,正如您所解释的,“这”在引用原始实例的侦听器函数中,在这种情况下,解决方法是不使用箭头方法和延迟绑定方法,例如,
listener
是常规方法,用作
event=>this.listener(event)
this.listener.bind(this)
。IIRC这是装饰师可以做的事情,以防您的设置支持它们。正如另一篇文章所建议的那样,该类不一定要在Vue组件内部使用硬编码的
反应式
,但它的设计需要考虑到这一点。
const myobject = reactive(new MyClass());
myobject.init() // `this` is a proxy inside `init`