Vue3 对类字段内部更新的反应方式与 Vue2 不同

Posted

技术标签:

【中文标题】Vue3 对类字段内部更新的反应方式与 Vue2 不同【英文标题】:Vue3 does not react to class field internal updates in the same way as Vue2 【发布时间】:2022-01-08 00:57:46 【问题描述】:

我注意到,在 Vue2 中你可以将一个元素绑定到一个类的属性,并且当这个类属性从 Vue 世界之外的某个地方更改时,该元素会更新,这在 Vue3 中似乎是不可能的。

我在这里创建了两个简单的例子来说明我的意思:

Vue2:https://codesandbox.io/s/vue2-6hztv

Vue3:https://codesandbox.io/s/vue3-o2rfn

有一个类有一个内部计时器,它将增加类字段。在 Vue2 中,绑定到 myClass.field 的元素已正确更新,但在 Vue3 中没有任何反应。

我的问题是

1.为什么这里 Vue2 和 Vue3 有区别?

2。我怎样才能在 Vue3 中实现类似于工作中的 Vue2 示例?

请注意,我无法在 Vue 生命周期方法中运行计时器。类字段需要自己更新。

这是不起作用的 Vue3 代码:

html

<div id="app"> myClass.field </div>

javascript

class MyClass 
  field = 0;

  constructor() 
    setInterval(() => 
      this.field++;
    , 1000);
  


export default 
  data() 
    return 
      myClass: new MyClass(),
    ;
  ,
;

【问题讨论】:

【参考方案1】:

正如this answer 中所述,在 Vue 3 中创建了代理对象以启用响应性。构造函数中的this 指的是原始类实例而不是代理,因此它不能是反应式的。

解决方案是将类构造函数和期望this 具有反应性的副作用的设置分开。 setup 方法可以实现流畅的接口模式,使其更易于使用:

class MyClass 
  field = 0;

  init() 
    setInterval(() => 
      this.field++;
    , 1000);

    return this;
  

在选项 API 中是:

  data() 
    return 
      myClass: new MyClass(),
    ;
  ,
  created() 
    this.myClass.init();
  

在组合 API 中是::

  const myClass = reactive(new MyClass()).init();

【讨论】:

非常感谢您的回答!我现在明白了为什么不能像在 vue2 中那样做的原因。但是,我仍在寻找一种方法来监视由自身启动的类中的更改,而不是通过任何 vue 生命周期方法。也许最后一个问题的答案就是不可能。 @rawpower 这是可能的,但不适用于在构造函数中运行的副作用,例如您的情况。在构造函数中执行此操作需要一个类知道它在 Vue 组件中使用,并使属性显式使用组合 API(在链接问题的另一个答案中显示)。 Vue 是面向 FP 的,你不会从使用 OOP 中受益很多。 感谢@Estus Flask。是时候弄清楚新的代码结构或更改为 vue2 了。

以上是关于Vue3 对类字段内部更新的反应方式与 Vue2 不同的主要内容,如果未能解决你的问题,请参考以下文章

vue2与vue3的区别

关于vue2与vue3

从Vue2.0到Vue3.0,哪些技术又要更新了?

简单对比vue2.x与vue3.x响应式及新功能

在设置选项内的 axios 响应回调中更新反应数据 - Vue 3

Vue 3.0 源码分析-数据侦测