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

Vue使用Fetch API遇空值读取错误,求替代React useEffect方案

问题:Vue异步获取产品数据后模板不更新,且出现访问null属性错误

我想要从API获取产品数据,问题在于模板不会等待异步函数执行完毕、products属性填充完获取的数据。由于这是异步函数,模板运行时products的值为null,访问products.value会抛出"cannot read properties of null (reading 'value')"错误。我尝试用v-if判断products是否存在后再渲染,但获取数据后products的变更未被捕获,页面无内容显示。在React中我可以通过useEffect API传入依赖数组指定products状态来触发更新,请问Vue中的等价实现方式是什么?

后端路由代码(Laravel)

Route::get('/products',function(){
    $products = DB::table('products')->get()->toArray();
    return response()->json([
        'products' => $products,
    ]);
});

当前Vue组件代码

import { ref, watchEffect } from "vue";

const products = ref(null);

watchEffect(() => {
    fetch("/products")
        .then((response) => response.json())
        .then((data) => (products.value = data));
});

<template>
  <div v-if="products">
   <ul v-for="product in products.value">
    <li class="py-4 px-2">
     <Link href="...">
      <img :src="product.imageUrl"/>
       <p>{{ product.name }}</p>
     </Link>
    </li>
   </ul>
  </div>
</template>
解决方案

1. 用onMounted替代watchEffect(对应React的useEffect(() => {}, []))

Vue中与React空依赖useEffect等价的是onMounted钩子,它只会在组件挂载时执行一次,完全匹配初始化获取数据的场景,无需额外追踪依赖:

import { ref, onMounted } from "vue";

const products = ref(null);

onMounted(() => {
    fetch("/products")
        .then((response) => response.json())
        .then((data) => {
            // 后端返回的是包含products数组的对象,需赋值数组本身
            products.value = data.products;
        });
});

2. 修正模板中的数据访问逻辑

Vue的ref在模板中会自动解包,不需要手动写.value,直接使用变量名即可:

<template>
  <!-- 直接判断products是否存在,ref自动解包 -->
  <div v-if="products">
   <!-- 循环products数组,无需添加.value -->
   <ul v-for="product in products" :key="product.id">
    <li class="py-4 px-2">
     <Link href="...">
      <img :src="product.imageUrl"/>
       <p>{{ product.name }}</p>
     </Link>
    </li>
   </ul>
  </div>
  <!-- 可选:添加加载状态提示 -->
  <div v-else>加载中...</div>
</template>

关键问题说明

  • 之前用watchEffect虽然能运行,但它会追踪依赖并重复执行,而初始化获取数据只需要执行一次,onMounted更语义化且性能更优。
  • 后端返回的data是{products: [...]}结构,之前直接把products.value设为整个data,导致模板中访问的是对象而非数组,这是数据赋值的核心错误。
  • Vue的ref在模板中自动解包,这是和React状态使用的关键区别,不需要像在脚本中那样手动调用.value。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 13:32:18