考虑以下简单示例(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 更改发生在回调函数内。有什么解决办法吗?
这是代码:
您面临的问题是由于
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
,此更改也应该能够实现适当的反应性。