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

Vue3中onMounted调用接口正常 watch调用后reactive值不更新问题

问题原因分析
  • watch回调未声明async,内部使用await属于语法错误,代码执行到此处直接抛出异常,打断后续赋值逻辑,即使接口请求正常发出,也无法完成数据更新。
  • 对reactive封装的响应式数组直接重新赋值会丢失响应式:reactive绑定的是引用类型的原始引用,直接执行products = xxx替换整个引用后,原来的响应式关联会断开,页面无法监听到数据变化。
  • splice方法返回值误用:Array.splice()的返回值是被删除的元素组成的数组,你执行splice(0, 0, ...result.data)时删除元素数量为0,返回值是空数组,直接赋值给products后自然没有有效数据。
修复方案

1. 数据服务层修改

推荐优先选择方案B,ref封装数组的使用逻辑更简单,不易出现响应式丢失问题:

方案A:保留reactive写法,修改更新逻辑

import axios from "axios";
import { reactive } from "vue";

export default function () {
    const products = reactive([]);
    async function searchProduct(param) {
        console.log(`dans la fonction avec param ${param}`)
        const url = "http://localhost:5000/product/?search="+param;
        const result = await axios.get(url);
        // 直接修改原数组内容,不替换整个引用
        products.length = 0;
        products.push(...result.data);
        console.log(products)
        return products
    }
    
    return { products, searchProduct };
}

方案B:改用ref封装数组

import axios from "axios";
import { ref } from "vue";

export default function () {
    const products = ref([]);
    async function searchProduct(param) {
        console.log(`dans la fonction avec param ${param}`)
        const url = "http://localhost:5000/product/?search="+param;
        const result = await axios.get(url);
        // ref包裹的引用类型直接修改value属性即可保持响应式
        products.value = result.data;
        console.log(products.value)
        return products.value
    }
    
    return { products, searchProduct };
}

2. 组件层修改

给watch的回调函数添加async关键字,修复await语法错误:

watch(searchQuery, async (searchQuery) => {
    await searchProduct(searchQuery)
})

可选优化建议

可以给searchProduct调用加防抖逻辑,避免用户连续输入时触发大量无效接口请求,也能规避接口响应顺序错乱导致的数据显示错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 11:45:01