简单示例中Vue.js 3与Vue.js 2的React性差异

piv4azn7  于 2023-02-24  发布在  Vue.js
关注(0)|答案(2)|浏览(213)

我有一个项目,我正在从Vue2迁移到Vue3。我遇到了这个问题,动态更改的对象没有反映在模板中。
例如,我有一个类 TestClass,它有一个数字属性 duration,在构造函数中,我每秒递增这个duration,这个类是:

export default class TestClass {
  constructor(data) {
    this.name = data.name;
    this.duration = data.duration;

    setInterval(() => {
      ++this.duration;
    }, 1000);
  }
}

这应该是启动计时器一旦类被创建与构造函数调用。然而,我没有看到任何变化,当我在一个组件中使用类,除了从初始设置的值。这是我的 TestComponent,我在其中使用的TestClass:

export default {
  name: "TestComponent",
  data() {
    return {
      testObject: new TestClass({ name: "Test Class", duration: 5 }),
    };
  },
  computed: {
    time() {
      return this.testObject.duration;
    },
  },
};
<template>
  <span> Class time: {{ time }}</span>
</template>

与Vue2不同,在Vue2中,变更将显示在模板中,而在Vue3中,变更始终保持在初始值(本例为5)。我的问题是,如何在本例中实现与Vue2相同的行为?我知道2和3之间的React性发生了变化。

6ljaweal

6ljaweal1#

您需要使用ref()reactive()函数来创建React性。忘记Vue 3中的OOP。选项API仍在工作,但您必须记住data()值的工作方式与ref()类似,为了实现React性,您需要每次为data()函数中的每个变量分配新值。在您的代码中,只执行一次。然后改变非React性的内部对象值。
下面是一个如何在Composition API中执行此操作的示例。

可组合闭包函数composable/timer.js

export function useTimer(data) {
   const name = ref(data.name)
   const duration = ref(data.duration)
   
   setInterval(() => {
      ++duration.value;
    }, 1000);

   return {name, duration}
}

组件

<script setup>
const { name, duration } = useTimer(data)
</script>
<template>
  <span> Closure function {{ name }} time: {{ duration }}</span>
</template>
o7jaxewo

o7jaxewo2#

在Vue 3中,React变量被 Package 在代理对象中。testObject不包含TestClass示例,它是该示例的代理。
递增duration发生在对象内部,而不是通过代理,因此不会检测到React性变化。我个人会使用Composition API的可组合路线,如另一个答案中所述,但如果您想继续使用Options API,一个变通方案是将异步操作移到构造函数之外(无论如何,它是一个反模式),并从组件创建的钩子调用setInterval函数。

export default class TestClass {
  constructor(data) {
    this.name = data.name;
    this.duration = data.duration;
  }
  init() {
    setInterval(() => {
      ++this.duration;
    }, 1000);
  }
}
export default {
  name: 'Test',
  data() {
    return {
      testObject: new TestClass({ name: 'Test Class', duration: 5 })
    };
  },
  computed: {
    time() {
      return this.testObject.duration;
    }
  },
  created() {
    this.testObject.init();
  }
};

相关问题