实现思路:
组件注册
组件的地址存储在表中,在xxx_components表中配置组件url
components_key:组件名称(不可重复)
components_url:组件地址
所填值为正常组件地址去掉 @/前缀 和.vue后缀
is_bill_process: Y (是否专案界面的流程组件(Y是,N否))
动态组件嵌入的位置
<el-tabs v-model="activeName" @tab-click="handleClick">
<!--固定表单-->
<el-tab-pane label="需求申请基本信息" name="100">
</el-tab-pane>
<!--动态表单-->
<el-tab-pane :lazy="true" v-for="(item, index) in tabPanes"
:label="item.title" :name="item.name" :key="item.name">
<listComponent :listComponentData="listComponentInfo"></listComponent>
</el-tab-pane>
</el-tabs>
<script>
import listComponent from "./listComponent.vue";
export default {
name: "purchaseApplyDetail",
components: {listComponent},
data() {
return {
activeName: '',
listComponentInfo: {},
}
},
methods: {
handleClick(tab, event) {
this.listComponentInfo.activeName = this.activeName
},
}
}
</script>
动态的tabPanes
@Override
public Map<String, Object> getBillProcess(Map<String, Object> param) {
Map<String, Object> result = new HashMap<>();
//获取组件注册的数据
List<BillProcessVo> billProcess = taskPurchaseApplyMapper.getBillProcess(param);
//获取可渲染的单据
List<SysProcessComponents> componentsList = sysProcessComponentsMapper.selectIsBillProcessComponentsList();
//依据单据类型放入map中
Map<String, SysProcessComponents> components = componentsList.stream().collect(Collectors.toMap(SysProcessComponents::getBillType, v -> v));
List<Map<String, Object>> tabPanes = new ArrayList<>();
for (BillProcessVo process : billProcess) {
//查询可渲染的单据id不能为空,为空说明没有该单据数据,则不加载该单据菜单
if(Objects.nonNull(process.getId()) && !process.getBillType().equals(BillTypeEnum.PURCHASEAPPLY.code())){
SysProcessComponents component = components.get(process.getBillType());
Map<String, Object> temp = new HashMap<>();
//title对应 el-tab-pane 的 label属性
temp.put("title", process.getDictLabel());
//name对应 el-tab-pane 的 name属性
temp.put("name", process.getBillType());
//component为空,说明xxx_components没有该单据的组件注册信息,则不返回前端
if(Objects.nonNull(component)){
temp.put("componentKey", component.getComponentsKey());
temp.put("componentUrl", component.getComponentsUrl());
List<String> billIds = Arrays.asList(process.getId().split(","));
temp.put("billIds", billIds);
}
tabPanes.add(temp);
}
}
result.put("tabPanes", tabPanes);
return result;
}
动态组件 - listComponent
<template>
<div>
<keep-alive>
<component :is="componentName" :componentData="componentData"></component>
</keep-alive>
<el-alert v-if="componentName==='' || componentName ===undefined " title="未配置专案流程组件,请联系管理员进行配置"
type="warning" center show-icon :closable="false"/>
</div>
</template>
<script>
export default {
name: "listComponent",
components: {},
props: {
listComponentData: {},
},
data() {
return {
componentName: '',
componentData: '',
}
},
created() {
for (let i of this.listComponentData.tabPanes) {
if (this.listComponentData.activeName === i.name) {
this.componentName = i.componentKey
this.componentData = i
}
try {
this.$options.components[i.componentKey] = require(`@/${i.componentUrl}.vue`).default
} catch (e) {
// console.log(`${i.componentKey}组件注册失败,地址为:@/${i.componentUrl}.vue`)
}
}
},
methods: {}
}
</script>
实际嵌入的组件 - invoiceListComponent
<template>
<div style="padding-bottom: 10px">
<vxe-grid class="mytable-scrollbar" ref='xGrid' v-bind="gridOptions" v-if="tableHeight" :height="tableHeight">
<template #billCode_table="scope">
<el-button type="text" @click="showInfo(scope.row)">{{ scope.row.billCode }}</el-button>
</template>
<template #confirmStatus_table="scope">
<dict-tag :options="dict.type.confirm_status" :value="scope.row.confirmStatus"/>
</template>
<template #userType_table="scope">
<dict-tag :options="dict.type.user_type" :value="scope.row.userType"/>
</template>
<template #invoiceClass_table="scope">
<dict-tag :options="dict.type.invoice_class" :value="scope.row.invoiceClass"/>
</template>
<template #isSendGoldenTax_table="scope">
<dict-tag :options="dict.type.sys_yes_no" :value="scope.row.isSendGoldenTax"/>
</template>
<template #syncState_table="scope">
<dict-tag :options="dict.type.sync_state" :value="scope.row.syncState"/>
</template>
<template #operate="scope">
<!-- <el-button type="text" v-hasPermi="['srm:invoice:add']"-->
<!-- @click="editEvent(scope.row)" icon="el-icon-edit">修改-->
<!-- </el-button>-->
<!-- <el-button type="text" v-hasPermi="['srm:invoice:remove']"-->
<!-- @click="removeRowEvent(scope.row)" icon="el-icon-delete">删除-->
<!-- </el-button>-->
</template>
</vxe-grid>
<pagination :limit.sync="pageSize" :page.sync="pageNum" :total="total" @pagination="getList" v-show="total > 0"/>
</div>
</template>
<script>
export default {
name: "invoiceListComponent",
dicts: ['sys_yes_no', 'invoice_class', 'bill_type','confirm_status','sync_state'],
props: {
componentData: {},//接收父组件传递的数据
},
data() {
return {
tableHeight: window.innerHeight - 400, //表格动态高度
screenHeight: window.innerHeight, //内容区域高度
// 总条数
total: 0,
pageNum: 1,
pageSize: 20,
gridOptions: {
id: 'invoice_index', //storage需要
keepSource: true,//编辑状态下的还原需要
border: true,
loading: false,
align: "center",
stripe: true,
printConfig: {},
exportConfig: {},
rowConfig: {
isHover: true//高亮显示
},
formConfig: {
titleWidth: 80,
titleAlign: 'right',
items: [],
data: {},
},
columnConfig: {
resizable: true //是否启用列宽调整
},
customConfig: {
storage: true, //是否启用 localStorage 本地保存
immediate: true,
showFooter: false
},
editConfig: {
trigger: 'dblclick',
enabled: false,
mode: 'row',
showStatus: true //只对 keep-source 开启有效,是否显示单元格新增与修改状态
},
filterConfig: {
remote: true
},
//右击菜单
menuConfig: {
body: {}
},
//列
columns: [],
//较验规则
editRules: {},
data: []
},
}
},
watch: {
// 监听screenHeight从而改变table的高度
screenHeight(val) {
this.screenHeight = val;
this.tableHeight = this.screenHeight - 400;
}
},
created() {
this.gridOptions.menuConfig.body = constant.menuConfig;
this.getColumns();
},
methods: {
getColumns() {
this.gridOptions.loading = true
getInfoByBusiCode("srm_purchase_invoic_list").then(res => {
if (res.code === 200) {
this.gridOptions.columns = JSON.parse(res.data.columns);
for (let i of this.gridOptions.columns) {
if (i.title === '操作') {
i.visible = false
}
if(i.type === 'checkbox'){
i.visible = false
}
}
this.getList();
} else {
this.gridOptions.loading = false;
this.$modal.msgError("获取表数据失败,请重试");
}
});
},
//获取列表数据
getList() {
this.gridOptions.loading = false;
const params = {
pageNum: this.pageNum,
pageSize: this.pageSize,
objMap: {
id: this.componentData.billIds //组件传递的主表id List
}
}
getInvoiceList(params).then(res => {
this.gridOptions.loading = false;
if (res.code === 200) {
this.gridOptions.data = res.rows;
this.total = res.total;
}
})
},
showInfo(row) {
const params = {pageNum: this.pageNum};
this.$tab.openPage("发票详情", '/srm/invoice/invoiceDetail/' + row.id, params);
},
}
}
</script>