Vue3+TypeScript中Pinia的weekDisplay计算属性不响应式更新问题
问题:Pinia计算属性未随Date类型状态更新
在Vue3+TypeScript项目中使用Pinia管理状态,控制当前显示的周数。点击PageHeader组件的按钮调用changeDisplay修改currentDate后,currentDate在store和组件中均正常更新,但用computed包裹的weekDisplay计算属性值未更新,导致页面上的周数文本不变化。
相关代码:
src/stores/Activities.ts
import { defineStore } from "pinia"; import { computed, ref } from "vue"; import { weekName } from "@/main"; ... /* 类型、枚举等 */ export const useActivitiesStore = defineStore("activities", () => { const eventsMap = ref<Map<string, Activity[]>>(new Map()); const currentDate = ref<Date>(new Date()); const weekDisplay = computed(() => weekName(currentDate.value)); function changeDisplay(change: number): void { currentDate.value.setDate(currentDate.value.getDate() + 7 * change); } return { eventsMap, currentDate, weekDisplay, changeDisplay }; });
src/components/PageHeader.vue
<script setup lang="ts"> ... /* 其他导入 */ import { useActivitiesStore } from "@/stores/Activities"; import { storeToRefs } from "pinia"; import { computed } from "vue"; let store = useActivitiesStore(); const { eventsMap, currentDate, weekDisplay } = storeToRefs(store); </script> <template> <header id="header"> ... <section id="week-navigation-container" class="week-navigation"> <article id="previous-week-button" class="week-button" @click="store.changeDisplay(-1)"> <IconLeftArrow class="left-arrow" /> <Tooltip text="Previous week" /> </article> <article id="open-calendar-button" class="week-display"> <h1 class="font-menu-title"> {{ weekDisplay }} </h1> <Tooltip text="Open calendar" /> </article> <article id="next-week-button" class="week-button" @click="store.changeDisplay(1)"> <IconRightArrow class="right-arrow" /> <Tooltip text="Next week" /> </article> </section> </header> </template>
解决方案
问题根源
currentDate是ref包裹的Date对象,而Date属于引用类型。setDate方法仅修改了Date对象内部的时间值,并未改变currentDate.value的引用地址。Vue的响应式系统对引用类型的触发逻辑是:只有当引用本身发生变化时,才会触发相关计算属性和视图的更新,因此weekDisplay没有重新计算。
修复方法
修改changeDisplay函数,创建新的Date对象替换原有currentDate.value,让Vue检测到引用变化:
function changeDisplay(change: number): void { // 基于当前日期创建新的Date对象 const newDate = new Date(currentDate.value); // 修改新日期的天数 newDate.setDate(newDate.getDate() + 7 * change); // 替换原ref的值,触发响应式更新 currentDate.value = newDate; }
修改后,currentDate.value的引用发生变化,会触发weekDisplay计算属性重新执行,页面上的周数文本也会随之更新。
内容的提问来源于stack exchange,提问作者Serban Untu
相关产品推荐
相关产品推荐

