vue3封装Element动态表单组件

news2024/11/22 14:42:22

在这里插入图片描述

1. 封装组件DymanicForm.vue

  1. 使用component实现动态组件
  2. 组件不能直接使用字符串传入,所以根据传入的组件名称找到对应的组件
  3. 校验规则,可使用rule传入自定义规则,也可以使用封装好的基本规则 示例中使用了checkRequired
  4. 暴露重置方法和校验方法
<template>
  <el-form
    :model="currentValue"
    ref="dymanicForm"
    v-bind="$attrs"
    @submit.native.prevent
  >
    <el-form-item
      :prop="index"
      :rules="item.rules"
      v-for="(item, index) in currentSchema"
      :key="index"
      v-bind="item.formItem || {}"
    >
      <component
        v-model="currentValue[index]"
        :is="item.componentName"
        v-bind="item"
        v-on="item.methods || {}"
      />
    </el-form-item>
    <slot />
  </el-form>
</template>

<script lang="ts" setup>
import checkValidator from "~/utils/validator/index";

import {
  ElInput,
  ElSelect,
  ElDatePicker,
  ElCheckbox,
  ElRadio,
  ElRadioGroup,
  ElCheckboxGroup,
  ElSwitch,
} from "element-plus";

const componentMap = {
  ElInput: ElInput,
  ElSelect: ElSelect,
  ElDatePicker: ElDatePicker,
  ElCheckbox: ElCheckbox,
  ElRadio: ElRadio,
  ElRadioGroup: ElRadioGroup,
  ElCheckboxGroup: ElCheckboxGroup,
};

const props = defineProps({
  schema: Object,
  modelValue: [String, Number, Boolean, Array, Date, Object],
});
const emit = defineEmits(["update:modelValue"]);
const currentValue = computed({
  get: () => props.modelValue,
  set: (val) => emit("update:modelValue", val),
});

const currentSchema = computed(() => {
  const schema = {};
  for (const key in props.schema) {
    let { visible = true, ...item } = props.schema[key];
    // 动态表单的组件名
    item.componentName = componentMap[item.componentName];
    // 是否显示
    visible =
      typeof visible !== "function" ? visible : visible(currentValue, item);
    if (visible) {
      schema[key] = { clearable: true, ...item };
    }
    // 表单验证规则
    if (schema[key].validator && schema[key].validator.length) {
      if (!schema[key].rules) schema[key].rules = [];
      schema[key].validator?.forEach(([valida, args]) => {
        if (checkValidator[valida]) {
          schema[key].rules.unshift(checkValidator[valida](args));
        }
      });
    }
  }
  return schema;
});
const dymanicForm = ref(null);
const validate = (func) => {
  if (typeof func === "function") {
    dymanicForm.value.validate((valid) => {
      func(valid);
    });
  } else {
    return new Promise((resolve) => {
      dymanicForm.value.validate((valid) => {
        resolve(valid);
      });
    });
  }
};
const resetFields = () => {
  dymanicForm.value.resetFields();
};

defineExpose({
  resetFields,
  validate,
});
</script>

2. 调用组件示例

<template>
  <div class="">
    <DymanicForm
      ref="formRef"
      :inline="true"
      :schema="schema"
      v-model="searchValue"
    >
      <el-form-item>
        <el-button type="primary" @click="handleQuery">查询</el-button>
        <el-button @click="handleReset">重置</el-button>
      </el-form-item>
    </DymanicForm>
  </div>
</template>
<script setup lang="ts">
import { ref, reactive } from "vue";
import type { ItemSchema } from "~/types/dymanic";
import DymanicForm from "~/components/DymanicForm.vue";

const formRef = ref<InstanceType<typeof DymanicForm>>();
const schema = ref<ItemSchema>({
  userId: {
    formItem: {
      label: "用户ID:",
    },
    style: {
      width: "200px",
    },
    componentName: "ElInput",
    placeholder: "请输入用户ID",
    maxlength: 20,
    validator: [
      [
        "checkRequired",
        {
          msg: "用户ID不能为空",
        },
      ],
    ],
  },
  username: {
    formItem: {
      label: "账号:",
    },
    style: {
      width: "200px",
    },
    componentName: "ElInput",
    placeholder: "请输入账号",
    maxlength: 20,
  },
  name: {
    formItem: { label: "用户名:" },
    style: {
      width: "200px",
    },
    componentName: "ElInput",
    placeholder: "请输入用户名",
    maxlength: 20,
  },
});
const searchValue = reactive({
  userId: "",
  username: "",
  name: "",
});
const handleQuery = () => {
  formRef.value.validate((valid: boolean) => {
    if (valid) {
      console.log("查询", searchValue);
      // 查询逻辑
    }
  });
};

