Element-UI Table实现列表筛选数据及列表嵌套选择框

VUE 框架在 Element UI 的基础上,Table 组件中实现了列表数据的修改功能,支持单选和多选功能,并且列表具备筛选功能。样式如图所示。

功能介绍

  • 点击table列名实现筛选查询功能
  • 相关性判断点击列表中的正方形实现选择框功能,同时修改列表数据
  • 其他标记点击列表实现复选框功能,列表样式根据选择数据的数量动态适应宽度。

功能实现

相关性判断类单选功能

  • 表头筛选功能
    在表头位置添加了一个 el-popover 弹出框,里面包含了 el-checkbox-group 用于选择不同的相关性判断选项。通过点击表头旁边的图标来打开弹出框并选择筛选条件。点击"查询"按钮时,将关闭弹出框,并执行查询逻辑。
  • 列表数据修改功能
    每行数据旁边都有一个 el-popover,其中包含可点击的不同相关性判断选项。当点击某个选项时,会更新该行数据的相关性判断,并发送请求到后端进行数据更新。
代码
html 复制代码
<el-table-column width="60" prop="correlationJudgment">
    <!-- 列数据筛选功能 -->
    <template #header>
        <span class="top-header">相关性<br />判断
            <!-- 弹出框,用于显示相关性判断的选择 -->
            <el-popover 
                @show="correlationJudgmentshowPopover('相关性')" 
                @hide="correlationJudgmenthidePopover" 
                ref="correlationJudgmentPopover" 
                placement="bottom" 
                trigger="click" 
                popper-class="top-popover" 
                :popper-options="{ boundariesElement: 'viewport', removeOnDestroy: true }">
                
                <div class="genePopover-title">相关性判断</div>
                <div class="genePopover-box"> 
                    <div style="padding: 5px 15px">
                        <!-- 多选框组,用于选择相关性判断的选项 -->
                        <el-checkbox-group v-model="correlationJudgmentList">
                            <el-checkbox label="高度相关">高度相关</el-checkbox>
                            <el-checkbox label="其他可疑">其他可疑</el-checkbox><br>
                            <el-checkbox label="参考位点">参考位点</el-checkbox>
                            <el-checkbox label="热点突变">热点突变</el-checkbox><br>
                            <el-checkbox label="无">无</el-checkbox>
                        </el-checkbox-group>
                    </div>
                </div>
                <div class="popover-footer">
                    <!-- 取消按钮 -->
                    <div class="geneBtnCancel" @click="correlationJudgmentCancelBtn">
                        取消
                    </div>
                    <!-- 查询按钮 -->
                    <div class="geneBtnQuery" @click="correlationJudgmentQueryBtn">
                        查询
                    </div>
                </div>
                <!-- 弹出框的参考内容 -->
                <div slot="reference" class="determine">
                    <img src="../../../assets/images/筛选.png" class="top-img" alt="" v-if="correlationJudgmentList.length == 0" />
                    <img src="../../../assets/images/red.png" class="top-img1" alt="" v-else />
                </div>
            </el-popover>
        </span>
    </template>
    
    <!-- 列表数据修改显示 -->
    <template slot-scope="scope">
        <div class="determine-box">
            <!-- 每一行数据的弹出框 -->
            <el-popover 
                :ref="`popover-${scope.$index}`" 
                placement="left" 
                trigger="click" 
                :offset="30" 
                :popper-options="{ boundariesElement: 'viewport',removeOnDestroy: true }">
                
                <!-- 相关性判断的选项,每个选项都调用 getdetermine 方法 -->
                <div style="width: 100px;margin: 0;display: flex;justify-content: center;line-height: 2;" @click="getdetermine('高度相关', scope)">
                    高度相关
                </div>
                <div style="width: 100px;margin: 0;display: flex;justify-content: center;line-height: 2;" @click="getdetermine('其他可疑', scope)">
                    其他可疑
                </div>
                <div style="width: 100px;margin: 0;display: flex;justify-content: center;line-height: 2;" @click="getdetermine('参考位点', scope)">
                    参考位点
                </div>
                <div style="width: 100px;margin: 0;display: flex;justify-content: center;line-height: 2;" @click="getdetermine('热点突变', scope)">
                    热点突变
                </div>
                <div style="width: 100px;margin: 0;display: flex;justify-content: center;line-height: 2;" @click="getdetermine('无', scope)">
                    无
                </div>
                <!-- 显示当前行的相关性判断结果 -->
                <div slot="reference" class="determine">
                    {{ scope.row.correlationJudgment }}
                </div>
            </el-popover>
        </div>
    </template>
