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

Vue中watchEffect监听Store值异常:为何获取值为undefined?

问题原因与修复方案

核心问题:Ref的访问方式错误

你用ref()包裹了整个store对象,但在<script>中直接访问mystore.myVariable是错误的——ref的响应式值存储在.value属性中。模板里Vue会自动为ref解包,所以模板中mystore.myVariable能正常显示,但脚本里必须通过.value访问。

同时你的watchEffect只触发一次,是因为它没有追踪到有效的响应式依赖(你访问的mystore.myVariable不是响应式的,只是一个undefined值)。

具体修复步骤

1. 优化Store的写法(解决this指向问题)

当前setMyVariable方法里的this指向存在不确定性,建议把方法抽离出来,操作更清晰:

// stores/mystore.js
import { ref } from "vue";

export const mystore = ref({
  myVariable: false,
});

// 独立方法,避免this指向问题
export function setMyVariable(value) {
  mystore.value.myVariable = value;
}

2. 修正组件脚本中的Ref访问

在foo.vue的<script>中,所有访问store属性的地方都要加上.value,这样才能追踪到响应式变化:

<script setup>
import { watchEffect, reactive } from "vue";
import { mystore, setMyVariable } from "../../../stores/mystore.js";

const { data: thedata, refresh } = await useFetch(
  "http://api.test/foo",
  {
    transform(data) {
      return JSON.parse(data);
    },
    pick: ["data"],
  }
);

const headers = reactive([
  { title: "ID", key: "id" },
  { title: "Name", key: "name" }
]);

watchEffect(() => {
  console.log("test");
  console.log(mystore.value.myVariable); // 这里添加.value
  // 触发fetch刷新
  if (mystore.value.myVariable) {
    refresh();
    // 重置变量,避免重复触发
    mystore.value.myVariable = false;
  }
});
</script>

3. 修正触发按钮的调用

如果采用了抽离后的独立方法,index.vue里也要对应修改:

<script setup>
import { setMyVariable } from "../stores/mystore.js";
</script>

<template>
  <v-btn @click="setMyVariable(true)">Refresh</v-btn>
</template>

为什么模板里能正常显示?

Vue3的模板会自动为顶层ref进行解包,所以mystore.myVariable在模板中等价于mystore.value.myVariable,但这个自动解包仅在模板中生效,<script>里必须手动使用.value。

内容的提问来源于stack exchange,提问作者DevonDahon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 04:45:07