You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 14:38:29