vue2 动态组件


在这里插入图片描述
在这里插入图片描述

实现思路:

组件注册

组件的地址存储在表中,在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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值