在异步回调中更改 ref 的值时,反应性会中断

问题描述 投票:0回答:1

考虑以下简单示例(vue3 + pinia + fullcalendar):

店铺:

export const useFullCalendarStore = defineStore('calendar', () => {
    // ...
    const activeView = ref<Nullable<ViewApi>>(null);

    const options = reactive<CalendarOptions>({
        datesSet: ({ view }) => {
            nextTick(() => {
                activeView.value = view;
            });
        }
    });
    // ...
});

组件:

<template>
    <!-- ... -->
    <div class="text-3240 font-bold">{{ viewHeaderTitle }}</div>
    <!-- ... -->
</template>

<script lang="ts" setup>
import { useFullCalendarStore } from '@/vue/src/store/FullCalendar';

const _fullCalendarStore = useFullCalendarStore();

const viewHeaderTitle = computed(() => {
    return _fullCalendarStore.activeView?.activeStart.toDateString();
});
</script>

通常,每次

activeView
更改时,组件都应该更新,但在这种情况下则不会,因为 ref 更改发生在回调函数内。有什么解决办法吗?

vuejs3 fullcalendar pinia vue-reactivity
1个回答
0
投票

这是代码:

您面临的问题是由于

datesSet
内部回调函数的异步性质造成的。默认情况下,Vue 中的反应性系统不会检测异步回调内所做的更改。为了确保反应性按预期工作,您可以使用
reactive
模块中的
@vue/reactivity
函数为您的商店创建反应性对象,然后为其赋值。以下是修改代码的方法:

// Import reactive from @vue/reactivity
import { reactive } from '@vue/reactivity';

// ...

export const useFullCalendarStore = defineStore('calendar', () => {
    // ...
    const store = reactive({
        activeView: ref<Nullable<ViewApi>>(null)
    });

    const options = reactive<CalendarOptions>({
        datesSet: ({ view }) => {
            nextTick(() => {
                store.activeView.value = view;
            });
        }
    });
    // ...
});

通过将

activeView
属性封装在
reactive
对象中,您可以确保在异步回调中对其所做的任何更改都是反应性的,并将触发组件中的更新。

即使在异步回调内修改

activeView
,此更改也应该能够实现适当的反应性。

© www.soinside.com 2019 - 2024. All rights reserved.