form-create和form-create-designer创建自定义组件

news2024/12/28 2:30:04

    在项目中,我需要使用表单设计器form-create-designer设计带有选择用户的弹窗组件,而设计器内置的组件不能满足需求,因此要创建自定义组件。form-create 支持在表单内部生成任何 vue 组件。 

    1.开发选择用户的组件 SelectUser.vue

<!--用户选择组件-->
<template>
  <div>
    <el-row :gutter="10">
      <el-col :span="20">
        <el-input v-model="selectUserNames"/>
      </el-col>
      <el-col :span="4">
        <el-button type="primary" @click="selectUser">选择</el-button>
      </el-col>
    </el-row>
    <el-input v-model="selectUserIds" style="display: none"/>
    <el-dialog title="选择用户" v-model="dialogVisible" width="50%">
      <el-row :gutter="10">
        <el-col :span="8">
          <el-tree-select v-model="value" :data="orgData" filterable :props="orgProps" show-checkbox/>
        </el-col>
        <el-col :span="8">
          <el-input v-model="userName" placeholder="账号"/>
        </el-col>
        <el-col :span="8">
          <el-button type="primary" @click="search">查询</el-button>
        </el-col>
      </el-row>
      <el-table v-loading="loading" :data="tableData" ref="tableRef" stripe style="width: 100%;height: 350px"
                @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55"/>
        <el-table-column prop="username" label="用户账号" width="140"/>
        <el-table-column prop="realname" label="用户姓名" width="140"/>
        <el-table-column prop="sex_dictText" label="性别" width="80"/>
        <el-table-column prop="orgCodeTxt" label="部门"/>
      </el-table>
      <Pagination v-if="pagination.total" :pageSize="pagination.pageSize" :pageNo="pagination.pageNo"
                  :total="pagination.total" @pageChange="pageChange" @sizeChange="sizeChange"/>
      <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="updateSelect">
          确定
        </el-button>
      </span>
      </template>
    </el-dialog>
  </div>
</template>
<script lang="ts">
import {defineComponent, reactive, ref, watch} from 'vue'
import {defHttp} from "/@/utils/http/axios";
import Pagination from "./Pagination.vue";
import {ElTable} from 'element-plus'

