【无标题】基于 Element UI Select 组件封装的字典选择器 el-select

数据字典下拉框组件

注: JSelect组件是一个基于 Element UI Select 组件封装的字典选择器。通过传入数据字典名称,自动从本地存储或远程获取数据字典选项列表,实现快速选择字典数据的功能。

使用方法

在 Vue 项目中引入 JSelect 组件 并在components声明

import JSelect from "@/components/JSelect.vue";

components: {
   
   
  JSelect
}

也可以在全局注册 找到main.js文件

import JSelect from "@/components/JSelect/JSelect.vue";

Vue.component('JSelect', JSelect);

基本使用

<JSelect
  v-model="selected"
  name="dictionary_name"
  filterable
  clearable
  placeholder="请选择"
/>
  • v-model:用于双向绑定已选中的值
  • name:数据字典的名称,必填项
  • filterable:是否支持过滤选项,默认为 true
  • clearable:是否支持清空已选项,默认为 true
  • placeholder:输入框默认占位文本
  • 需要注意的是,组件的 value 属性和 v-model 属性不要同时使用

::: tip 温馨提示

  • JSelect 组件需要传入数据字典的名称作为 name 属性,因此在使用组件前需要确认该数据字典是否存在。
  • JSelect 组件在获取数据字典时,首先会尝试从本地缓存获取,如果不存在则会调用远程接口获取。因此需要确保数据字典已经被加载到本地缓存中。
  • JSelect 组件内部使用了 Element UI 的 Select 组件,因此支持 Select 组件的所有 Props、Slots 和 Events。如果需要对 Select
    组件进行更深层次的修改,可以在 JSelect 组件内部通过 v-bind=“attrs"和v−on="attrs" 和 v-on="attrs"von="listeners” 将原生的 Props 和 Events 传递到
    Select 组件中。
    :::

完整组件内容

<template>
  <el-select
    v-model="selected"
    v-bind="$attrs"
    v-on="$listeners"
  
