当前位置: 首页 > news >正文

《Vue项目开发实战》第五章:组件封装--Form

系列文章

《Vue项目开发实战》https://blog.csdn.net/sen_shan/category_13075264.html

第四章:组件封装--ToolBarhttps://blog.csdn.net/sen_shan/article/details/154640827

文章目录

前言

文章详细讲解了DynamicForm通用表单组件的技术方案,包括字段描述接口定义、布局逻辑、内置校验规则、日期格式化处理等功能特性。该组件支持通过字段描述数组实现多类型表单渲染,自动处理双向绑定和数据校验,可无缝集成到弹窗、抽屉等场景。文章还提供了组件使用范例和样式主题定制方法,展示了如何通过expose暴露validate/resetFields等表单操作方法。组件采用TypeScript开发,实现数据驱动表单生成能力,提升开发效率。

Form组件

src\components\ActionFormCont.vue  基于原逻辑微调,细节略。

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import router from './router';
import App from './App.vue'
import { createPinia } from 'pinia'
//import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
import { createPersistedState } from 'pinia-plugin-persistedstate'
// 引入 Mock 数据
//import './mock' //暂时关闭
import { ReloadData,useAllDataStore } from '@/stores';
import { i18n } from '@/locales';
import defaultConfig from '@config/index.js'; // 相对路径
import '@/assets/styles/index.css';
import '@unocss/reset/tailwind.css' // 可选重置
import 'uno.css'
const mockEnabled = defaultConfig.mockEnabled;if (mockEnabled) {import('./mock').then(() => {console.log('Mock 已加载');});
}// 创建 Pinia 实例
const pinia = createPinia();const app = createApp(App)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, component)}//  app.use(router);// 使用插件// pinia.use(piniaPluginPersistedstate);pinia.use(createPersistedState({key: id => `__persisted__${id}`,storage: sessionStorage,}))app.use(pinia);
// 国际化// 设置 i18n 的 locale
let currentLanguage = navigator.language.replace(/-(\S*)/, '');
// 如果本地缓存记录了语言环境,则使用本地缓存
const Store = useAllDataStore();
let lsLocale = Store.getLocale() || '';
console.log('lsLocale', lsLocale);
if (lsLocale) {try {const parsedLocale = JSON.parse(lsLocale);currentLanguage = parsedLocale?.curLocale || 'zh'; // 确保有默认值} catch (error) {// console.error('Failed to parse lsLocale:', error);currentLanguage = lsLocale; // 如果解析失败,直接使用 lsLocale}
}// 校验语言是否合法,仅允许 "zh" 或 "en"
const allowedLocales: ("zh" | "en")[] = ["zh", "en"];
currentLanguage = allowedLocales.includes(currentLanguage as "zh" | "en")? currentLanguage: "zh"; // 如果非法,默认设置为 "zh"// 设置 i18n 的 locale
i18n.global.locale.value = currentLanguage as "zh" | "en";ReloadData();app.use(router);app.use(ElementPlus, {locale: zhCn,})app.use(i18n);app.mount('#app')

技术文档:DynamicForm 组件(基于 Element Plus)
版本:v1.3
文件路径: src/components/DynamicForm.vue 

一、组件定位
通用数据驱动表单引擎,零代码扩展:
仅需一份“字段描述数组”即可渲染出多行、多列、多类型的表单;
自动双向绑定、校验、分组布局;
支持只读、隐藏、行列合并、日期格式化等常用能力;
通过  expose  向外暴露  validate / resetFields ,可无缝嵌入抽屉、弹窗、步骤条等场景。
二、接口一览(props & events)

事件
 update:data (隐式)—— 内部  formData  变化时实时向外抛出,可直接  v-model:data  使用。

三、Field 字段描述子项

interface Field {field: string;          // 对应 data 的 keylabel: string;          // 标签文本input_type: 'text'|'select'|'date'|'number'|'switch'|'textarea';row_id?: number;        // 分组行号,默认 1col_span?: number;      // 列宽,默认 24(即一行一列)hide?: boolean;         // true 时不渲染read_only?: boolean;    // 是否禁用is_null?: boolean;      // 是否允许为空(false=必填)Validation?: any;       // Element 规则对象或自定义校验函数options?: {label:string; value:any; disabled?:boolean}[];rows_num?: number;      // textarea 行高,默认 2
}

四、布局逻辑
1. 先过滤  hide=true  的字段;
2. 按  row_id  归并到同一  <el-row> ;
3. 每行内部按  col_span  做响应式栅格;
4. 未指定  row_id  的字段默认归入第 1 行。

五、内置校验
当  is_null=false (即必填)时,组件自动追加规则
  {required:true, message:'${label}不能为空', trigger:'blur'} 
若提供  Validation ,则追加到同字段规则数组,支持异步、自定义校验。

六、日期格式化
 el-date-picker  选择后自动格式化为  YYYY-MM-DD  字符串,回写到  formData[field] 。

七、样式主题
通过  size="large"  统一大字号;
提供  .big-form  作用域类名(已注释在  <style> ),可在父级加  class="big-form"  一键放大字体与行高;
 popper-class="bg-amber-50/70 rounded-md"  给下拉面板加浅色圆角背景,保持视觉统一。

八、使用范例【详见后章节】

<template><!-- 弹窗内直接使用 --><DynamicFormv-model:data="entity":fields="fields"ref="formRef"/><el-button type="primary" @click="submit">保存</el-button>
</template><script setup>
import { ref } from 'vue'
const entity = ref({name: '',gender: '',birthday: ''
})const fields = [{ field:'name', label:'姓名', input_type:'text', row_id:1, col_span:12 },{ field:'gender', label:'性别', input_type:'select', row_id:1, col_span:12,options:[{label:'男',value:1},{label:'女',value:0}] },{ field:'birthday', label:'生日', input_type:'date', row_id:2 }
]const formRef = ref()
async function submit(){try {await formRef.value.validate()// 调接口保存} catch {}
}
</script>

九、暴露方法(已注释,可按需打开)

defineExpose({
  resetFields: () => formRef.value?.resetFields(),
  validate:    () => formRef.value?.validate()
})
 

http://www.dtcms.com/a/601921.html

相关文章:

  • 数据管理战略|流程与IT变革、量化闭环
  • 外卖网站制作wordpress主题 制作教程
  • 企业网站总承包建设模式关键步骤wordpress安装主题后打不开
  • 在纷扰世界里找到自己的安心之道——《安心之道》的实践指南
  • 网站建设的公司太多了东莞南城房价
  • 【python】使用opencv的模板匹配进行自动化点击
  • leetcode 2654 使数组所有元素变成1的最少操作次数
  • 数据结构(长期更新)第8讲:队列
  • LKT4305安全芯片身份认证介绍
  • 看门狗超时时间的理解
  • C语言编译器手机教程 | 轻松在手机上编写和编译C语言程序
  • 基于SpringBoot的企业资产管理系统开发与设计
  • 黄骅做网站价格莱芜金点子招工小时工
  • 速卖通网站怎样做店面的二维码厦门网站建设
  • 好创意网站有哪些方面幸运28网站开发
  • AI小白入门:什么是RAG技术?
  • 【一天一个计算机知识】—— 【编程百度】条件编译
  • 网站分享注册公司代理电话
  • 免费制作一个企业网站广告设计公司网页
  • Gradle vs Maven 详细对比
  • [Column#187] 10data_struct | IP速查表 | 协议TCPUDP | DeepSeek-OCR
  • 生产级HMACSHA256签名与验签案例
  • 腾讯云服务器搭建网站漯河网站建设费用
  • docker部署开源监控软件hertzbeat
  • 上海网站网站建设工程公司简介范文大全
  • STM32CubeMx学习hal库
  • 在线确定性算法与自适应启发式在虚拟机动态整合中的竞争分析与性能优化
  • 企业网站建设费多少钱硬盘做免费嗳暧视频网站
  • 做图在哪个网站上找南京自助建站模板
  • 山东市网站建设中国林业网站群建设工程