Vue3中调用ref数组push方法出现无限重复添加值的问题
问题原因与解决方案
为什么会无限重复添加数据?
你在Vue模板的v-for循环里直接调用了getTank方法,而这个方法内部会修改arrayOfFunctions这个响应式ref。Vue的响应式机制会在每次组件渲染时执行模板里的表达式,当arrayOfFunctions被修改后,会触发组件重新渲染,重新渲染又会再次调用getTank,如此往复形成无限循环,导致同一个数据被反复添加到数组里。
正确的解决方式
绝对不要在模板表达式中调用会修改响应式数据的方法,应该把数据请求逻辑放到生命周期钩子或者watch中,提前处理好数据:
方案1:在组件挂载时批量获取数据
<template> <tr class="border-b border-slate-200" v-for="(item, index) in farray" :key="item.id"> <td>{{ item.tankInfo }}</td> </tr> </template> <script setup> import { ref, onMounted } from 'vue' import axios from 'axios' // 假设farray是你已有的数据源 const farray = ref([]) const arrayOfFunctions = ref([]) onMounted(async () => { // 遍历farray,逐个请求tank数据 for (const item of farray.value) { try { const res = await axios.get(`/gettank/${item.tankno}`) // 将数据直接绑定到对应的item上,方便模板渲染 item.tankInfo = res.data // 如果需要维护arrayOfFunctions,先判断是否已存在避免重复 const isExist = arrayOfFunctions.value.some(data => data.id === res.data.id) if (!isExist) { arrayOfFunctions.value.push(res.data) } } catch (err) { console.error(err) } } }) </script>
方案2:监听farray变化,自动更新数据
如果farray是动态变化的(比如后续会新增数据),可以用watch监听它的变化,自动触发数据请求:
<script setup> import { ref, watch } from 'vue' import axios from 'axios' const farray = ref([]) const arrayOfFunctions = ref([]) // 监听farray的变化,immediate: true表示组件挂载时立即执行一次 watch(farray, async (newList) => { // 先清空数组避免重复 arrayOfFunctions.value = [] for (const item of newList) { try { const res = await axios.get(`/gettank/${item.tankno}`) arrayOfFunctions.value.push(res.data) } catch (err) { console.error(err) } } }, { immediate: true }) </script>
关键注意点
模板里的表达式只能是纯函数——也就是不会修改任何响应式数据、相同输入永远返回相同输出的函数。只要违反这个规则,大概率会触发无限渲染循环。
内容的提问来源于stack exchange,提问作者Muhammad Muazzam
相关产品推荐
相关产品推荐

