You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue:修复v-for生成元素点击后数据全局显示的问题

解决Vue组件点击后全局更新数据的问题

嘿,这个问题我之前开发Vue项目时也碰到过!核心原因很简单:你现在用了一个全局的strainData变量,所有的strain-description组件都绑定了同一个数据源,所以不管点击哪个图标,所有组件都会跟着更新数据。咱们来一步步修复这个问题:

核心思路

给每个单独的strain条目存储它自己的详情数据,而不是用一个全局变量共享所有数据。我们可以把strainData改成一个对象,用strain的id作为键,这样每个id对应一组专属的详情数据。

修改步骤

1. 调整Strain.vue的data定义

把原来的strainData保留为对象,用来存每个strain的详情:

data(){
  return{
    strains: [],
    apiKey: 'removed-for-stack-overflow',
    strainData: {}, // 用id作为键,存储对应strain的详情
  }
},

2. 更新getDetails方法,把数据存到对应id下

修改请求成功后的赋值逻辑,把获取到的数据绑定到当前点击的strain的id上:

getDetails: function(id){
  const descApi = fetch(`https://strainapi.evanbusse.com/${this.apiKey}/strains/data/desc/${id}`);
  const effectApi = fetch(`https://strainapi.evanbusse.com/${this.apiKey}/strains/data/effects/${id}`);
  const flavourApi = fetch(`https://strainapi.evanbusse.com/${this.apiKey}/strains/data/flavors/${id}`);
  axios.all([descApi, effectApi, flavourApi])
    .then((values)=> axios.all(values.map(value => value.json())))
    .then((data) => {
      this.strainData[id] = data; // 把数据存到对应id的键下,实现数据隔离
    });
}

3. 修改模板,给每个组件传递对应的数据

在strain-description组件上,只传递当前strain对应的详情数据,并且添加v-if判断,确保有数据时才渲染(避免空数据报错):

<div id="strain-container" v-for="(strain, index) in strains" :key="index" >
  <h3>{{ strain.name }}</h3>
  <p>{{ strain.race }}</p>
  <i class="fas fa-info-circle" @click="getDetails(strain.id)"></i>
  <!-- 只渲染当前strain有详情数据的组件,并且传递对应的数据 -->
  <strain-description v-if="strainData[strain.id]" :strainData="strainData[strain.id]"></strain-description>
</div>

4. 优化strainDescription.vue,避免空数据报错

给模板里的表达式加上可选链操作符?.,防止数据还没加载时出现报错:

<template>
  <div id="strain-description">
    <p>{{ strainData?.[0]?.desc }}</p>
    <p>{{ strainData?.[1] }}</p>
    <p>{{ strainData?.[2] }}</p>
  </div>
</template>

可选优化方案:把详情数据存在strains数组里

如果你觉得用对象存储不够直观,也可以把每个strain的详情直接存在strains数组的对应元素里:

  1. 点击时传入index:
<i class="fas fa-info-circle" @click="getDetails(strain.id, index)"></i>
  1. 修改getDetails方法:
getDetails: function(id, index){
  // ... 之前的请求代码
  .then((data) => {
    // 用$set确保响应式更新
    this.$set(this.strains, index, {...this.strains[index], details: data});
  });
}
  1. 模板里直接使用strain的details:
<strain-description v-if="strain.details" :strainData="strain.details"></strain-description>

这样修改后,每个strain条目只会显示自己被点击后获取到的详情数据,不会再全局更新啦!

内容的提问来源于stack exchange,提问作者notmynamelastname

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 13:52:53