Vue中传入对象类型prop时get_data函数出现无限循环问题
Vue组件无限循环问题的原因与修复
问题根源
- 模板里直接写
{{ get_data() }}会导致组件每一次渲染都会执行这个方法。 get_data()内部修改了响应式数据this.temp,数据变化会触发组件重新渲染。- 渲染→调用方法→修改数据→再渲染,形成无限循环。
- 对象prop时问题更明显的原因:对象是引用类型,父组件哪怕传递新的对象引用(属性未变),都会触发组件重渲染;字符串是值类型,只有值真正改变时才触发渲染,所以字符串prop时循环没立刻显现,但隐患一直存在。
- 移除
{{ this.temp }}后,模板不再依赖temp,修改temp不会触发渲染,循环自然停止,但这只是掩盖问题,并非根本解决。
修复方案
核心是把数据请求的触发逻辑从模板移到生命周期钩子或watch中,打破渲染与方法调用的循环依赖:
- 用
watch监听city变化,每次city更新时发起请求; - 组件挂载时,若
city已有值,发起初始化请求; - 修正
temp的初始值(不要用Object构造函数,设为null或空对象即可); - 用
async/await优化异步请求写法,替代嵌套then,提升可读性。
修正后的代码
<script setup> import { watch, onMounted } from 'vue' const props = defineProps({ city: String }) </script> <template> <div v-if="city != null"> {{ temp }} </div> </template> <script> export default { data() { return { temp: null // 修正初始值,避免使用Object构造函数 } }, methods: { async get_data() { try { const response = await fetch(`https://api.openweathermap.org/data/2.5/weather?q=${this.city}&appid=&units=metric`) const obj = await response.json() console.log(obj) this.temp = obj } catch (err) { console.error('天气数据请求失败:', err) } } }, mounted() { // 组件挂载时若city存在,执行初始化请求 this.city && this.get_data() }, watch: { // 监听city变化,重新请求数据 city(newCity) { newCity && this.get_data() } } } </script>
额外注意事项
- 模板中禁止调用会修改响应式数据的方法,这是Vue开发的常见禁忌;
- 异步请求必须加错误处理,防止请求失败引发页面异常;
- 代码中
appid参数为空,实际使用时需填入OpenWeatherMap的有效API密钥。
内容的提问来源于stack exchange,提问作者stackoverflowuser
相关产品推荐
相关产品推荐

