【问题标题】:Vue3 does not react to class field internal updates in the same way as Vue2Vue3 对类字段内部更新的反应方式与 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(),
    };
  },
};

【问题讨论】:

    标签: javascript vue.js vuejs2 vuejs3


    【解决方案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 了。
    猜你喜欢
    • 1970-01-01
    • 2021-07-25
    • 2021-06-12
    • 2021-06-16
    • 2014-07-02
    • 2021-07-03
    • 2021-08-14
    • 1970-01-01
    • 2021-09-09
    相关资源
    最近更新 更多