</el-table-column>
js 复制代码
methods:{
   	//悬浮
    correlationJudgmentshowPopover (row) {
      this.titleContent = row;
    },
    //悬浮隐藏
    correlationJudgmenthidePopover () {

    },
    //悬浮取消
    correlationJudgmentCancelBtn () {
      this.$refs.correlationJudgmentPopover.doClose();
    },
    //悬浮查询
    correlationJudgmentQueryBtn () {
      this.pageSize = 10;
      this.pageNum = 1;
      this.getAllParams();
      this.$refs.correlationJudgmentPopover.doClose();
    },
    //选中数据
    getdetermine (val, row) {
      let oldcorrelationJudgment = row.row.correlationJudgment;
      if (val == "无") {
        row.row.correlationJudgment = "";
      }
      let params = {
        参数...
      };
      updateReport(params).then((res) => {
      	this.getList();
      });
      this.$refs[`popover-${row.$index}`].doClose();
      this.$forceUpdate();
    },
}
注释说明:
  • <el-table-column>: 定义表格的列,指定宽度和绑定的数据属性。
  • <template #header>: 自定义表头,包含一个弹出框用于选择相关性判断。
  • <el-popover>: 弹出框组件,用于显示选项和操作按钮。
  • <el-checkbox-group>: 用于多个复选框的分组,允许用户选择多个选项。
  • @click: 事件处理器,触发相应的方法。
  • slot-scope : 用于访问当前行数据(scope),使得每一行可以独立操作。

其他标记复选功能

  • 表头筛选功能
    类似地,在其他标记列的表头位置也添加了一个 el-popover 弹出框,用于选择不同的其他标记。可以选择多个标记,并通过点击"查询"按钮来执行筛选操作。
  • 列表数据修改功能
    每行数据旁边也有一个 el-popover,其中包含可选择的其他标记选项。可以选择或取消选择某些标记,然后当关闭弹出框时,会更新该行数据的其他标记,并发送请求到后端进行数据更新。
代码
html 复制代码
<el-table-column width="90" prop="multipleRelevances">
    <!-- 自定义表头 -->
    <template #header>
        <span class="top-header">其他<br />标记
            <!-- 弹出框,用于选择其他标记 -->
            <el-popover 
                @show="multipleRelevanceshowPopover('相关性')" 
                @hide="multipleRelevancehidePopover" 
                ref="multipleRelevancePopover" 
                placement="bottom" 
                trigger="click" 
                popper-class="top-popover" 
                :popper-options="{ boundariesElement: 'viewport', removeOnDestroy: true }">
                
                <div class="genePopover-title">其他标记</div>
                <div class="genePopover-box">
                    <div style="padding: 5px 15px">
                        <!-- 多选框组,用于选择其他标记 -->
                        <el-checkbox-group v-model="multipleRelevanceList">
                            <el-checkbox label="自闭基因">自闭基因</el-checkbox>
                            <el-checkbox label="次要发现">次要发现</el-checkbox><br>
                            <el-checkbox label="无">无</el-checkbox>
                        </el-checkbox-group>
                    </div>
                </div>
                <div class="popover-footer">
                    <!-- 取消按钮 -->
                    <div class="geneBtnCancel" @click="multipleRelevanceCancelBtn">
                        取消
                    </div>
                    <!-- 查询按钮 -->
                    <div class="geneBtnQuery" @click="multipleRelevanceQueryBtn">
                        查询
                    </div>
                </div>
                <!-- 弹出框的参考内容 -->
                <div slot="reference" class="determine">
                    <img src="../../../assets/images/筛选.png" class="top-img" alt="" v-if="multipleRelevanceList.length == 0" />
                    <img src="../../../assets/images/red.png" class="top-img1" alt="" v-else />
                </div>
            </el-popover>
        </span>
    </template>

    <!-- 列表数据修改显示 -->
    <template slot-scope="scope">
        <div class="determine-box">
            <el-popover 
                @hide="multipleRelevanceHide(scope)" 
                @show="multipleRelevanceClick(scope)" 
                :ref="`popover-${scope.$index}`" 
                placement="left" 
                trigger="click" 
                :offset="30" 
                :popper-options="{ boundariesElement: 'viewport',removeOnDestroy: true }">
                
                <div style="width: 100px;margin-left: 20px;display: flex;justify-content: center;line-height: 2;">
                    <!-- 多选框组,用于选择其他标记 -->
                    <el-checkbox-group v-model="multipleRelevances" @change="handleMultipleRelevanceChange">
                        <el-checkbox label="自闭基因">自闭基因</el-checkbox>
                        <el-checkbox label="次要发现">次要发现</el-checkbox>
                    </el-checkbox-group>
                </div>
                <!-- 弹出框的参考内容,通过数据量动态显示样式宽度 -->
                <div slot="reference" class="determine" :style="'width: '+(scope.row.multipleRelevances && scope.row.multipleRelevances.length > 1 ? 60 : 30) + 'px;'">
                    <span v-for="relevance in scope.row.multipleRelevances" :key="relevance">
                        {{ relevance }}
                    </span>
                </div>
            </el-popover>
        </div>
    </template>