const handleReset = () => {
  formRef.value.resetFields();
};
</script>
<style lang="scss" scoped></style>

3. 校验规则示例

// 校验内容不能为空的验证
const checkRequired = ({ msg, trigger = ['blur'] }) => {
  return {
    required: true,
    message: msg,
    trigger,
  }
}

export default checkRequired

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

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

相关文章

git配置密钥

要配置 Git 密钥&#xff0c;可以按照以下步骤进行操作&#xff1a; 1.生成密钥&#xff1a;首先&#xff0c;在终端或命令提示符中运行以下命令生成密钥对&#xff1a; ssh-keygen -t rsa -b 4096 -C "dengweng-pulse.net"这将生成一个 RSA 密钥对&#xff0c;其中…

面试题:Java虚拟机JVM的组成

1. 基础概念 JVM是什么 Java Virtual Machine Java程序的运行环境&#xff08;java二进制字节码的运行环境&#xff09; 好处&#xff1a; 一次编写&#xff0c;到处运行 自动内存管理&#xff0c;垃圾回收机制 JVM由哪些部分组成&#xff0c;运行流程是什么&#xff1f; …

vue.js——学习计划表

1&#xff09;准备工作 ①打开D:\vue\chapter02\ learning_schedule 目录&#xff0c;找到 index.html 文件。 在文件中引 入BootStrap 样式文件&#xff0c;具体代码如下 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8&qu…

tensorflow安装GPU版报错cublasLt64_11.dll缺失

我的报错是&#xff1a; Use tf.config.list_physical_devices(GPU) instead. 2024-03-28 17:01:46.724677: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the follo…

蓝桥杯嵌入式学习笔记(6):IIC程序设计

目录 前言 1. IIC基本原理 2. 电路原理 3. 代码编程 3.1 预备工作 3.2 AT24C02写读功能编写 3.2.1 AT24C02写操作实现 3.2.2 AT24C02读操作实现 3.3 MCP4017写读功能编写 3.3.1 MCP4017写操作实现 3.3.2 MCP4017读操作实现 3.4 main.c编写 3.4.1 头文件引用 3.4.…

react-navigation:

我的仓库地址&#xff1a;https://gitee.com/ruanjianbianjing/bj-hybrid react-navigation&#xff1a; 学习文档&#xff1a;https://reactnavigation.org 安装核心包: npm install react-navigation/native 安装react-navigation/native本身依赖的相关包: react-nativ…

水电站生态流量监测解决方案:亲历水电站生态监控改造

​记得那是在2022年夏天,我所在的环保咨询公司接到了一项非常具有挑战性的监测项目。某省的环保部门要求对辖区内所有水电站的生态流量情况进行评估,并给出整改建议。作为项目负责人,我深知这项工作的重要意义。&#xff08;选自&#xff1a;智慧水务数字孪生安全监测解决方案提…

武汉星起航公司助力零经验新手卖家征战亚马逊跨境电商市场

在数字化浪潮的推动下&#xff0c;亚马逊跨境电商行业正逐渐成为众多创业者和企业家们的新战场。然而&#xff0c;对于零经验的新手卖家而言&#xff0c;这片广袤的电商海洋无疑充满了未知与挑战。在这个关键时刻&#xff0c;武汉星起航公司以其专业的服务和深厚的行业积累&…

怎么做扫描二维码填写数据?用二维码收集用户反馈的方法

现在很多人都开始使用扫码填表的方式来收集用户反馈、签到登记、问卷调查等类型的用途&#xff0c;这种方式的使用不仅减少了制作者的成本压力&#xff0c;采用无纸化登记也提高了用户填写数据的便利性。只需要制作一个二维码&#xff0c;分享之后就可以让许多人同时扫码填写数…

详解GPT模型的前世今生

省流版&#xff1a; GPT模型是一种基于神经网络的自回归语言模型。该模型使用了一个称为“Transformer”的架构&#xff0c;从而有效避免了传统的循环神经网络产生的梯度消失问题。从第一代GPT到现在的GPT4&#xff0c;没带都产生了不同的变化&#xff0c;其性能也越来越强大。…

