【问题标题】:Reactivity in Vue3 Composition APIVue3 组合 API 中的反应性
【发布时间】:2021-06-11 14:00:48
【问题描述】:

我正在尝试让 Vue 3 组件对底层 Typescript 对象的更改做出反应。有一个普通的(非反应性的)Timer 对象,它通过重复的 setTimeout 对象将其自己的公共 percentRemaining 属性从 100 更新为 0。

计时器倒计时,如果我创建一个本地间隔函数来吐出值,我可以吐出它的新值。但在控制台中,我只收到“计时器保留”消息,而没有收到“手表保留”消息。我还在组件模板中显示了 percentRemaining 值,但它仍然是 100。

控制台显示如下内容:

Timer remain: 98.95958383353342
Timer remain: 97.93917567026811
Timer remain: 96.9187675070028
Timer remain: 95.87835134053621
Timer remain: 94.83793517406963
Timer remain: 93.81752701080433
Timer remain: 92.77711084433774

我尝试了不同风格的reftoReftoRefs,结果相同。我尝试将 percentRemaining 包装在 computed(() => timer.percentRemaining) 中 - 它也只是返回 100 而无需更新。

我可以通过类似的reactive 调用和本地setInterval 成功获取本地到组件的普通对象来更新,并且观察它的计数器工作正常。

我不确定这是因为我在做外部 setTimeout,还是只是误解了关于 Composition API 的一些基本知识。

import { defineComponent, reactive, watch } from 'vue';
import { Timer } from '@/app/timers/timer';

const TimerComponent = defineComponent({

    props: {
        timer: {
            type: Timer,
            required: true
        }
    },
    setup(props) {

        const timer = reactive(props.timer);
        // const { timer } = reactive(props);
        // const { timer } = toRefs(props);

        const intervalTimer = setInterval(() => {
            console.log(`Timer remain: ${timer.percentRemaining}`)
        }, 50);

        watch(() => timer.percentRemaining, (newValue) => {

            console.log(`Watch remain: ${newValue}`);

        });

        return {

            timer,
            intervalTimer

        }

    }

});

【问题讨论】:

  • 但是你并没有改变会触发观察者的反应状态
  • 对象正在定时器上更新自己。我正在尝试移植一些在纯 Typescript 环境(没有 VueJS)中运行的代码,我希望有一种方法可以简单地在我的普通对象周围添加反应式包装器。我在将对象移动到 Vuex 存储或只是 ref-fed 状态对象方面取得了一些成功,并且它们正在更新而没有由组件发起更改,但这让我感到困惑。我还在我的前啊哈!不过,关于解决合成 API 的灯泡时刻阶段。
  • timer.percentRemaining 应该在计时器组件内部还是从父组件更新?
  • 我不希望组件负责更新对象,但我认为天亮了。在其他情况下,某些东西可以工作——它不是来自组件,但它正在仍在使用状态/存储对象并“通过”反应性对象引用传递给它。似乎我无法摆脱纯粹是对象内部的逻辑。我在想reactive 引用仍然会“知道”该值已更改,但这将依赖于轮询它或类似的东西。你至少让我思考 - 谢谢。

标签: typescript vuejs3 vue-composition-api


【解决方案1】:
  1. 首先,您在 props 和 setup 输出中使用了相同的名称 timer,这可能是一个错误。
  2. 你想要的是:让 vue 知道你对自己的普通对象的直接操作。
    我觉得不可能
  3. reactivity api 是 vue 中的一个独立模块,您可以将它们用作响应式功能包。您需要做的就是在定义它们时将自己的计时器 obj 替换为 reactive(your timer obj),并消除任何副作用

【讨论】:

    猜你喜欢
    • 2021-06-08
    • 2021-08-30
    • 2021-09-09
    • 2021-09-16
    • 2022-09-25
    • 2021-10-24
    • 2021-09-09
    • 2021-02-23
    • 2021-11-08
    相关资源
    最近更新 更多