Bootstrap

路由传参、搜索、多选框勾选、新增/编辑表单复用

前言:

记录添加运动员页面功能的具体实现

①由赛事管理页面跳转时路由传参(携带该页面表格中莫某条数据对应的赛事id到另一个页面);

②搜索框实时搜索;

③多选框勾选搜索;

④新增表单和编辑表单复用;

⑤导出文件:根据赛事id和搜索条件导出表格中的数据;

1. 在该页,点击编辑跳转页面,并携带赛事id(路由传参)

goAddAthlete(row){
      this.$router.push({
        path:'/eventManage/athlete/add',
        query:{eventId:row.id}
      })
    },

跳转到该页

在data中放一个容器eventId,将路由传参传过来的赛事id(eventId)存放起来,

页面跳转过来直接调用根据赛事id获取运动员列表数据的方法,所以写在created,

在methods中定义getAthleteByEventId,拿到数据

data() {
  return{
    eventId:null,//赛事id
  }
},
created() {
  // 初始化 eventId
  this.eventId = this.$route.query.eventId;
  if (this.eventId) {
    this.getAthleteByEventId();
  }else{
    this.$message.error('未传递赛事id');
  }
},
methods: {
  // 根据赛事id获取运动员列表数据
  getAthleteByEventId() {
    // 调用获取运动员列表的接口,传入赛事id
    getAthleteList({eventId: this.eventId}).then((res) => {
      this.athleteList = res.records
      this.total = res.total
      this.filteredAthleteList = this.athleteList; // 初始化筛选列表(复制一份数据用于筛选操作)
    })
  },
}

2. 搜索框查询的功能

用于根据用户在搜索框中输入的关键字过滤运动员列表,并将过滤后的结果显示在 filteredAthleteList 中。

两种写法

方法1:当后端不接收一个search参数时,在前端进行筛选

使用 filter 方法遍历 athleteList

方法2:后端接收一个search参数来实现模糊查询

直接在getAthleteByEventId方法中调用接口时传入search参数

<!-- 搜索框 -->
<el-input
  v-model="searchKey"
  placeholder="请输入姓名、拼音或注册号搜索"
  prefix-icon="el-icon-search"
  clearable
  class="search-input"
  @input="filterAthleteList"
  >
</el-input>
data() {
    return {
      searchKey:''
    }
}
方法1
// 查询对应运动员数据
filterAthleteList(){
  const searchKey = this.searchKey.trim().toLowerCase();
  if (!searchKey) {
    // 如果搜索框为空,恢复全部数据
    this.filteredAthleteList = this.athleteList;
    return;
  }
  // 过滤 athleteList 中的数据
  this.filteredAthleteList = this.athleteList.filter((athlete) => {
    return (
      athlete.name?.toLowerCase().includes(searchKey) || // 匹配姓名
      athlete.pinyin?.toLowerCase().includes(searchKey) || // 匹配拼音
      athlete.registeredNumber?.toLowerCase().includes(searchKey) // 匹配注册号
    );
  });

},
方法2
getAthleteByEventId() {
      // 调用获取运动员列表的接口,传入赛事id
      getAthleteList({
        eventId: this.eventId,
        search:this.searchKey.trim()
      }).then((res) => {
        this.athleteList = res.records
        this.total = res.total
        this.filteredAthleteList = this.athleteList; // 初始化筛选列表(复制一份数据用于筛选操作)
      })
    },

filterAthleteList(){
    this.getAthleteByEventId()
},

3. 筛选注册类型功能

// 根据选中类型筛选
filterByTypes() {
  if (this.selectedTypes.length === 0) {
    // 如果没有选择任何类型,显示全部数据
    this.filteredAthleteList = this.athleteList;
    return;
  }

  // 筛选出符合选中类型的数据
  this.filteredAthleteList = this.athleteList.filter((athlete) =>
    this.selectedTypes.includes(athlete.registrationType)
  );
},

4. 新增/编辑对话框复用