</el-table-column>
注释说明:
  • <el-table-column>: 定义表格的列,指定宽度和绑定的数据属性。
  • <template #header>: 自定义表头,包含一个弹出框用于选择其他标记。
  • <el-popover>: 弹出框组件,用于显示选项和操作按钮。
  • <el-checkbox-group>: 用于多个复选框的分组,允许用户选择多个选项。
  • @click: 事件处理器,触发相应的方法。
  • slot-scope : 用于访问当前行数据(scope),使得每一行可以独立操作。
js 复制代码
methods:{
   	//悬浮
    multipleRelevanceshowPopover (row) {
      this.titleContent = row;
    },
    //悬浮隐藏
    multipleRelevancehidePopover () {

    },
    //悬浮取消
    multipleRelevanceCancelBtn () {
      this.$refs.multipleRelevancePopover.doClose();
    },
    //悬浮查询
    multipleRelevanceQueryBtn () {
      this.pageSize = 10;
      this.pageNum = 1;
      this.getAllParams();
      this.$refs.multipleRelevancePopover.doClose();
    },
    //选中数据,进行修改
    multipleRelevanceHide (row) {
      let multipleRelevanceStr = JSON.parse(JSON.stringify(this.multipleRelevances));
      this.multipleRelevances = [];
      let multipleRelevance = multipleRelevanceStr.join(',')
      let oldmultipleRelevance = row.row.multipleRelevance;
      let params = {
        参数...
      };
      updateReport(params).then((res) => {
        this.getList(); 
      });
      this.$refs[`popover-${row.$index}`].doClose();
      this.$forceUpdate();
    },
    //点击时获取数据用于复选框数据回显
    multipleRelevanceClick (row) {
      this.multipleRelevances = row.row.multipleRelevances
    },
    //选中的数据
    handleMultipleRelevanceChange (value) {
      this.multipleRelevances = value
    },
}

页面样式

css 复制代码
<style lang="scss">
@import "../../../assets/styles/index.scss";

