Vue3中基于RestCountries API构建边境国家可点击按钮的数据获取异常问题
解决RestCountries API边境国家数据获取的异步顺序问题
你遇到的核心问题是异步操作的执行顺序错误——axios.get(this.urlDetail)是异步请求,你在调用它之后立刻去读取this.details.borders,这时候this.details还保持着初始的空数组状态(因为then回调还没执行),自然拿不到边境代码,导致后续边境请求的URL构建失败。刷新页面偶尔能成功只是浏览器缓存让请求更快完成的偶然情况,并非根本解决办法。
核心解决方案:确保详情数据加载完成后再请求边境数据
你需要把获取边境国家的逻辑嵌套在详情请求的then回调里,保证只有拿到国家详情后,再去构建边境请求URL并发起请求。修改后的mounted钩子代码如下:
mounted() { axios .get(this.urlDetail) .then(response => { this.details = response.data[0]; // 仅当details成功赋值后,再处理边境数据请求 this.borders = this.details.borders.join(";"); this.urlBorders = "https://restcountries.eu/rest/v2/alpha?codes=" + this.borders; return fetch(this.urlBorders); }) .then(res => res.json()) .then(data => { this.bordersData = data; this.isFetching = false; // 结束加载状态 }) .catch(error => { console.error('数据请求失败:', error); this.isFetching = false; }) }
更直观的写法:使用async/await
如果觉得Promise链式调用不够清晰,也可以用async/await语法让逻辑更接近同步代码:
async mounted() { try { // 先获取国家详情 const detailResponse = await axios.get(this.urlDetail); this.details = detailResponse.data[0]; // 构建边境请求URL并获取数据 this.borders = this.details.borders.join(";"); this.urlBorders = "https://restcountries.eu/rest/v2/alpha?codes=" + this.borders; const borderResponse = await fetch(this.urlBorders); this.bordersData = await borderResponse.json(); } catch (error) { console.error('请求出错:', error); } finally { this.isFetching = false; } }
额外优化建议
处理无边境的情况:有些国家(比如岛国)没有边境,此时
this.details.borders是空数组,直接join会生成空字符串导致请求错误,建议加判断:if (this.details.borders.length > 0) { this.borders = this.details.borders.join(";"); // 发起边境请求 } else { this.bordersData = []; // 或在页面显示"无边境国家"提示 }优化路由参数的使用:你当前在
data中直接拼接this.$route.params.countryName生成urlDetail,如果路由参数变化(比如从其他页面跳转),urlDetail不会自动更新。建议改成计算属性:computed: { urlDetail() { return `https://restcountries.eu/rest/v2/name/${this.$route.params.countryName}`; } }合理利用加载状态:用
isFetching在页面显示加载动画,避免用户看到未渲染的空白按钮。
内容的提问来源于stack exchange,提问作者Goldsucher
相关产品推荐
相关产品推荐

