vue2 动态组件
文章目录
- 实现思路:
- 组件注册
- 动态组件嵌入的位置
- 动态的tabPanes
- 动态组件 - listComponent
- 实际嵌入的组件 - invoiceListComponent
实现思路:
组件注册
组件的地址存储在表中,在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
@Overridepublic 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.componentKeythis.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 = truegetInfoByBusiCode("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>
