vue3 + antd 封装动态表单组件(一)

前置条件:

vue版本 v3.3.11
ant-design-vue版本 v4.1.1

创建动态组件配置文件config.js

import { Input, Textarea, InputNumber, Select, RadioGroup, CheckboxGroup, DatePicker } from 'ant-design-vue';

// 表单域组件类型
export const componentsMap = {
    Text: Input,
    Textarea,
    Number: InputNumber,
    Select,
    Radio: RadioGroup,
    Checkbox: CheckboxGroup,
    DatePicker,
}

创建dynamic-form.vue组件

<template>
  <div>
    <a-form ref="formRef" :model="formModel">
      <a-form-item
        :name="item.field"
        :label="item.label"
        v-for="item in formSchema"
        :key="item.field"
        v-bind="item.formItemProps"
      >
        <component
          :is="componentsMap[item.component]"
          v-bind="item.componentProps"
          v-model:value="formModel[item.field]"
        />
      </a-form-item>
    </a-form>
  </div>
</template>

<script setup>
import { ref, watch, onMounted } from "vue";
import { componentsMap } from "./config.js";

const props = defineProps({
  // 表单项配置
  schema: {
    type: Array,
    default: () => [],
  },
  // 表单model配置,一般用于默认值、回显数据
  model: {
    type: Object,
    default: () => ({}),
  },
});

const formRef = ref(null);

const formSchema = ref([]);
const formModel = ref({});

// 表单初始化
const initForm = () => {
  formSchema.value = props.schema.map((x) => {
    return {
      ...x,
    };
  });

  // model初始数据
  formModel.value = props.schema.reduce((pre, cur) => {
    if (!pre[cur.field]) {
      // 表单初始数据(默认值)
      pre[cur.field] = cur.value;
      return pre;
    }
  }, {});
};

onMounted(() => {
  initForm();
  // 构建表单项后才回显model值,model会覆盖schema配置的value值
  watch(
    () => props.model,
    (newVal) => {
      formModel.value = { ...formModel.value, ...newVal };
    },
    {
      immediate: true,
      deep: true,
    }
  );
});

// 表单验证
const validateFields = () => {
  return new Promise((resolve, reject) => {
    formRef.value
      .validateFields()
      .then((formData) => {
        resolve(formData);
      })
      .catch((err) => reject(err));
  });
};

// 表单重置
const resetFields = (isInit = true) => {
  // 是否清空默认值
  if (isInit) {
    formModel.value = {};
  }
  formRef.value.resetFields();
};

// 暴露方法
defineExpose({
  validateFields,
  resetFields,
});
</script>

使用dynamic-form.vue组件

<template>
  <div style="padding: 200px">
    <DynamicForm ref="formRef" :schema="schema" :model="model" />
    <div style="display: flex; justify-content: center">
      <a-button @click="handleReset(true)">重置(全部清空)</a-button>
      <a-button style="margin-left: 50px" @click="handleReset(false)"
        >重置</a-button
      >
      <a-button type="primary" style="margin-left: 50px" @click="handleSubmit"
        >提交</a-button
      >
    </div>
  </div>
</template>

<script setup>
import DynamicForm from "@/components/form/dynamic-form.vue";
import { ref } from "vue";
import dayjs from "dayjs";
const formRef = ref(null);

