Vue中如何对v-for循环内的每个asin自动发起API请求获取商品数据
实现方案
问题核心
原代码存在两个核心问题:
- 全局共用一个
product变量,所有循环项的商品数据会互相覆盖,无法做到每个项展示自身对应商品 - 商品请求仅在点击按钮时触发,没有和博客内容拉取逻辑联动自动执行
具体修改思路
- 调整数据存储结构:把全局
product改为以asin为键、对应商品数据为值的映射对象,每个asin的商品数据独立存储不会互相覆盖 - 自动触发请求:拿到博客内容后直接遍历
content数组,对每个项的asin自动发起商品接口请求 - 模板适配:循环渲染时每个项直接根据自身asin从映射对象中取对应商品展示即可
修改后完整代码
HTML 部分
<div v-for="content in blogPost.content" :key="content.id"> {{ content.asin }} <!-- 仅展示当前项asin对应的商品,可自定义加载/错误状态展示 --> {{ productMap[content.asin] || '商品加载中...' }} <div v-html="content.content"></div> </div>
JS 部分
export default { data() { return { blogPost: [], // 用映射对象存储asin和对应商品的关系 productMap: {} } }, async fetch() { try { const blogPost = await this.$axios.$get( `/api/get-post/${this.$route.params.id}` ) this.blogPost = blogPost // 拉取到博客内容后自动遍历请求所有关联商品 this.blogPost.content.forEach(item => { // 已请求过的asin跳过,避免重复请求 if (item.asin && !this.productMap[item.asin]) { this.getProduct(item.asin) } }) } catch (err) { console.log(err) } }, methods: { async getProduct(asin) { try { const product = await this.$axios.$get('/api/get-product-from-asin', { params: { asin }, }) // 响应式存入映射对象 this.$set(this.productMap, asin, product) } catch (err) { console.log(err) // 可自定义错误状态存储,方便前端展示 this.$set(this.productMap, asin, '商品加载失败') } }, }, }
优化提示
如果单篇博客关联的商品数量较多,可以加并发请求限制,避免短时间内发起大量请求触发接口限流。如果有后端修改权限,也可以直接在博客内容接口里提前拼接好关联商品数据,前端直接渲染即可,减少额外接口请求开销。
内容的提问来源于stack exchange,提问作者Philippe
相关产品推荐
相关产品推荐

