vue2 动态组件

news2024/11/27 22:33:01

文章目录

  • 实现思路:
    • 组件注册
    • 动态组件嵌入的位置
    • 动态的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

@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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2062701.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024年最新股指期货交易手续费标准是多少?

股指期货交易手续费是指投资者在进行股指期货买卖时需要支付的费用&#xff0c;主要包括开仓手续费和平仓手续费。这些费用是交易所和期货公司为了维持市场运行和提供服务而收取的。 一、沪深300、上证50、中证500、中证1000股指期货手续费 日内交易&#xff1a;只要你在交易…

计算机中的「null」怎么读?

今天咱们来聊一个让无数程序员纠结的问题&#xff1a;“null”这个词到底该怎么读&#xff1f; 在开始讨论这个问题之前&#xff0c;我觉得有必要先带大家回忆一下我们曾经踩过的那些发音雷区。 尤其是那些英文术语&#xff0c;真的是一个坑接一个。比如这些常见的发音错误&am…

常见DDoS攻击之零日漏洞Zero-day Attacks

目录 一、什么是零日漏洞Zero-day Attacks 二、零日漏洞是如何转化为零日攻击的 三、常见的零日攻击类型 四、为什么零日攻击很危险 五、著名的零日攻击事件 六、如何降低零日攻击的风险 七、DDoS攻击防御解决方案&#xff08;定制化&#xff09; 7.1 产品优势 7.2 产品…

Vue - 详细介绍wow.js滚动触发动画组件(Vue2 Vue3)

Vue - 详细介绍wow.js滚动触发动画组件&#xff08;Vue2 & Vue3&#xff09; 在日常网页中&#xff0c;我们难免会用到CSS动画来对某些元素进行显示隐藏&#xff0c;在wowjs中可根据浏览器滚动来触发对应的CSS动画&#xff0c;并且可设置多种animate动画类型、动画持续时间…

速卖通自养号测评:安全高效提升产品销量的秘诀

速卖通自养号测评是跨境电商卖家为了提升产品销量、评价数量及排名而采取的一种策略。以下是对速卖通自养号测评的详细解析&#xff1a; 一、自养号测评的定义 自养号测评&#xff0c;顾名思义&#xff0c;是指卖家自行培养并管理买家账号&#xff0c;通过模拟真实买家的购物…

重新认识一下,从BIO到NIO,再到AIO,响应式编程

Netty 的高性能架构&#xff0c;是基于一个网络编程设计模式 Reactor 进行设计的。现在&#xff0c;大多数与 I/O 相关的组件&#xff0c;都会使用 Reactor 模型&#xff0c;比如 Tomcat、Redis、Nginx 等&#xff0c;可见 Reactor 应用的广泛性。 Reactor 是 NIO 的基础。为什…

WordPress中最佳免费WooCommerce主题推荐:专家级指南

在电商领域&#xff0c;每个创业者的梦想是拥有一个既功能强大又美观的在线商店。对于已经具备一定建站经验的专家级用户来说&#xff0c;重点是选择一款功能强大且灵活性高的WooCommerce主题。在这篇文章中&#xff0c;我将为大家推荐几款适合专家级用户的免费WooCommerce主题…

javaer选手快速入门grpc

本文前置内容 需要学过java微服务开发,至少知道使用过openfeign和dubbo等rpc微服务组件的相关内容 相信已经学习到微服务开发的对grpc或多或少都有了解,高效的性能和protobuf这样轻量序列化的方式 无论是go开发必学还是java 使用dubbo或者其他深入也是需要了解的 相关概念 Pro…

使用js代码模拟React页面中input文本框输入

遇到的问题&#xff1a; 使用js代码模拟input框中输入指定的字符串&#xff0c;在浏览器调试页面能看到输入框的文字已经变成我需要的文字&#xff0c;但是只要我点击输入框&#xff0c;或者页面上的其他输入框&#xff0c;输入框的文字就清空了。 解决过程和方法&#xff1a; …

火语言RPA流程组件介绍--睡眠等待

&#x1f6a9;【组件功能】&#xff1a;休眠等待指定时间后再恢复执行 阻塞当前流程继续向下运行&#xff0c;暂停等待指定时间&#xff0c;一般当上一组件操作需要缓冲时间或完成太快需要休眠观测时使用此组件。 配置预览 配置说明 延迟时间 支持T或# 输入仅支持整型 阻塞…