const schema = ref([
  {
    label: "姓名",
    field: "name",
    component: "Text",
    componentProps: {
      allowClear: true,
      showCount: true,
      maxlength: 20,
      style: {
        width: "500px",
      },
    },
    formItemProps: {
      rules: [
        {
          required: true,
          message: "请输入姓名",
          trigger: "blur",
        },
      ],
    },
  },
  {
    label: "性别",
    field: "sex",
    component: "Radio",
    componentProps: {
      options: [
        { value: 1, label: "男" },
        { value: 2, label: "女" },
        { value: 3, label: "保密" },
      ],
    },
    formItemProps: {
      rules: [
        {
          required: true,
          message: "请选择性别",
          trigger: "blur",
        },
      ],
    },
    value: 1,
  },
  {
    label: "生日",
    field: "birthday",
    component: "DatePicker",
    formItemProps: {
      rules: [
        {
          required: true,
          message: "生日日期不能为空",
          trigger: "blur",
        },
      ],
    },
  },
  {
    label: "兴趣",
    field: "hobby",
    component: "Checkbox",
    componentProps: {
      options: [
        { value: 1, label: "足球" },
        { value: 2, label: "篮球" },
        { value: 3, label: "排球" },
      ],
    },
  },
  {
    label: "国家",
    field: "country",
    component: "Select",
    componentProps: {
      allowClear: true,
      options: [
        { value: 1, label: "中国" },
        { value: 2, label: "美国" },
        { value: 3, label: "俄罗斯" },
      ],
    },
  },
  {
    label: "简介",
    field: "desc",
    component: "Textarea",
    componentProps: {
      allowClear: true,
      autoSize: {
        minRows: 4,
        maxRows: 4,
      },
      maxlength: 200,
      showCount: true,
    },
  },
]);
const model = ref({ name: "百里守约" });
// 提交
const handleSubmit = async () => {
  const formData = await formRef.value.validateFields();
  if (formData.birthday) {
    formData.birthday = dayjs(formData.birthday).format("YYYY-MM-DD");
  }
  console.log("提交信息:", formData);
};

// 重置
const handleReset = (isInit) => {
  formRef.value.resetFields(isInit);
};
</script>

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

还在手动复制文章吗?教你如何一键将文章从notion同步到WordPress

本文会给大家介绍如何在WordPress上安装一个插件&#xff0c;实现将notion上写的文章自动同步到WordPress上&#xff0c;从而提高写作效率&#xff0c;接下来请跟随我的脚步一起来操作吧&#xff01; 一、插件安装 在WordPress后台添加新插件页面中搜索“notion”&#xff0c;…

实验六 模式对象管理与安全管理

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的很重要&…

Matplotlib Mastery: 从基础到高级的数据可视化指南【第30篇—python:数据可视化】

文章目录 Matplotlib: 强大的数据可视化工具1. 基础1.1 安装Matplotlib1.2 创建第一个简单的图表1.3 图表的基本组件&#xff1a;标题、轴标签、图例 2. 常见图表类型2.1 折线图2.2 散点图2.3 条形图2.4 直方图 3. 图表样式与定制3.1 颜色、线型、标记的定制3.2 背景样式与颜色…

Linux——进程等待

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、为什么要进程等待二、进程等待的方法1、wait方法2、waitpid方法 三、获取子进程status 一…

2008年苏州大学837复试机试C语言

2008年苏州大学复试机试C 题目 编写程序充成以下功能: 一、从键盘上输入随机变量x的 10个取样点。X0&#xff0c;X1—X9 的值; 1、计算样本平均值 2、判定x是否为等差数列 3、用以下公式计算z的值(t0.63) 注。请对程序中必要地方进行注释 补充&#xff1a;个人觉得这个题目回…

【51单片机】矩阵按键

0、前言 参考&#xff1a;普中 51 单片机开发攻略 1、硬件 2、软件 main.c #include <reg52.h> #include <intrins.h> #include "delayms.h"typedef unsigned int u16; //对数据类型进行声明定义 typedef unsigned char u8; #define GPIO_KEY P1 #d…

leetcode:每日温度---单调栈

题目&#xff1a; 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不会升高&#xff0c;请在该位置用 0 来代替。 示例&…

浪花 - 用户信息展示+更新