export default defineComponent({
  name: "SelectUser",
  components: {
    Pagination, ElTable
  },
  props: {
    modelValue: {
      type: String,
    },
  },
  emits: ['update:modelValue'],
  setup(props, {emit}) {
    const tableRef = ref<InstanceType<typeof ElTable>>()
    const selectUserIds = ref<any>()
    const multipleSelection = ref([])

    //初始化赋值
    selectUserIds.value = props.modelValue

    const userName = ref<any>()
    const value = ref<any>()
    const orgData = ref<any>([])
    const orgProps = ref<any>({
      label: 'title'
    })
    const pagination = reactive({
      pageNo: 1,
      pageSize: 10,
      total: null
    })
    const dialogVisible = ref<boolean>(false)
    const loading = ref<boolean>(false)
    const tableData = ref<any>([])

    const selectUsers = ref<any>([])
    const selectUserNames = ref<any>()

    async function list(pageNo, pageSize) {
      loading.value = true
      if (pageNo) pagination.pageNo = pageNo;
      if (pageSize) pagination.pageSize = pageSize;
      let params = {
        username: userName.value,
        departId: value.value,
        pageNo: pagination.pageNo,
        pageSize: pagination.pageSize
      }
      const data = await defHttp.get({url: "/sys/user/queryUserComponentData", params});
      tableData.value = data.records
      pagination.total = data.total
      loading.value = false
    }

    function search() {
      list(1, 10);
    }

    //切换当前页时触发
    function pageChange(page) {
      list(page, 10);
    }

    //每页展示条数切换时触发
    function sizeChange(value) {
      list(1, value);
    }

    /**
     * 组织结构树查询
     */
    async function initDeptData() {
      const data = await defHttp.get({url: "/sys/sysDepart/queryTreeList"});
      orgData.value = data
    }

    watch(
      () => props.modelValue,
      (val: string, prevVal: string) => {
        selectUserIds.value = val
        if (!selectUserNames.value) {
          listRealnameData(val)
        }
      },
      {
        immediate: true,
      }
    );

    /**
     * 根据用户名查询真实姓名
     */
    async function listRealnameData(value) {
      if (!value) {
        return
      }
      let params = {
        userNames: value
      }
      const data = await defHttp.get({url: "/sys/user/listRealname", params});
      selectUserNames.value = data
    }

    /**
     * 选择用户
     */
    async function selectUser() {
      dialogVisible.value = true
      if (orgData.value.length == 0) {
        initDeptData();
      }
      await list(1, 10)
      let checkUsers = [];
      if (selectUserIds.value) {
        selectUserIds.value.split(",").forEach((item) => {
          let list = tableData.value.filter(val => val.username == item);
          if (list && list.length > 0) {
            checkUsers.push(list[0])
          }
        })
      }
      if (checkUsers && checkUsers.length > 0) {
        checkUsers.forEach(row => {
          tableRef.value!.toggleRowSelection(row, true)
        })
      }
    }

    const handleSelectionChange = (val) => {
      multipleSelection.value = val
    }

    /**
     * 确认选择
     */
    function updateSelect() {
      let selectUserIds = []
      let selectUsers = []
      if (multipleSelection.value.length > 0) {
        multipleSelection.value.forEach((item) => {
          selectUserIds.push(item.username)
          selectUsers.push(item.realname)
        })
      }
      selectUserNames.value = selectUsers.join(",")
      emit('update:modelValue', selectUserIds.join(","));
      dialogVisible.value = false
    }


    return {
      tableRef,
      multipleSelection,
      userName,
      value,
      orgData,
      orgProps,
      pagination,
      dialogVisible,
      loading,
      tableData,
      selectUserIds,
      selectUsers,
      search,
      pageChange,
      sizeChange,
      initDeptData,
      selectUser,
      handleSelectionChange,
      updateSelect,
      selectUserNames
    }
  }
});
</script>
<style lang="less" scoped>

</style>

参考: 生成自定义组件 | form-create 

2.注册组件

全局注册:在main.ts中引入自定义组件,

app.component('selectUser', SelectUser) 注册组件。

 3.form-create-designer自定义组件

(1)定义组件的拖拽规则

创建文件SelectUser.ts,内容如下:

import uniqueId from '@form-create/utils/lib/unique';
import {localeProps, makeRequiredRule} from './index';

const label = '用户组件';
const name = 'selectUser';

export const selectuser = {
  //拖拽组件的图标
  icon: 'icon-add',
  //拖拽组件的名称
  label,
  //拖拽组件的 key
  name,
  //拖拽组件的生成规则
  rule() {
    //如果在 props 方法中需要修改 rule 的属性,需要提前在 rule 上定义对应的属性
    return {
      //生成组件的名称
      type: name,
      //field 自定不能重复,所以这里每次都会生成一个新的
      field: uniqueId(),
      title: label,
      info: '',
      $required: false,
      props: {},
    };
  },
  //拖拽组件配置项(props)的生成规则
  props(_, {t}) {
    return localeProps(t, name + '.props', [
      makeRequiredRule(),
    ])
  }
};

注意:name = 'selectUser',name的值为注册的组件名称。

rule的规则配置请参考:自定义组件 | form-create-designer

(2)将自定义拖拽规则插入到表单设计器form-create-designer左侧表单

<template>
  <fc-designer ref="designerRef"/>
</template>

<script lang="ts" setup>
import {ref} from 'vue';
import {selectuser} from "./custom/SelectUser";

const designerRef = ref()

//插入组件规则
designerRef.value.addComponent(selectuser);

//插入拖拽按钮到`系统组件`分类下
designerRef.value.addMenu({
  title: '系统组件',
  name: 'system',
  list: [
    {
      icon: selectuser.icon,
      name: selectuser.name,
      label: selectuser.label
    }]
});

</script>
 

4.表单设计器form-create-designer效果图