<template> <div class="bim-card-emer-plan-management"> <el-card :body-style="bodyStyle10"> <el-container> <el-header height="45px"> <el-row :gutter="24" style="width: 100%; margin-bottom: 0;"> <el-col :span="3" :offset="11" > <el-cascader v-model="selectBridge" :options="bridgeOptions" placeholder="请选择桥梁" :props="cascaderProps" @change="handleBridgeChange" clearable ></el-cascader> </el-col> <el-col :span="2.5" :offset="0" > <el-select v-model="selectAccident" placeholder="请选择预案类型" @change="handleChange" > <el-option v-for="item in emergencyEventTypeOptions" :key="item.value" :label="item.label" :value="item.value"></el-option> </el-select> </el-col> <el-col :span="3" :offset="0" > <el-input style="width:100%" placeholder="请输入预案名称/描述" v-model="Accidentinput" clearable ></el-input> </el-col> <el-col :span="1.5" :offset="0" > <el-button type="primary" icon="el-icon-search"> 搜索 </el-button> </el-col> <el-col :span="1" :offset="0"> <el-button type="success" icon="el-icon-circle-plus" @click="createNewid" > 新建 </el-button> </el-col> </el-row></el-header> <el-main class="layout-container"> <el-table :data="tableData" style="width: 100%" height="100%" :cell-style="{ textAlign: 'center' }" :header-cell-style="{ textAlign: 'center' }" class="full-height-table"> <el-table-column prop="ceshibridgeName" label="桥梁名称" width="150"></el-table-column> <el-table-column :prop="ceshiNumber" label="桥梁编号" width="200"></el-table-column> <el-table-column :prop="ceshidanwei" label="测试单位" width="250"></el-table-column> <el-table-column :prop="emergencyName" label="应急预案名称" width="250"></el-table-column> <el-table-column :prop="emergencyType" label="应急预案类型" width="300"></el-table-column> <el-table-column :prop="emergencyDescription" label="应急预案说明" width="300"></el-table-column> <el-table-column :prop="emergencyNote" label="应急预案备注" width="300"></el-table-column> <el-table-column fixed="right" :data="ceshioperation" label="操作" width="360"> <template :slot-scope="scpoe"> <el-button type="primary" icon="el-icon-edit" size="mini" @click="handleEdit(scope.row)"> </el-button> <el-button type="success" icon="el-icon-view" size="mini" @click="handleView(scope.view)"> </el-button> <el-button type="danger" icon="el-icon-delete" size="mini" @click="handleDelete(scope.row)"> </el-button> </template> </el-table-column> </el-table> </el-main> <el-footer height="60px"> <el-pagination ></el-pagination> </el-footer> </el-container> </el-card> </div> </template> <script> // 混入 import autoHeight from "@/mixin/autoHeight"; import { mapCfg, dateTimeFormat } from "@/utils"; import ElementUI from "element-ui"; import request from '@/utils/request' // 提示信息 import { CONFIRM, TIP } from "@/optionsCfg/Message.js"; import { DIALOG_CLOSED_TYPE as Dialog } from "@/optionsCfg/Constants"; import { getBridgeListV2 } from "../../api/bridgeSelection"; export default { name: "emergencyPlanManagementTable", data() { return { selectAccident: '', emergencyEventTypeOptions: [], selectBridge: [], bridgeOptions: [], cascaderProps: { value: 'id', label: 'name', children: 'children', checkStrictly: true, emitPath: false }, tableData: [], // 实际数据 allBridges: [], bodyStyle10: { padding: '10px' }, Accidentinput: '', ceshiNumber: 'bridgeCode', ceshidanwei: 'maintainCompany', emergencyName: 'planName', emergencyType: 'planType', emergencyDescription: 'description', emergencyNote: 'remark', ceshioperation: 'operation' }; }, async created() { await this.loadBridges(); await this.getEmergencyEventTypeOptins(); await this.fetchEmergencyPlans(); }, filters: { }, watch: { }, mixins: [autoHeight], mounted() { this.$nextTick((_) => { this.alarmTableHeight = document.querySelector(".bim-card-emer-plan-management").offsetHeight - document.querySelector(".header-height-emer-plan-management").offsetHeight - 52 - 10; }); this.loadBridges(); }, methods: { async getEmergencyEventTypeOptins(){ try{ //返回的是数组 const dictList = await mapCfg("EmergencyEventType")(); console.log('预期类型字典数据',dictList); this.emergencyEventTypeOptions = dictList.map(item =>({ value:item.key, label:item.value })); console.log('转换后的预案类型选项',this.emergencyEventTypeOptions); }catch(error){ console.error('获取失败',error); } }, async loadBridges() { try { console.log('开始加载桥梁数据...'); const res = await getBridgeListV2({ isApproved: true }); console.log('API响应:', res); if (res?.data) { const options = []; Object.entries(res.data).forEach(([companyName, bridgeList], index) => { console.log(`处理单位[${index}]:`, companyName); const companyNode = { id: `company_${index}_${companyName}`, name: companyName, children: [] }; bridgeList.forEach((bridge, bIndex) => { console.log(` 添加桥梁[${bIndex}]:`, bridge.bridgeName); companyNode.children.push({ id: bridge.id, name: bridge.bridgeName || '未命名桥梁', bridgeData: bridge }); }); options.push(companyNode); }); this.bridgeOptions = options; console.log('最终选项:', this.bridgeOptions); } } catch (error) { console.error('加载失败:', error); } }, handleBridgeChange(bridgeId) { this.selectedBridgeId = bridgeId; this.fetchEmergencyPlans(); // 根据桥梁ID获取应急预案 }, handleChange(value) { console.log('预案类型选择:', value); this.fetchEmergencyPlans(); }, createNewid() { console.log('新建预案'); // 这里添加新建逻辑 }, handleBridgeChange(value) { console.log('桥梁选择:', value); this.fetchEmergencyPlans(); }, async fetchEmergencyPlans() { try { // 这里添加获取应急预案数据的逻辑 const params = { bridgeId: this.selectBridge, planType: this.selectAccident }; const res = await request.get('/api/emergency-plans', { params }); this.tableData = res.data; this.ceshiData = this.tableData; // 同步到表格数据 } catch (error) { console.error('获取应急预案失败:', error); } }, // 其他操作方法 handleEdit(row) { console.log('编辑:', row); }, handleView(row) { console.log('查看:', row); }, handleDelete(row) { console.log('删除:', row); }, }, async created() { await this.loadBridges(); await this.getEmergencyEventTypeOptins(); await this.fetchEmergencyPlans(); // 初始化加载数据 } }; </script> <style scoped> .layout-container{ height: 70vh; } .full-height-table{ flex:1; min-height: 0; } .el-header { border-bottom: 1px solid #dad8d8; /* 下边框 */ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); /* 阴影增强效果 */ } .el-main{ margin-top: 5px; padding: 0; overflow: hidden; flex-direction: column; } .el-row { margin-bottom: 20px; &:last-child{ margin-bottom: 0; } } .el-col { border-radius: 4px; } .p20 { padding: 20px; } .p10 { padding: 10px; } .mb10 { margin-bottom: 10px; } .line1 { border-bottom: 1px solid #ebeef5; } h2.title { font-size: 16px; padding-left: 20px; padding-right: 20px; } </style>需要凑后端列表数据接口: api/emergency-plan-maint-controller文件 getEmergencyPlanPageList 传入参 pageSize: , // 请求数量/页 pageNo: , // 页码 bridgeCode: "", // 桥梁编码 planType: "", // 应急预案类型 searchKey: "", // 测点编号/测点名称/测点位置 我要怎么给我的这个代码传参
07-22
<template> <div class="bim-card-emer-plan-management"> <!-- 封装的对话框组件:用于新建、编辑和查看应急预案 --> <emergency-plan-dialog :dialog-visible="dialogVisible" :dialog-mode="dialogMode" :emergency-event-type-options="emergencyEventTypeOptions" :current-form="currentForm" @update:dialogVisible="val => (dialogVisible = val)" @update:currentForm="val => (currentForm = val)" @dialog-closed="handleDialogClosed" @submit="handleSubmit" :bridge-unit-map="bridgeUnitMap" :bridge-options="bridgeOptions" /> <!-- 主内容卡片 --> <el-card> <div class="box"> <!-- 头部搜索区域 --> <div class="box__header"> <el-row :gutter="10" type="flex" justify="end"> <!-- 桥梁选择器 --> <el-col :span="5" :offset="8"> <bridge-cascader v-model="selectBridge" :bridge-options="bridgeOptions" @change="handleSearchBridgeChange" :current-bridge-code="storageKey" :show-all-levels="false" /> </el-col> <!-- 预案类型选择器 --> <el-col :span="5"> <el-select v-model="selectAccident" placeholder="请选择预案类型" clearable size="medium" @clear="handleSearch" class="emergencyTypeClass"> <el-option v-for="item in emergencyEventTypeOptions" :key="item.value" :label="item.label" :value="item.value" filterable /> </el-select> </el-col> <!-- 搜索输入框 --> <el-col :span="6"> <el-input placeholder="请输入预案名称/描述" v-model="emergencyName" clearable size="medium" @clear="handleSearch" /> </el-col> <!-- 搜索按钮 --> <el-col :span="1.5"> <el-button type="primary" icon="el-icon-search" @click="handleSearch" size="medium"> 搜索 </el-button> </el-col> <!-- 新建按钮 --> <el-col :span="1.5"> <el-button type="success" icon="el-icon-circle-plus" @click="openCreateDialog" size="medium"> 新建 </el-button> </el-col> </el-row> </div> <!-- 主体表格区域 --> <div class="box__content"> <el-table :data="tableData" style="width: 100%; " :cell-style="{ textAlign: 'center' }" :header-cell-style="{ textAlign: 'center' }" class="full-height-table"> <el-table-column prop="bridgeName" label="桥梁名称" width="150"></el-table-column> <el-table-column prop="bridgeCode" label="桥梁编号" width="200"></el-table-column> <el-table-column prop="emergencyPlanUnit" label="运营单位" width="250"></el-table-column> <el-table-column prop="emergencyPlanName" label="应急预案名称" width="250"></el-table-column> <el-table-column prop="emergencyPlanType" label="应急预案类型" width="300"></el-table-column> <el-table-column prop="emergencyPlanDesc" label="应急预案说明" width="300"></el-table-column> <el-table-column prop="emergencyPlanRemark" label="应急预案备注" width="300"></el-table-column> <!-- 操作列 --> <el-table-column fixed="right" label="操作" width="300"> <template slot-scope="scope"> <el-button-group> <!-- 修改按钮 --> <el-button type="primary" icon="el-icon-edit" size="mini" @click="handleEdit(scope.row)"> 修改 </el-button> <!-- 查看按钮 --> <el-button type="success" icon="el-icon-view" size="mini" @click="handleView(scope.row)"> 查看 </el-button> <!-- 删除按钮 --> <el-button type="danger" icon="el-icon-delete" size="mini" @click="handleDelete(scope.row)"> 删除 </el-button> </el-button-group> </template> </el-table-column> </el-table> </div> <!-- 分页区域 --> <div class="box__footer"> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="pagination.pageNo" :page-sizes="[15, 20, 25, 50]" :page-size="pagination.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total" /> </div> </div> </el-card> </div> </template> <script> // 引入自动高度混入 import autoHeight from "@/mixin/autoHeight"; // 引入字典配置工具 import { mapCfg } from "@/utils"; // 引入应急预案管理API import { getEmergencyPlanPageList, addEmergencyPlan, deleteEmergencyPlan, getEmergencyPlanInfo, updateEmergencyPlan } from "@/api/emergency-plan-maint-controller.js"; // 引入桥梁级联选择器组件 import BridgeCascader from "./BridgeCascader.vue"; // 引入应急预案对话框组件 import EmergencyPlanDialog from "./EmergencyPlanDialog.vue"; export default { name: "emergencyPlanManagementTable", // 使用自动高度混入 mixins: [autoHeight], components: { BridgeCascader, EmergencyPlanDialog }, data() { return { // 默认选中的桥梁编码 storageKey: "G76431026R0310", // 当前选中的桥梁 selectBridge: "", // 桥梁与单位的映射关系 bridgeUnitMap: {}, // 桥梁选项数据 bridgeOptions: [], // 对话框是否可见 dialogVisible: false, // 对话框模式:create(创建)/edit(编辑)/view(查看) dialogMode: "create", // 数据总数 total: 0, // 分页参数 pagination: { pageSize: 15, pageNo: 1 }, // 搜索条件表单 filterForm: {}, // 选中的预案类型 selectAccident: "", // 搜索关键字(预案名称/描述) emergencyName: "", // 表格数据 tableData: [], // 预案类型选项 emergencyEventTypeOptions: [], // 当前表单数据 currentForm: { bridgeCode: "", emergencyPlanName: "", emergencyPlanType: "", emergencyContacts: "", emergencyTel: "", emergencyPlanDesc: "", emergencyPlanRemark: "", emergencyPlanUnit: "", fileList: [], createDate: "", creator: "", isDelete: 0, isLast: 1 } }; }, // 组件创建时的生命周期钩子 async created() { // 获取预案类型选项 await this.getEmergencyEventTypeOptins(); // 加载第一页数据 await this.loadListData(); }, methods: { /** * 处理桥梁选择变化 * @param {Object} payload - 选择的桥梁数据 */ handleSearchBridgeChange(payload) { const bridgeCode = payload ? payload.bridgeCode : ""; this.selectBridge = bridgeCode; // 触发搜索 this.handleSearch(); }, /** * 处理搜索操作 */ handleSearch() { // 设置搜索条件 this.filterForm = { bridgeCode: this.selectBridge, planType: this.selectAccident, searchKey: this.emergencyName }; // 重置到第一页 this.pagination.pageNo = 1; // 重新加载数据 this.loadListData(); }, /** * 处理每页条数变化 * @param {number} val - 新的每页条数 */ handleSizeChange(val) { this.pagination.pageSize = val; this.pagination.pageNo = 1; this.loadListData(); }, /** * 处理当前页码变化 * @param {number} val - 新的页码 */ handleCurrentChange(val) { this.pagination.pageNo = val; this.loadListData(); }, /** * 获取预案类型选项 */ async getEmergencyEventTypeOptins() { try { // 从字典配置中获取预案类型 const dictList = await mapCfg("EmergencyEventType")(); // 转换为组件需要的格式 this.emergencyEventTypeOptions = dictList.map(item => ({ value: item.key, label: item.value })); } catch (error) { console.error("获取失败", error); } }, /** * 加载表格数据 */ async loadListData() { try { // 设置请求参数 const params = { pageSize: this.pagination.pageSize, pageNo: this.pagination.pageNo, bridgeCode: this.selectBridge, planType: this.filterForm.planType, searchKey: this.filterForm.searchKey }; // 调用API获取数据 const res = await getEmergencyPlanPageList(params); // 处理数据:将预案类型值转换为标签 this.tableData = res.entities.map(item => { const typeOption = this.emergencyEventTypeOptions.find( opt => opt.value === item.emergencyPlanType ); return { ...item, emergencyPlanType: typeOption ? typeOption.label : item.emergencyPlanType }; }); // 设置数据总数 this.total = res.entityCount; } catch (error) { console.error("获取数据失败:", error); this.$message.error("获取数据失败"); } }, /** * 打开创建对话框 */ openCreateDialog() { this.dialogMode = "create"; this.dialogVisible = true; const now = new Date(); // 初始化表单数据 this.currentForm = { bridgeCode: "", emergencyPlanName: "", emergencyPlanType: "", emergencyContacts: "", emergencyTel: "", emergencyPlanDesc: "", emergencyPlanRemark: "", emergencyPlanUnit: "", fileList: [], // 设置创建日期 createDate: now.toISOString(), // 设置创建人 creator: this.$store.state.user.userInfo?.username || "系统用户", isDelete: 0, isLast: 1 }; }, /** * 处理对话框关闭事件 */ handleDialogClosed() { // 重置表单数据 this.currentForm = { bridgeCode: "", emergencyPlanName: "", emergencyPlanType: "", emergencyContacts: "", emergencyTel: "", emergencyPlanDesc: "", emergencyPlanRemark: "", emergencyPlanUnit: "", fileList: [] }; }, /** * 处理表单提交 * @param {Object} formData - 提交的表单数据 */ handleSubmit(formData) { this.submitForm(formData); }, /** * 提交表单数据 * @param {Object} formData - 表单数据 */ async submitForm(formData) { try { // 移除不需要的字段 const { emergencyPlanUnit, ...params } = formData; if (this.dialogMode === "create") { // 创建操作 await addEmergencyPlan(params); this.$message.success("创建成功"); } else if (this.dialogMode === "edit") { // 编辑操作 params.id = this.currentForm.id; await updateEmergencyPlan(params); this.$message.success("修改成功"); } // 关闭对话框 this.dialogVisible = false; // 重置到第一页并刷新数据 this.pagination.pageNo = 1; this.loadListData(); } catch (error) { console.error("操作失败:", error); this.$message.error(this.dialogMode === "create" ? "创建失败" : "修改失败"); } }, /** * 处理删除操作 * @param {Object} row - 要删除的行数据 */ handleDelete(row) { // 确认对话框 this.$confirm("确认删除这条应急预案吗?", "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning" }) .then(() => { // 调用删除API deleteEmergencyPlan({ emergencyPlanId: row.id }) .then(res => { if (res) { this.$message.success("删除成功"); // 刷新数据 this.loadListData(); this.pagination.pageNo = 1; } else { this.$message.error("删除失败"); } }) .catch(error => { this.$message.error("删除请求失败"); console.error(error); }); }) .catch(action => { if (action === "cancel") { this.$message.info("已取消删除"); } }); }, /** * 处理编辑操作 * @param {Object} row - 要编辑的行数据 */ handleEdit(row) { this.dialogMode = "edit"; this.handleList(row); }, /** * 处理查看操作 * @param {Object} row - 要查看的行数据 */ handleView(row) { this.dialogMode = "view"; this.handleList(row); }, /** * 加载应急预案详情 * @param {Object} row - 行数据 */ // 在handleList方法中,添加桥梁名称到currentForm async handleList(row) { try { const id = row.id; const res = await getEmergencyPlanInfo({ emergencyPlanId: id }); // 添加桥梁名称到表单数据 const bridgeOption = this.bridgeOptions.flatMap(company => company.children).find(b => b.value === res.bridgeCode); this.dialogVisible = true; this.currentForm = { ...res, bridgeName: bridgeOption ? bridgeOption.bridgeName : "", // 添加桥梁名称 fileList: res.fileList || [], // ...其他字段 }; } catch (error) { console.error("获取详情失败:", error); this.$message.error("获取详情失败"); } } } }; </script> <style scoped> /* 主容器样式 */ .bim-card-emer-plan-management { height: 100%; display: flex; flex-direction: column; } /* 卡片样式 */ .el-card { height: 100%; display: flex; flex-direction: column; } /* 卡片体样式 */ .el-card ::v-deep .el-card__body { flex: 1; display: flex; flex-direction: column; padding: 0; height: 100%; } /* 内部容器布局 */ .box { display: flex; flex-direction: column; height: 100%; padding: 0 15px 15px 15px; } /* 头部区域样式 */ .box__header { flex-shrink: 0; /* 防止压缩 */ padding: 10px 0; margin-bottom: 0; } /* 内容区域样式 */ .box__content { flex: 1; /* 占据剩余空间 */ display: flex; flex-direction: column; min-height: 300px; /* 最小高度 */ height: 0; /* 允许内容区域伸缩 */ } /* 底部区域样式 */ .box__footer { flex-shrink: 0; /* 防止压缩 */ padding: 15px 0 5px; display: flex; justify-content: left; /* 左对齐 */ } /* 全高表格样式 */ .full-height-table { flex: 1; height: auto !important; display: flex; flex-direction: column; } /* 行间距 */ .el-row { margin-bottom: 15px; &:last-child { margin-bottom: 0; } } /* 预案类型选择器样式 */ .emergencyTypeClass { width: 100%; /* 宽度100% */ } /* 表格内部样式调整 */ .full-height-table ::v-deep .el-table { height: 100% !important; } /* 表格体包装器样式 */ .full-height-table ::v-deep .el-table__body-wrapper { height: calc(100% - 40px) !important; /* 减去表头高度 */ overflow-y: auto !important; /* 允许垂直滚动 */ flex: 1; } </style> 修复table内操作列不能随表格垂直滚动的问题 不要移除fixed="right" 发我修改好的完整代码
08-14
<template> <div class="bim-card-emer-plan-management"> <!-- 封装的对话框组件:用于新建、编辑和查看应急预案 --> <emergency-plan-dialog :dialog-visible="dialogVisible" :dialog-mode="dialogMode" :emergency-event-type-options="emergencyEventTypeOptions" :current-form="currentForm" @update:dialogVisible="val => (dialogVisible = val)" @update:currentForm="val => (currentForm = val)" @dialog-closed="handleDialogClosed" @submit="handleSubmit" :bridge-unit-map="bridgeUnitMap" :bridge-options="bridgeOptions" /> <!-- 主内容卡片 --> <el-card> <div class="box"> <!-- 头部搜索区域 --> <div class="box__header"> <el-row :gutter="10" type="flex" justify="end"> <!-- 桥梁选择器 --> <el-col :span="5" :offset="8"> <bridge-cascader v-model="selectBridge" :bridge-options="bridgeOptions" @change="handleSearchBridgeChange" :current-bridge-code="storageKey" :show-all-levels="false" /> </el-col> <!-- 预案类型选择器 --> <el-col :span="5"> <el-select v-model="selectAccident" placeholder="请选择预案类型" clearable size="medium" @clear="handleSearch" class="emergencyTypeClass"> <el-option v-for="item in emergencyEventTypeOptions" :key="item.value" :label="item.label" :value="item.value" filterable /> </el-select> </el-col> <!-- 搜索输入框 --> <el-col :span="6"> <el-input placeholder="请输入预案名称/描述" v-model="emergencyName" clearable size="medium" @clear="handleSearch" /> </el-col> <!-- 搜索按钮 --> <el-col :span="1.5"> <el-button type="primary" icon="el-icon-search" @click="handleSearch" size="medium"> 搜索 </el-button> </el-col> <!-- 新建按钮 --> <el-col :span="1.5"> <el-button type="success" icon="el-icon-circle-plus" @click="openCreateDialog" size="medium"> 新建 </el-button> </el-col> </el-row> </div> <!-- 主体表格区域 --> <div class="box__content"> <el-table :data="tableData" style="width: 100%; " :cell-style="{ textAlign: 'center' }" :header-cell-style="{ textAlign: 'center' }" class="full-height-table"> <el-table-column prop="bridgeName" label="桥梁名称" width="150"></el-table-column> <el-table-column prop="bridgeCode" label="桥梁编号" width="200"></el-table-column> <el-table-column prop="emergencyPlanUnit" label="运营单位" width="250"></el-table-column> <el-table-column prop="emergencyPlanName" label="应急预案名称" width="250"></el-table-column> <el-table-column prop="emergencyPlanType" label="应急预案类型" width="300"></el-table-column> <el-table-column prop="emergencyPlanDesc" label="应急预案说明" width="300"></el-table-column> <el-table-column prop="emergencyPlanRemark" label="应急预案备注" width="300"></el-table-column> <!-- 操作列 --> <el-table-column fixed="right" label="操作" width="300"> <template slot-scope="scope"> <el-button-group> <!-- 修改按钮 --> <el-button type="primary" icon="el-icon-edit" size="mini" @click="handleEdit(scope.row)"> 修改 </el-button> <!-- 查看按钮 --> <el-button type="success" icon="el-icon-view" size="mini" @click="handleView(scope.row)"> 查看 </el-button> <!-- 删除按钮 --> <el-button type="danger" icon="el-icon-delete" size="mini" @click="handleDelete(scope.row)"> 删除 </el-button> </el-button-group> </template> </el-table-column> </el-table> </div> <!-- 分页区域 --> <div class="box__footer"> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="pagination.pageNo" :page-sizes="[15, 20, 25, 50]" :page-size="pagination.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total" /> </div> </div> </el-card> </div> </template> <script> // 引入自动高度混入 import autoHeight from "@/mixin/autoHeight"; // 引入字典配置工具 import { mapCfg } from "@/utils"; // 引入应急预案管理API import { getEmergencyPlanPageList, addEmergencyPlan, deleteEmergencyPlan, getEmergencyPlanInfo, updateEmergencyPlan } from "@/api/emergency-plan-maint-controller.js"; // 引入桥梁级联选择器组件 import BridgeCascader from "./BridgeCascader.vue"; // 引入应急预案对话框组件 import EmergencyPlanDialog from "./EmergencyPlanDialog.vue"; export default { name: "emergencyPlanManagementTable", // 使用自动高度混入 mixins: [autoHeight], components: { BridgeCascader, EmergencyPlanDialog }, data() { return { // 默认选中的桥梁编码 storageKey: "G76431026R0310", // 当前选中的桥梁 selectBridge: "", // 桥梁与单位的映射关系 bridgeUnitMap: {}, // 桥梁选项数据 bridgeOptions: [], // 对话框是否可见 dialogVisible: false, // 对话框模式:create(创建)/edit(编辑)/view(查看) dialogMode: "create", // 数据总数 total: 0, // 分页参数 pagination: { pageSize: 15, pageNo: 1 }, // 搜索条件表单 filterForm: {}, // 选中的预案类型 selectAccident: "", // 搜索关键字(预案名称/描述) emergencyName: "", // 表格数据 tableData: [], // 预案类型选项 emergencyEventTypeOptions: [], // 当前表单数据 currentForm: { bridgeCode: "", emergencyPlanName: "", emergencyPlanType: "", emergencyContacts: "", emergencyTel: "", emergencyPlanDesc: "", emergencyPlanRemark: "", emergencyPlanUnit: "", fileList: [], createDate: "", creator: "", isDelete: 0, isLast: 1 } }; }, // 组件创建时的生命周期钩子 async created() { // 获取预案类型选项 await this.getEmergencyEventTypeOptins(); // 加载第一页数据 await this.loadListData(); }, methods: { /** * 处理桥梁选择变化 * @param {Object} payload - 选择的桥梁数据 */ handleSearchBridgeChange(payload) { const bridgeCode = payload ? payload.bridgeCode : ""; this.selectBridge = bridgeCode; // 触发搜索 this.handleSearch(); }, /** * 处理搜索操作 */ handleSearch() { // 设置搜索条件 this.filterForm = { bridgeCode: this.selectBridge, planType: this.selectAccident, searchKey: this.emergencyName }; // 重置到第一页 this.pagination.pageNo = 1; // 重新加载数据 this.loadListData(); }, /** * 处理每页条数变化 * @param {number} val - 新的每页条数 */ handleSizeChange(val) { this.pagination.pageSize = val; this.pagination.pageNo = 1; this.loadListData(); }, /** * 处理当前页码变化 * @param {number} val - 新的页码 */ handleCurrentChange(val) { this.pagination.pageNo = val; this.loadListData(); }, /** * 获取预案类型选项 */ async getEmergencyEventTypeOptins() { try { // 从字典配置中获取预案类型 const dictList = await mapCfg("EmergencyEventType")(); // 转换为组件需要的格式 this.emergencyEventTypeOptions = dictList.map(item => ({ value: item.key, label: item.value })); } catch (error) { console.error("获取失败", error); } }, /** * 加载表格数据 */ async loadListData() { try { // 设置请求参数 const params = { pageSize: this.pagination.pageSize, pageNo: this.pagination.pageNo, bridgeCode: this.selectBridge, planType: this.filterForm.planType, searchKey: this.filterForm.searchKey }; // 调用API获取数据 const res = await getEmergencyPlanPageList(params); // 处理数据:将预案类型值转换为标签 this.tableData = res.entities.map(item => { const typeOption = this.emergencyEventTypeOptions.find( opt => opt.value === item.emergencyPlanType ); return { ...item, emergencyPlanType: typeOption ? typeOption.label : item.emergencyPlanType }; }); // 设置数据总数 this.total = res.entityCount; } catch (error) { console.error("获取数据失败:", error); this.$message.error("获取数据失败"); } }, /** * 打开创建对话框 */ openCreateDialog() { this.dialogMode = "create"; this.dialogVisible = true; const now = new Date(); // 初始化表单数据 this.currentForm = { bridgeCode: "", emergencyPlanName: "", emergencyPlanType: "", emergencyContacts: "", emergencyTel: "", emergencyPlanDesc: "", emergencyPlanRemark: "", emergencyPlanUnit: "", fileList: [], // 设置创建日期 createDate: now.toISOString(), // 设置创建人 creator: this.$store.state.user.userInfo?.username || "系统用户", isDelete: 0, isLast: 1 }; }, /** * 处理对话框关闭事件 */ handleDialogClosed() { // 重置表单数据 this.currentForm = { bridgeCode: "", emergencyPlanName: "", emergencyPlanType: "", emergencyContacts: "", emergencyTel: "", emergencyPlanDesc: "", emergencyPlanRemark: "", emergencyPlanUnit: "", fileList: [] }; }, /** * 处理表单提交 * @param {Object} formData - 提交的表单数据 */ handleSubmit(formData) { this.submitForm(formData); }, /** * 提交表单数据 * @param {Object} formData - 表单数据 */ async submitForm(formData) { try { // 移除不需要的字段 const { emergencyPlanUnit, ...params } = formData; if (this.dialogMode === "create") { // 创建操作 await addEmergencyPlan(params); this.$message.success("创建成功"); } else if (this.dialogMode === "edit") { // 编辑操作 params.id = this.currentForm.id; await updateEmergencyPlan(params); this.$message.success("修改成功"); } // 关闭对话框 this.dialogVisible = false; // 重置到第一页并刷新数据 this.pagination.pageNo = 1; this.loadListData(); } catch (error) { console.error("操作失败:", error); this.$message.error(this.dialogMode === "create" ? "创建失败" : "修改失败"); } }, /** * 处理删除操作 * @param {Object} row - 要删除的行数据 */ handleDelete(row) { // 确认对话框 this.$confirm("确认删除这条应急预案吗?", "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning" }) .then(() => { // 调用删除API deleteEmergencyPlan({ emergencyPlanId: row.id }) .then(res => { if (res) { this.$message.success("删除成功"); // 刷新数据 this.loadListData(); this.pagination.pageNo = 1; } else { this.$message.error("删除失败"); } }) .catch(error => { this.$message.error("删除请求失败"); console.error(error); }); }) .catch(action => { if (action === "cancel") { this.$message.info("已取消删除"); } }); }, /** * 处理编辑操作 * @param {Object} row - 要编辑的行数据 */ handleEdit(row) { this.dialogMode = "edit"; this.handleList(row); }, /** * 处理查看操作 * @param {Object} row - 要查看的行数据 */ handleView(row) { this.dialogMode = "view"; this.handleList(row); }, /** * 加载应急预案详情 * @param {Object} row - 行数据 */ // 在handleList方法中,添加桥梁名称到currentForm async handleList(row) { try { const id = row.id; const res = await getEmergencyPlanInfo({ emergencyPlanId: id }); // 添加桥梁名称到表单数据 const bridgeOption = this.bridgeOptions.flatMap(company => company.children).find(b => b.value === res.bridgeCode); this.dialogVisible = true; this.currentForm = { ...res, bridgeName: bridgeOption ? bridgeOption.bridgeName : "", // 添加桥梁名称 fileList: res.fileList || [], // ...其他字段 }; } catch (error) { console.error("获取详情失败:", error); this.$message.error("获取详情失败"); } } } }; </script> <style scoped> /* 主容器样式 */ .bim-card-emer-plan-management { height: 100%; display: flex; flex-direction: column; } /* 卡片样式 */ .el-card { height: 100%; display: flex; flex-direction: column; } /* 卡片体样式 */ .el-card ::v-deep .el-card__body { flex: 1; display: flex; flex-direction: column; padding: 0; height: 100%; } /* 内部容器布局 */ .box { display: flex; flex-direction: column; height: 100%; padding: 0 15px 15px 15px; } /* 头部区域样式 */ .box__header { flex-shrink: 0; padding: 10px 0; margin-bottom: 0; } /* 内容区域样式 - 关键修改 */ .box__content { flex: 1; display: flex; flex-direction: column; min-height: 300px; /* 移除高度限制 */ height: auto; /* 确保内容区域正确扩展 */ overflow: hidden; } /* 底部区域样式 */ .box__footer { flex-shrink: 0; padding: 15px 0 5px; display: flex; justify-content: left; } /* 全高表格样式 - 关键修改 */ .full-height-table { flex: 1; display: flex; flex-direction: column; height: 100%; } /* 行间距 */ .el-row { margin-bottom: 15px; &:last-child { margin-bottom: 0; } } /* 预案类型选择器样式 */ .emergencyTypeClass { width: 100%; } /* 表格内部样式调整 - 关键修改 */ .full-height-table ::v-deep .el-table { flex: 1; display: flex; flex-direction: column; height: 100% !important; } /* 表格头包装器 */ .full-height-table ::v-deep .el-table__header-wrapper { flex-shrink: 0; } /* 表格体包装器样式 - 关键修改 */ .full-height-table ::v-deep .el-table__body-wrapper { flex: 1; overflow-y: auto !important; } /* 固定列包装器 - 关键修改 */ .full-height-table ::v-deep .el-table__fixed-right { height: 100% !important; } </style> 修复操作列无法随表格垂直滚动 界面要求保持flex布局 和固定fixed="right" 给我修改一下我的.vue代码 不要html格式 不要模拟内容模拟数据
最新发布
08-14
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值