1. 用户登录获取登录凭证 已登录的用户才能获取个人信息发送 Aixos 请求登录 const user ref();onMounted(async () > {const res await myAxios.get(/user/current);if (res.code 0) {console.log("获取用户信息成功");user.value res.data;} else {consol…

python_selenium自动化测试框架

设计思路 本文整理归纳以往的工作中用到的东西&#xff0c;现汇总成基础测试框架提供分享。 框架采用python3 selenium3 PO yaml ddt unittest等技术编写成基础测试框架&#xff0c;能适应日常测试工作需要。 1、使用Page Object模式将页面定位和业务操作分开&#xff0…

自然语言处理(Natural Language Processing,NLP)解密

专栏集锦&#xff0c;大佬们可以收藏以备不时之需&#xff1a; Spring Cloud 专栏&#xff1a;http://t.csdnimg.cn/WDmJ9 Python 专栏&#xff1a;http://t.csdnimg.cn/hMwPR Redis 专栏&#xff1a;http://t.csdnimg.cn/Qq0Xc TensorFlow 专栏&#xff1a;http://t.csdni…

多维表格产品vika多维表、Flowus、Wolai体验记录

昨天从下午6点肝到凌晨2点多体验低代码平台多维表格产品&#xff0c;体验了3个国内产品&#xff0c;vika多维表、Flowus、Wolai。 具有多维表格新型关系数据库的鼻祖是 Airtable&#xff0c;国内模仿产品有vika多维表、飞书多维表格等。 还有一种类型就是以在国内鼎鼎大名的N…

流式湖仓增强,Hologres + Flink构建企业级实时数仓

云布道师 2023 年 12 月&#xff0c;由阿里云主办的实时计算闭门会在北京举行&#xff0c;阿里云实时数仓Hologres 研发负责人姜伟华现场分享 HologresFlink 构建的企业级实时数仓&#xff0c;实现全链路的数据实时计算、实时写入、实时更新、实时查询。同时&#xff0c;随着流…

实验七 RMAN恢复管理器

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的很重要&…

Python笔记10-数据可视化练习折线图

文章目录 JSON数据Python数据和Json数据的相互转化pyecharts模块构建折线图全局配置绘制疫情数据折线图 JSON数据 JSON是一种轻量级的数据交互格式。可以按照JSON指定的格式去组织和封装数据 。本质上是一个带有特定格式的字符串 主要功能&#xff1a;可以在各个编程语言中流通…

JumpServer 堡垒机安装指南

介绍 什么是JumpServer JumpServer 是广受欢迎的开源堡垒机&#xff0c;是符合 4A 规范的专业运维安全审计系统。JumpServer 帮助企业以更安全的方式管控和登录所有类型的资产&#xff0c;包括&#xff1a; SSH (Linux / Unix / 网络设备 等)Windows (Web 方式连接 / 原生 R…

Wpf 使用 Prism 实战开发Day13

配置 AutoMapper 关系映射 在上一节 ToDoController 控制器&#xff0c;或 IToDoService 服务接口中&#xff0c;方法的传参都是直接传的实体类。但在实际开发过程中&#xff0c;这样是不允许的。标准且规范的做法是&#xff0c;定义一个数据传输层&#xff0c;即Dto层。 一.在…

forEach如何跳出或中断循环

文章目录 概要使用try...catch抛出错误设置数组长度为0使用splice删除数组的元素 概要 在Javascript中&#xff0c;我们使用forEach遍历循环的时候&#xff0c;往往会面临跳出循环和中断循环&#xff0c;我们可以采取以下几种方式&#xff1a; 使用try…catch抛出错误 const …

智能音箱喇叭杂音问题

智能音箱喇叭杂音问题 智能音箱生厂或出货过程会遇到多种喇叭播放有杂音的问题&#xff0e; 螺丝不匹配 智能音箱设备在生产过程&#xff0c;会有SPL测试喇叭失真&#xff0c;发现不良率8%的杂音问题&#xff0e; 分析原因是来料导入了新螺丝&#xff0c; 使用过程进入异物…

GO 中如何防止 goroutine 泄露

文章目录 概述如何监控泄露一个简单的例子泄露情况分类chanel 引起的泄露发送不接收接收不发送nil channel真实的场景 传统同步机制MutexWaitGroup 总结参考资料 今天来简单谈谈&#xff0c;Go 如何防止 goroutine 泄露。 概述 Go 的并发模型与其他语言不同&#xff0c;虽说它…

配置redis挂载

1. 暂停和删除redis 2.创建文件夹 /usr/local/software/redis/6379/conf/ /usr/local/software/redis/6379/data/ 把redis-conf文件上传到conf文件夹中 3.配置网络 docker network create --driver bridge --subnet172.18.12.0/16 --gateway172.18.1.1 wn_docker_net 4.运…