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

Vue项目按俱乐部筛选足球运动员功能问题求助

问题描述

需求:在Vue项目中实现按俱乐部筛选足球运动员的功能,选择下拉框中的俱乐部时,仅展示该俱乐部的球员,而非联赛所有球员。
当前存在两个问题:

  1. 选择俱乐部后仍显示全部联赛球员
  2. 切换俱乐部时下拉列表出现阻塞情况

解决方案

一、核心问题分析

当前代码未实现「根据选中俱乐部过滤球员」的逻辑,且未对频繁切换操作做优化,导致阻塞。以下分两种场景给出优化方案:

方案1:本地过滤(适合数据量不大的场景)

通过Vue计算属性在本地过滤球员,无需频繁请求后端,性能更流畅。

修改步骤:

  1. 添加计算属性过滤球员
    在script中新增computed选项,根据selectedKlub过滤球员列表:
computed: {
  filtriraniIgraci() {
    // 未选择俱乐部时返回全部球员
    if (!this.selectedKlub) return this.igraci;
    // 根据球员的俱乐部ID匹配选中值,注意字段名需与后端返回的球员数据一致(如igrac.klubId或igrac.klub._id)
    return this.igraci.filter(igrac => igrac.klubId === this.selectedKlub);
  }
}
  1. 修改模板渲染列表
    将原模板中循环的igraci替换为计算属性filtriraniIgraci:
<div class="grid">
  <div v-for="igrac in filtriraniIgraci" :key="igrac._id" @click="otvoriSliku(igrac)">
    <img :src="igrac.slika" alt="Slika igrača">
    <p>{{ igrac.ime }} {{ igrac.prezime }}</p>
    <h2>{{ igrac.nadimak }}</h2>
  </div>
</div>

方案2:后端过滤(适合数据量极大的场景)

通过监听俱乐部选择事件,动态请求后端带筛选参数的接口,同时添加防抖避免频繁请求导致阻塞。

前端修改:

  1. 修改球员请求方法,支持传俱乐部ID
async dobaviIgrace(klubId = '') {
  try {
    // 根据是否传俱乐部ID拼接请求地址
    const url = klubId ? `http://localhost:3000/igraci?klubId=${klubId}` : 'http://localhost:3000/igraci';
    const response = await axios.get(url);
    this.igraci = response.data;
  } catch(error) {
    console.error('Greška prilikom dobavljanja igrača:', error);
    this.errorMessage = 'Došlo je do greške prilikom dobavljanja igrača sa servera.';
  }
}
  1. 添加防抖+监听俱乐部选择事件
    先实现防抖函数,避免快速切换时多次请求:
methods: {
  // 自定义防抖函数
  debounce(func, delay) {
    let timeoutId;
    return function(...args) {
      clearTimeout(timeoutId);
      timeoutId = setTimeout(() => func.apply(this, args), delay);
    };
  },
  // ...其他方法
},
watch: {
  // 监听选中俱乐部变化,防抖后请求数据
  selectedKlub(newKlubId) {
    this.debouncedDobaviIgrace(newKlubId);
  }
},
created() {
  // 初始化防抖后的请求方法
  this.debouncedDobaviIgrace = this.debounce(this.dobaviIgrace, 300);
}

后端配合修改(以Express为例)

在球员接口中添加根据klubId参数筛选的逻辑:

router.get('/igraci', async (req, res) => {
  const { klubId } = req.query;
  let query = {};
  // 若传了俱乐部ID,添加筛选条件
  if (klubId) query.klubId = klubId;
  
  try {
    const igraci = await Igraci.find(query);
    res.json(igraci);
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
});

完整修改后的前端代码示例

Template部分

<template>
  <div>
    <div class="topnav"></div>
    <div>
      <div class="clubDropdown">
        <label for="klub">Odaberi klub:</label>
        <select v-model="selectedKlub">
          <option value="" disabled>Odaberi klub</option>
          <option v-for="klub in klubovi" :value="klub._id" :key="klub._id">{{ klub.naziv }}</option>
        </select>
      </div>
      <button @click="otvoriDialog">Dodaj igrača</button>
      
      <ModalComponent v-if="dialogOtvoren" @zatvori="zatvoriDialog">
        <AddPlayer @zatvori="zatvoriDialog" />
        <button @click="zatvoriDialog" class="close">X</button>
      </ModalComponent>
    </div>

    <div v-if="errorMessage" class="error-message">{{ errorMessage }}</div>

    <div class="grid">
      <div v-for="igrac in filtriraniIgraci" :key="igrac._id" @click="otvoriSliku(igrac)">
        <img :src="igrac.slika" alt="Slika igrača">
        <p>{{ igrac.ime }} {{ igrac.prezime }}</p>
        <h2>{{ igrac.nadimak }}</h2>
      </div>
    </div>
  </div>
</template>

Script部分

<script>
import axios from 'axios';
import AddPlayer from '../components/AddPlayer.vue';
import ModalComponent from '../components/ModalComponent.vue';

export default {
  name: 'PlayerView',
  components: {
    AddPlayer,
    ModalComponent
  },
  data() {
    return {
      klubovi: [],
      selectedKlub: '',
      igraci: [],
      dialogOtvoren: false,
      errorMessage: ''
    };
  },
  computed: {
    filtriraniIgraci() {
      if (!this.selectedKlub) return this.igraci;
      return this.igraci.filter(igrac => igrac.klubId === this.selectedKlub);
    }
  },
  methods: {
    async dobaviKlubove() {
      try {
        const response = await axios.get('http://localhost:3000/klubovi');
        this.klubovi = response.data;
      } catch (error) {
        console.error('Greška prilikom dobavljanja klubova:', error);
        this.errorMessage = 'Došlo je do greške prilikom dobavljanja klubova sa servera.';
      }
    },
    async dobaviIgrace() {
      try {
        const response = await axios.get('http://localhost:3000/igraci');
        this.igraci = response.data;
      } catch(error) {
        console.error('Greška prilikom dobavljanja igrača:', error);
        this.errorMessage = 'Došlo je do greške prilikom dobavljanja igrača sa servera.';
      }
    },
    otvoriDialog() {
      this.dialogOtvoren = true;
    },
    zatvoriDialog() {
      this.dialogOtvoren = false;
    },
    otvoriSliku(igrac) {
      window.open(igrac.slika, '_blank');
    },
  },
  
  mounted() {
    this.dobaviKlubove();
    this.dobaviIgrace();
  }
};
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 14:12:18