[Linux#44][线程] CP模型2.0 | 信号量接口 | 基于环形队列

目录 1.回忆 Task.hpp 1. #pragma once 2. 头文件和命名空间 3. 类 CallTask 4. 操作符字符串 5. 回调函数 mymath 阻塞队列 BlockQueue 的实现 BlockQueue 生产者和消费者线程 生产者productor 消费者 consumer 主函数 main 代码整体说明 2. 信号量 2.1 回忆&…

简化登录流程,助力应用建立用户体系

随着智能手机和移动应用的普及&#xff0c;用户需要在不同的应用中注册和登录账号&#xff0c;传统的账号注册和登录流程需要用户输入用户名和密码&#xff0c;这不仅繁琐而且容易造成用户流失。 华为账号服务&#xff08;Account Kit&#xff09;提供简单、快速、安全的登录功…

Raft分区产生的脏读问题

Raft分区产生的脏读问题 前言网络分区情况1 4和5分到一个分区&#xff0c;即当前leader依然在多数分区情况2 1和2分到一个分区&#xff0c;即当前leader在少数分区 脏读问题的解决官方解答其他论文 参考链接 前言 昨天面试阿里云被问到了这个问题&#xff0c;在此记录一下。 …

终于有人将Transformer可视化了!

都 2024 年&#xff0c;还有人不了解 Transformer 工作原理吗&#xff1f;快来试一试这个交互式工具吧。 2017 年&#xff0c;谷歌在论文《Attention is all you need》中提出了 Transformer&#xff0c;成为了深度学习领域的重大突破。该论文的引用数已经将近 13 万&#xff…

第二证券:股票可以亏损本金吗?股票会不会亏成负?

炒股是存在赔本本金的或许的&#xff0c;当你卖出股票的价格小于买入股票的价格&#xff0c;那就是赔本的。 实践上&#xff0c;还因为不管是买入股票仍是卖出股票都会收取股票生意手续费&#xff0c;所以假设卖出股票价格等于买入股价&#xff0c;或许只上涨了一点点&#xf…

开放式耳机怎么选?南卡、漫步者、Oladance OWS PRO四款耳机无广深度测评!

最近这段时间&#xff0c;我发现很多的小伙伴在我已经怎么选择开放式耳机&#xff0c;哪一款比较推荐的&#xff0c;如今市面上出现了很多不同的开放式耳机品牌&#xff0c;在购买的时候大多数人都没有非常明确的目标&#xff0c;主要就是因为大多数人对开放式耳机的了解程度不…

C#实现数据采集系统-多设备采集

系统功能升级-多设备采集 数据采集系统在网络环境下&#xff0c;性能足够&#xff0c;可以实现1对多采集&#xff0c;需要支持多个设备进行同时采集功能&#xff0c;现在就开发多设备采集功能 修改多设备配置 设备配置 将DeviceLink 改成List集合的DeviceLinks删掉Points&a…

【知识图谱】2.知识抽取与知识存储

目录 一、知识抽取 1、实体命名识别&#xff08;Name Entity Recognition&#xff09; 2、关系抽取&#xff08;Relation Extraction&#xff09; 3、实体统一&#xff08;Entity Resolution&#xff09; 4、指代消解&#xff08;Coreference Resolution&#xff0…

聚水潭ERP集成金蝶云星瀚(聚水潭主供应链)

源系统成集云目标系统 金蝶云星瀚介绍 金蝶云星瀚是专为大企业设计的新一代数字化管理云服务、大型企业SaaS管理云&#xff0c;旨在凭借千亿级高性能和世界一流企业的实践&#xff0c;帮助大企业实现可信的数字化系统升迁&#xff0c;打造韧性企业&#xff0c;支撑商…

【xilinx】Vivado : 解决 I/O 时钟布局器错误:Versal 示例

示例详细信息&#xff1a; 设备&#xff1a; XCVM1802 Versal Prime问题&#xff1a;尽管使用 CCIO 引脚作为时钟端口&#xff0c;但该工具仍返回 I/O 时钟布局器错误 错误&#xff1a; <span style"background-color:#f3f3f3"><span style"color:#…