如图一个由elementUI el-table组件生成的一个表格,需要在表格头部,完成情况列增加一个图标,点击后浮动一个轻量级的弹层,选择单选项,点击确定,实现批量设置完成情况的功能。一般来说,这种需求,可以通过el-table的头部插槽+el-popover弹出框来实现。结果遇到了一个难题,不论怎么尝试,渲染出来的弹出框中的单选框点击没有任何选中效果,使用vue插件查看数据,v-model对应的值数据确实发生了改变,并且重新打开页面,弹出框的选项才发生变化。期间尝试过使用input框来绑定数据,不论是放在el-popover组件中,还是直接放在el-popover外面,均无法生效。
最后使用render-header的方式解决了问题。
为了方便使用,将表格头部插槽内容单独抽取组件。
表格部分代码:
<el-table-column prop="paramLevelId" :render-header="renderHeader" :label="qualityCheckEvalLevelName" width="100" align="center"> <template slot-scope="{ row, $index }"> <div class="spread"> <div v-show="controlParam.btnName !=='检查' && controlParam.btnName !=='提交'" :style="{color:getColor(row.paramLevelId)}"> {{ getLevelName(row.paramLevelId) }} </div> <el-tooltip v-model="row.evalParamLevelIdTips" class="item" :disabled="!row.evalParamLevelIdTips" effect="dark" :content="'请选择'+qualityCheckEvalLevelName" placement="top-end"> <el-select v-show="controlParam.btnName ==='检查' || controlParam.btnName ==='提交'" :ref="`evalParamLevelId${row.number}`" v-model="row.paramLevelId" :placeholder="'请选择'+qualityCheckEvalLevelName" @change="changeTextColor($event,`evalParamLevelId${row.number}`)"> <el-option v-for="item in paramLevelList" :key="item.id" :label="item.levelName" :value="item.id" v-html="'<span style=color:'+item.color+'>'+item.levelName+'</span>'" /> </el-select> </el-tooltip> </div> </template> </el-table-column> renderHeader(h, { column, $index }, index) { return ( <ParamLevelRenderHeader qualityCheckEvalLevelName={this.qualityCheckEvalLevelName} levelCheckModeParamValue={this.levelCheckModeParamValue} controlParam={this.controlParam} paramLevelList={this.paramLevelList}/> ) } // 相对定位 需要设置overflow 否则看不到popover弹出框 .checkTableInfo .el-table__header-wrapper{ overflow: visible !important; } .checkTableInfo .el-table th{ overflow: visible !important; } .checkTableInfo .el-table .cell{ overflow: visible !important; }
组件代码:
<template> <div class="d-flex" style="justify-content: center;align-items: center;position: relative"> <span class="flex">{{ qualityCheckEvalLevelName }}</span> <i v-if="(controlParam.btnName ==='检查' || controlParam.btnName ==='提交') && levelCheckModeParamValue === 'allCheck'" class="el-icon-set-up flex" style="font-size: 18px;cursor: pointer" @click.stop="showBatchParamLevel" /> <el-popover v-if="(controlParam.btnName ==='检查' || controlParam.btnName ==='提交') && levelCheckModeParamValue === 'allCheck'" ref="batchParamLevel" class="batchParamLevel" placement="bottom" trigger="click" > <div @click.stop> <div style="text-align: center;" class="font-14">批量设置</div> <div> <div> <el-radio-group v-model="batchSettingParamLevelId" style="padding: 0;margin-top:10px;width: 100%;"> <el-radio v-for="(item,index5) in paramLevelList" :key="index5" style="margin: 5px 0;text-align: center;width: 90%" :label="item.id">{{ item.levelName }}</el-radio> </el-radio-group> </div> </div> <div class="d-flex j-center"> <el-button class="mt-1" type="primary">确定</el-button> <el-button class="mt-1" type="primary">重置</el-button> </div> </div> </el-popover> </div> </template> <script> export default { name: 'ParamLevelRenderHeader', props: { qualityCheckEvalLevelName: { // 分级名称 type: String, default: '' }, levelCheckModeParamValue: { type: String, default: 'questionCheck' }, controlParam: { // 控制参数 type: Object, default: () => ({ btnName: '查看' }) }, paramLevelList: { type: Array, default: () => { return [] } } }, data() { return { batchSettingParamLevelId: '' } }, methods: { /** * 显示批量设置质控评价分级 */ showBatchParamLevel() { if (this.$refs['batchParamLevel']) { this.$refs['batchParamLevel'].doShow() document.addEventListener('click', this.closePopover) } }, closePopover() { if (this.$refs['batchParamLevel']) { this.$refs['batchParamLevel'].doClose() document.removeEventListener('click', this.closePopover) } } } } </script> <style> </style>
代码解析:
1、采用相对定位布局,使得滚动时跟随表格滚动,需要增加额外样式,处理overflow,否则弹出框无法显示。
2、点击图标弹出popover,点击空白处隐藏弹出框,需要在popover中最大的div上加上@click.stop阻止冒泡,否则点击弹出框中的内容也会关闭弹出框。
发表评论