新增与编辑的对话框复用

<el-dialog
  :visible.sync="isDialogVisible"
  :title="isEditing ? '编辑运动员信息' : '添加运动员信息'"
  width="50%"
  >
  <!-- 表单内容 -->
</el-dialog>
// 默认为新增(isEdit=false,row为空对象{},执行else分支)
// 打开新增或编辑对话框
openDialog(isEdit = false, row = {}) {
      this.isEditing = isEdit; // 设置对话框状态
      this.isDialogVisible = true;
      if (isEdit) {
        // 编辑模式:填充表单数据
        this.form = { ...row };
      } else {
        // // 新增模式:清空表单
        // this.$nextTick(() => {
        //   this.$refs.formRef.resetFields();
        // });
        this.form = {
          id: null,
          name: "",
          pinyin: "",
          gender: "",
          nation: "",
          team: "",
          cardType: "",
          idCardNumber: "",
          registrationType: "",
          registeredProject: "",
          registeredNumber: "",
        };
  
      }
},

onSubmit() {
      this.$refs.formRef.validate((valid) => {
        if (valid) {
          if (this.isEditing) {
            // 编辑模式
            updateAthleteById(this.form).then(() => {
              this.$message.success('修改运动员成功');
              this.isDialogVisible = false; // 关闭对话框
              this.getAthleteByEventId(); // 重新获取列表
            }).catch(() => {
              this.$message.error('修改运动员失败');
            });            
          }else{
            // 新增模式
            const newAthlete = { ...this.form, eventId:this.eventId }; // 拼接数据
            addAthleteByEventId(newAthlete).then(() => {
              this.$message.success('添加运动员成功');
              this.isDialogVisible = false; // 关闭对话框
              this.getAthleteByEventId(); // 重新获取列表
            }).catch(() => {
              this.$message.error('添加运动员失败');
            });
          }
          
        }
      });
    },
// 编辑模式下,表单中会填充对应数据;新增模式下,表单清空

isDialogOpen: false, // 控制对话框开关
isEditing: false, // 区分新增和编辑

// 打开对话框(编辑模式)
  openDialog(row) {
    this.isEditing = true; // 切换为编辑模式
    this.isDialogOpen = true; // 打开对话框
    this.form = { ...row }; // 将选中的数据复制到表单中
  },

// 提交表单(新增或编辑)
  onSubmit() {
    this.$refs.form.validate((valid) => {
      if (valid) {
        if (this.isEditing) {
          // 编辑操作
          updateAthleteById(this.form)
            .then(() => {
              this.$message.success("运动员信息更新成功");
              this.isDialogOpen = false; // 关闭对话框
              this.getAthleteList(); // 重新加载列表
            })
            .catch((err) => {
              this.$message.error("运动员信息更新失败");
            });
        } else {
          // 新增操作
          const newAthlete = {
            ...this.form,
            eventId: this.eventId, // 新增时需附加 eventId
          };
          addAthleteByEventId(newAthlete)
            .then(() => {
              this.$message.success("添加运动员成功");
              this.isDialogOpen = false; // 关闭对话框
              this.getAthleteList(); // 重新加载列表
            })
            .catch((err) => {
              this.$message.error("添加运动员失败");
            });
        }
      }
    });
  },

  // 关闭对话框时重置表单
  handleDialogClose() {
    this.$refs.form.resetFields();
    this.isEditing = false; // 重置为新增模式
    this.form.id = null; // 清空 id
  },
},

5. 导出功能

// 导出
handleExport(){
  // 方法1.将条件构建导出请求的参数
  const exportParams = {
    eventId: this.eventId,
    search: this.searchKey.trim(),          
    registrationType: this.selectedTypes.join(','), // 将注册类型转换为后端可识别的格式
  };


  // 调用导出接口
  exportAthleteByEventId(exportParams)
    .then((response) => {
      this.$download.excel(response.data, '已添加的运动员信息.xlsx');
    });
}
;