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
相关产品推荐
相关产品推荐