预览效果图: 

 5.表单创建器form-create生成的表单效果图

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

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

相关文章

论文《Diagnostic accuracy of CT imaging parameters in pelvic lipomatosis》案例分析

一、引言 在该篇文章的引言部分&#xff0c;作者明确阐述了本篇论文的研究目的、问题和方法&#xff0c;并指出了研究的贡献和创新点。以下是具体内容&#xff1a; 研究目的&#xff1a;本研究的目的是评估盆腔脂肪肥大的CT成像特征&#xff0c;并探讨其在诊断和管理中的应用…

Java程序设计入门教程--包

情形 在Java中&#xff0c;包(package)是一种松散的类的集合&#xff0c;它可以将各种类文件组织在一起&#xff0c;就像磁盘的目录&#xff08;文件夹&#xff09;一样。包的管理机制提供了类的多层次命名空间避免了命名冲突问题&#xff0c;解决了类文件的组织问题&#xff0…

Midjourney AI绘画中文教程(完整版)

我有一种预感&#xff0c;这篇内容一定会破万~~~ Midjourney AI绘画中文教程&#xff0c;Midjourney是一款2022年3月面世的AI绘画工具&#xff0c;创始人是David Holz。 只要输入想到的文字&#xff0c;就能通过人工智能产出相对应的图片&#xff0c;耗时只有大约一分钟&…

Linux Shell 实现部署单机Oracle 21C

oracle前言 Oracle开发的关系数据库产品因性能卓越而闻名&#xff0c;Oracle数据库产品为财富排行榜上的前1000家公司所采用&#xff0c;许多大型网站也选用了Oracle系统&#xff0c;是世界最好的数据库产品。此外&#xff0c;Oracle公司还开发其他应用程序和软件。同时&#…

《Spring Guides系列学习》guide1 - guide5

要想全面快速学习Spring的内容&#xff0c;最好的方法肯定是先去Spring官网去查阅文档&#xff0c;在Spring官网中找到了适合新手了解的官网Guides&#xff0c;一共68篇&#xff0c;打算全部过一遍&#xff0c;能尽量全面的了解Spring框架的每个特性和功能。 开始吧&#xff0…

UDP就一定比TCP快吗?

前言 话说&#xff0c;UDP比TCP快吗&#xff1f; 相信就算不是八股文老手&#xff0c;也会下意识的脱口而出&#xff1a;”是“。 但这也让人好奇&#xff0c;用UDP就一定比用TCP快吗&#xff1f;什么情况下用UDP会比用TCP慢&#xff1f; 我们今天就来聊下这个话题。 使用…

关于使用--- pyinstaller---无法打包py文件为exe的问题集合

目录 安装 pyinstaller 问题1&#xff1a; 解决办法&#xff1a; CMD中输入 问题2&#xff1a; 解决办法&#xff1a; CMD中输入 问题3&#xff1a; 将py文件打包成exe中&#xff0c;需要按照如下在CMD中输入 PyInstaller介绍 PyInstaller是一个Python库&#xff0c;可以…

智慧档案馆八防是怎么建设的?都需要注意哪些内容

智慧档案馆八防环境监控系统一体化解决系统方案 智慧档案库房一体化平台通过智慧档案管理&#xff0c;实现智慧档案感知协同处置功能&#xff1b;实现对档案实体的智能化识别、定位、跟踪监控&#xff1b;实现对档案至智能密集架、空气恒湿净化一体设备、安防设备&#xff0c…

基于java用队列实现栈

基于java用队列实现栈 问题描述 请你仅使用两个队列实现一个后入先出&#xff08;LIFO&#xff09;的栈&#xff0c;并支持普通栈的全部四种操作&#xff08;push、top、pop 和 empty&#xff09;。 实现 MyStack 类&#xff1a; void push(int x) 将元素 x 压入栈顶。 int …

C++第六章:函数

函数 一、函数基础1.0 简介形参和实参形参列表函数的返回类型 1.1 局部对象自动对象局部静态对象 1.2 函数声明在头文件中进行函数声明 1.3 分离式编译编译和链接多个源文件 二、参数传递2.1 传值参数指针形参 2.2 传引用参数使用形参返回额外信息 2.3 const形参和实参指针或引…

「实在RPA·人社数字员工」促进人力社保数字办公战略转型

一、人力社保部门数字化转型的重要性 伴随着国家放宽人力资源市场准入条例&#xff0c;多次出台相关扶持政策&#xff0c;市场竞争加剧&#xff0c;后疫情时代格局的大变局&#xff0c;如何提高服务质量和效率&#xff0c;如何降本增效&#xff0c;成为人力资源和社会保障行业…

【算法】不使用LinkedHashMap实现一个LRU缓存

文章目录 什么是LRU&#xff1f;设计思路代码实现 LRU是我在面试过程中遇到的比较多的算法题了&#xff0c;并且我自己的项目中也手写了LRU算法&#xff0c;所以觉得还是有必要掌握一下这个重要的算法的。 什么是LRU&#xff1f; LRU是一种缓存淘汰策略。 我们知道&#xff0…

经典文献阅读之--PIBT(基于可见树的实时规划方案)

0. 简介 作为路径规划而言&#xff0c;不单单有单个机器人自主路径规划&#xff0c;近年来随着机器人行业的兴起&#xff0c;多机器人自主路径规划也越来越受到关注&#xff0c;对于多智能体寻路(MAPF)。一般的操作会给定一个地图、机器人集群、以及它们的初始位置和目的地&am…

IP地址分配与释放

IP 分配我们平时应该接触比较少。还记得在大学的时候&#xff0c;刚入学第一件事就是赶紧交网费。交网费时会有一个步骤&#xff0c;网管会让你提供 MAC 地址&#xff0c;然后把 IP 地址和 MAC 地址绑定&#xff0c;这也就是博主在隔壁宿舍无法通过网线上网的原因。 其实&#…

如何在华为OD机试中获得满分?Java实现【寻找相似单词】一文详解!

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: Java华为OD机试真题&#xff08;2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述…

[已解决] 决定系数R2为何为负 from sklearn.metrics import r2_score

最近在炼丹发现一件很有趣的现象&#xff0c;决定系数R2竟然为负&#xff0c;小学生都知道任何一个常数的平方绝不可能为负&#xff0c;潜意识里告诉我这里面必有蹊跷&#xff0c;因此查阅许多资料得知&#xff0c;决定系数R2不是r相关系数的平方这么简单&#xff0c;实际上当非…

加密后的敏感字段还能进行模糊查询吗?该如何实现?

前言 有一个问题不知道大家想过没&#xff1f;敏感字段数据是加密存储在数据库的表中&#xff0c;如果需要对这些敏感字段进行模模糊查询&#xff0c;还用原来的通过sql的where从句的like来模糊查询的方式肯定是不行的&#xff0c;那么应该怎么实现呢&#xff1f;这篇文章就来…

zigbee 串行通信

串口通信需要三个函数 // Initialize UART at the startup //------------------------------------------------------------------- void halUartInit(uint32 baud);//------------------------------------------------------------------- // Read a buffer from the UART …

MySQL 的锁

目录 一、锁的分类 二、全局锁、表级锁、页级锁、行级锁 三、乐观锁和悲观锁 四、共享锁和排它锁 五、意向共享锁和意向排它锁 六、间隙锁、临键锁、记录锁 锁的分类和用途 一、锁的分类 1、MySQL锁可以按模式分类为&#xff1a; 乐观锁悲观锁。 2、按粒度分可以分为&a…

【2023 · CANN训练营第一季】MindSpore模型快速调优攻略 第三章——MindSpore云上调试调优

1.ModelArts云上调试调优 ModelArts密钥初始化 详细教程&#xff1a; 初始化OBS服务 创建训练作业 2.MindSpore IDE插件效率提升 通过智能代码块推荐、代码自动补全等特性&#xff0c;提升MindSpore脚本开发效率&#xff0c;对接ModelArts云服务&#xff0c;实现模型训…