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

Vue3组件传递多v-model props获取足球API数据问题排查

核心问题:Prop传递错误导致数据未正确接收

1. 父组件状态定义错误

你把selectedLeague和selectedTeam定义成了props,但这两个是父组件自身维护的状态,应该放在data中:

// Teams.vue 中data修改为:
data() {
  return {
    headerShow: false,
    leagues: [],
    teams: [],
    selectedLeague: null, // 移到data里
    selectedTeam: null    // 移到data里
  }
}
// 删除原props中的selectedLeague和selectedTeam

2. 子组件Prop定义错误

子组件把需要的两个prop嵌套在了data属性里,应该直接定义独立的prop:

// TeamStatistics.vue 中props修改为:
props: {
  selectedLeague: {
    type: String,
    required: true
  },
  selectedTeam: {
    type: String,
    required: true
  }
}

3. 父组件传递Prop的方式错误

不需要用v-model(v-model用于双向绑定,需子组件触发update事件),直接用普通prop传递即可,且模板中无需加this.:

<!-- Teams.vue 中TeamStatistics组件修改为: -->
<TeamStatistics
    v-if="selectedTeam"
    :key="selectedTeam.teamId"
    :selected-league="selectedLeague.id"
    :selected-team="selectedTeam.teamId"
/>

数据请求逻辑优化

1. 子组件监听Prop变化,动态更新数据

当前子组件仅在mounted时请求一次数据,当父组件的选中项变化时,需重新获取统计数据,添加watch并抽离请求方法:

// TeamStatistics.vue 中添加watch和方法:
watch: {
  selectedTeam: {
    immediate: true,
    handler() {
      this.fetchTeamStatistics()
    }
  },
  selectedLeague: {
    immediate: true,
    handler() {
      this.fetchTeamStatistics()
    }
  }
},
methods: {
  fetchTeamStatistics() {
    this.teamStatistics = []
    const optionsTeams = {
      method: 'GET',
      url: 'https://api-football-v1.p.rapidapi.com/v3/teams/statistics',
      params: { league: this.selectedLeague, season: '2022', team: this.selectedTeam },
      headers: {
        'X-RapidAPI-Key': 'XXXXXXXXXXXXXX',
        'X-RapidAPI-Host': 'api-football-v1.p.rapidapi.com'
      }
    };

    axios.request(optionsTeams).then(response => {
      const stats = response.data.response
      this.teamStatistics.push({
        name: stats.team.name,
        photo: stats.team.logo,
        form: stats.form,
        played: stats.fixtures.played.total,
        wins: stats.fixtures.wins.total,
        draws: stats.fixtures.draws.total,
        loses: stats.fixtures.loses.total,
        goalsFor: stats.goals.for.total.total,
        goalsAgainst: stats.goals.against.total.total,
        biggestWinStreak: stats.biggest.streak.wins,
        biggestWins: stats.biggest.wins,
      })
      // 空值处理需放在异步回调内,确保数据已存在
      this.teamStatistics.forEach(o => {
        Object.keys(o).forEach(k => {
          if (o[k] === null) {
            o[k] = 'No info'
          }
        })
      })
    }).catch(error => {
      console.error(error)
    })
  }
},
mounted() {
  // 用ref替代原生DOM操作,符合Vue规范
  this.$refs.popup.style.visibility = 'hidden';
  setTimeout(() => {
    this.$refs.popup.style.visibility = 'visible';
  }, 600);
}

模板中添加ref:

<!-- TeamStatistics.vue 模板修改: -->
<div class="popup" ref="popup">

2. 父组件异步请求逻辑修正

父组件中console.log(this.leagues)会在axios请求完成前执行,导致打印空数组,需移到回调内:

// Teams.vue mounted中的axios请求修改:
axios.request(options).then(response => {
  for (let i = 0; i < response.data.response.length; i++) {
    this.leagues.push({
      name: response.data.response[i].league.name,
      id: response.data.response[i].league.id.toString(),
      displayLeague: `${response.data.response[i].league.name + ', ' + response.data.response[i].country.name}`
    })
  }
  console.log(this.leagues) // 移到这里
}).catch(function (error) {
  console.error(error);
});

其他代码优化建议

  1. 模板中移除this.:Vue模板可直接访问组件实例属性,比如{{ teamStatistics[0].name }}即可。
  2. 空值安全渲染:用可选链操作符避免数组为空时报错,比如{{ teamStatistics[0]?.name || 'No info' }}(需Vue 2.6+或Vue 3支持)。
  3. 数组清空方式:父组件中this.teams.length = 0可替换为this.teams = [],更直观。
  4. 方法逻辑修正:父组件dropdownShouldOpen方法中的this.league应为this.selectedLeague,否则逻辑不生效。
  5. 组件name规范:组件name无需加.vue,比如name: "Teams"即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 20:40:24