【Java扫盲篇】String、String Buffer和String Builder的区别

你在面试时&#xff0c;面试官让你讲讲String String Buffer String Builder的区别&#xff0c;你是否能流畅的、完整的叙述出他们三者的区别? ✍先说结论 相同点&#xff1a; 他们的底层都是由char数组实现的。不同点&#xff1a; String对象一旦创建&#xff0c;是不能修…

android安卓餐厅点餐课设

一、引言 随着移动互联网的快速发展&#xff0c;手机应用已经成为我们日常生活中不可或缺的一部分。餐饮行业也积极借助移动应用的力量&#xff0c;提供更便捷、高效的点餐服务。本文将介绍一个基于安卓系统开发的餐厅点餐APP的课程设计项目&#xff0c;探讨其设计理念、功能特…

PostgreSQL数据库如何新建登录用户?

在PostgreSQL数据库中&#xff0c;如何创建新的登录用户呢&#xff1f; 默认情况&#xff0c;PostgreSQL数据库的默认用户是&#xff1a;postgres &#xff0c;如果我们需要创建一个新的低权限用户角色&#xff0c;应该如何操作&#xff1f;本章教程&#xff0c;简单介绍一下这…

JavaFX的安装和使用

JavaFX的安装 安装可以参考&#xff1a;IDEA安装JavaFx_idea2019 javafx 下载安装-CSDN博客 JavaFX的使用 在JavaFX中&#xff0c;类的成员函数和操作本身被模式化作为在目标类中的类&#xff0c;而参数和返回值被表示为属性。代表目标对象的属性名是“this”。代表返回值的…

【C++初阶】之类和对象(中)

【C初阶】之类和对象&#xff08;中&#xff09; ✍ 类的六个默认成员函数✍ 构造函数&#x1f3c4; 为什么需要构造函数&#x1f3c4; 默认构造函数&#x1f3c4; 为什么编译器能自动调用默认构造函数&#x1f3c4; 自己写的构造函数&#x1f3c4; 构造函数的特性 ✍ 拷贝构造…

经纬恒润RTaW-Pegase:车载网络通信建模与时间特性分析工具

▎RTaW简介 RTaW-Pegase是由法国国家信息与自动化研究所&#xff08;INRIA&#xff09;旗下的RTaW公司开发的产品。它主要用于构建和优化汽车、航空航天以及工业领域的通信网络&#xff0c;包括时间敏感网络&#xff08;TSN&#xff09;、CAN&#xff08;FD&#xff0c;XL&…

【系统架构师】-第12章-信息系统架构

信息系统架构(ISA)是指对某一特定内容里的信息进行统筹、规划、设计、安排等一系列有机处理的活动。 为了更好地理解信息系统架构的定义&#xff0c; 特作如下说明: (1)架构是对系统的抽象&#xff0c;它通过描述元素、元素的外部可见属性及元素之间的关系来反映这种抽象。因此…

【QT入门】 Qt代码创建布局之水平布局、竖直布局详解

往期回顾&#xff1a; 【QT入门】 Qt实现自定义信号-CSDN博客 【QT入门】 Qt自定义信号后跨线程发送信号-CSDN博客 【QT入门】 Qt内存管理机制详解-CSDN博客 【QT入门】 Qt代码创建布局之水平布局、竖直布局详解 先看两个问题&#xff1a; 1、ui设计器设计界面很方便&#xf…

PyQT5学习--新建窗体模板

目录 1 Dialog 2 Main Window 3 Widget Dialog 模板&#xff0c;基于 QDialog 类的窗体&#xff0c;具有一般对话框的特性&#xff0c;如可以模态显示、具有返回值等。 Main Window 模板&#xff0c;基于 QMainWindow 类的窗体&#xff0c;具有主窗口的特性&#xff0c;窗口…

计算机网络基础——网络安全/ 网络通信介质

chapter3 网络安全与管理 1. 网络安全威胁 网络安全&#xff1a;目的就是要让网络入侵者进不了网络系统&#xff0c;及时强行攻入网络&#xff0c;也拿不走信息&#xff0c;改不了数据&#xff0c;看不懂信息。 事发后能审查追踪到破坏者&#xff0c;让破坏者跑不掉。 网络…