.el-popover {
  min-width: 100px;
  padding: 0;
  // left: 8px !important;
  font-size: 12px;

  .genePopover-title {
    padding: 0 10px;
    width: 100%;
    background-color: var(--topPopover);
    color: #ffffff;
    height: 30px;
    line-height: 30px;
    border-radius: 4px 4px 0 0;
  }

  .genePopover-box {
    padding: 8px;
    border-bottom: 1px solid #d0d0d0;

    .el-textarea__inner {
      font-size: 13px;
    }

    .title-info {
      padding: 5px 0;
    }
  }

  .genePopover-box {
    max-width: 300px !important;
  }

  .popover-footer {
    display: flex;
    justify-content: flex-end;
    padding: 8px;
    line-height: 1;

    .geneBtnCancel {
      padding: 4px 8px;
      border: 1px solid #d0d0d0;
      border-radius: 3px;
      margin-right: 10px;
    }

    .geneBtnQuery {
      padding: 4px 8px;
      border-radius: 3px;
      background-color: var(--topPopover);
      color: #ffffff;
    }
  }

  .numberOfCasesPopover {
    display: flex;
    align-items: center;
    padding-top: 10px;
    padding-bottom: 20px;

    .el-input--medium .el-input__inner {
      height: 30px;
      line-height: 30px;
    }
  }

  .el-checkbox {
    margin-right: 10px;

    .el-checkbox__label {
      padding-left: 5px;
      font-size: 12px;
    }
  }

  .el-checkbox__input.is-checked .el-checkbox__inner {
    background-color: var(--checkboxColor);
    border-color: var(--checkboxColor);
  }

  .el-checkbox__input.is-checked + .el-checkbox__label {
    color: var(--checkboxColor);
  }

  .el-checkbox__input.is-indeterminate .el-checkbox__inner {
    background-color: var(--checkboxColor);
    border-color: var(--checkboxColor);
  }

  .el-input--medium .el-input__inner {
    height: 30px;
    line-height: 30px;
  }
  .el-input__suffix {
    top: -3px;
  }
  .el-textarea__inner {
    padding-bottom: 15px;
  }

  .el-textarea .el-input__count {
    color: #909399;
    background: #ffffff;
    position: absolute;
    font-size: 12px;
    bottom: 2px;
    right: 20px;
    line-height: 1;
  }
}

.top-popover[x-placement^="bottom"] {
  margin-top: 21px;
  margin-left: 5px;
}

.top-popover[x-placement^="bottom"] .popper__arrow::after {
  border-bottom-color: var(--topPopover) !important;
}

.SNPInDel {
  .el-textarea__inner {
    padding-bottom: 15px;
  }

  .el-table {
    font-size: 12px;
    .el-table__header-wrapper {
      border-radius: 5px 5px 0 0;
    }
    .el-table__header-wrapper,
    .el-table__fixed-header-wrapper {
      th {
        word-break: break-word;
        background-color: #e3e8f1;
        color: #515a6e;
        height: 20px;
        font-size: 12px;
        font-weight: bold;
        padding: 3px 0;
      }
    }

    .el-table__body-wrapper {
      .el-button [class*="el-icon-"] + span {
        margin-left: 1px;
      }
    }

    .el-table--medium .el-table__cell {
      padding: 10px !important;
    }

    .cell {
      padding: 0 !important;
      line-height: 1.1;
      // height: 100%;
      display: flex;
      flex-direction: column;

      p {
        margin: 0 !important;
        height: 100%;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        width: 100%;
      }

      .el-icon-s-open:before {
        content: "";
        color: var(--color);
      }

      .determine-box {
        .determine {
          font-size: 12px;
          display: flex;
          justify-content: center;
          width: 30px;
          // height: 30px;
          min-height: 30px;
          align-items: center;
          color: var(--color);
          background-color: #c4e8ff;
          border: 1px dashed var(--color);
          border-radius: 2px;
          padding: 1px;
          cursor: pointer;
        }
        .determines {
          font-size: 12px;
          display: flex;
          justify-content: center;
          width: 30px;
          // height: 30px;
          min-height: 30px;
          align-items: center;
          color: var(--color);
          background-color: #c4e8ff;
          border: 1px dashed var(--color);
          border-radius: 2px;
          padding: 1px;
          cursor: pointer;
        }
      }
  
    }

    .top-header {
      position: relative;
      height: 40px;
      display: flex;
      align-items: center;

      .top-img {
        position: absolute;
        width: 12px !important;
        bottom: 3px;
        cursor: pointer;
      }
      .top-img1 {
        position: absolute;
        width: 12px !important;
        bottom: 3px;
        cursor: pointer;
      }
    }
  }
}
</style>
相关推荐
崔庆才丨静觅2 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60613 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了3 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅3 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅4 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅4 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment4 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅4 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊4 小时前
jwt介绍
前端
爱敲代码的小鱼5 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax