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

东莞网站建设哪里找海珠区建网站公司

东莞网站建设哪里找,海珠区建网站公司,手机就可以直接做设计的网站,有名的网站制作电话传送带#xff1a; vue3 antd 封装动态表单组件#xff08;一#xff09; vue3 antd 封装动态表单组件#xff08;二#xff09; 前置条件#xff1a; vue版本 v3.3.11 ant-design-vue版本 v4.1.1 我们发现ant-design-vue Input组件和FormItem组件某些属性支持slot插…传送带 vue3 antd 封装动态表单组件一 vue3 antd 封装动态表单组件二 前置条件 vue版本 v3.3.11 ant-design-vue版本 v4.1.1 我们发现ant-design-vue Input组件和FormItem组件某些属性支持slot插槽如何使得我们封装的动态表单组件也支持该功能呢(slot透传)本篇文章主要是解决该问题。 动态组件配置文件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, }// 配置各组件属性默认值相关配置项请查看ant-design官网各组件api属性配置 export const defaultComponentProps {Text: {allowClear: true,bordered: true,disabled: false,showCount: true,maxlength: 20,},Textarea: {allowClear: true,autoSize: { minRows: 4, maxRows: 4 },showCount: true,maxlength: 200,style: {width: 100%}},Select: {allowClear: true,bordered: true,disabled: false,showArrow: true,optionFilterProp: label,optionLabelProp: label,showSearch: true,},DatePicker: {allowClear: true,bordered: true,disabled: false,format: YYYY-MM-DD,picker: date,style: {width: 100%}}, }dynamic-form.vue组件 templatediva-form refformRef :modelformModel v-bind$attrsa-form-item:nameitem.field:labelitem.labelv-foritem in formSchema:keyitem.fieldv-binditem.formItemProps!-- 表单form-item插槽, 注意优先级组件formItemProps.slots formItemPropsSlots--templatev-forslot in formItemPropsSlots#[slot.name]slotProps:keyslot.keytemplate v-ifslot.field item.fieldslot :nameslot.key v-bindslotProps/slot/template/templatetemplatev-for(slot, name) in item.formItemProps?.slots || {}#[name]slotProps:key${item.field}_${name}component :isslot v-bindslotProps/component/templatetemplate v-ifitem.slotslot :nameitem.slot v-bindformModel/slot/templatetemplate v-elsespan v-ifitem.loadingLoadingOutlined stylemargin-right: 4px /数据加载中.../spancomponentv-else:iscomponentsMap[item.component]v-binditem.componentPropsv-model:valueformModel[item.field]!-- 表单项组件插槽, 注意优先级组件componentProps.slots componentPropsSlots--templatev-forslot in componentPropsSlots#[slot.name]slotProps:keyslot.keytemplate v-ifslot.field item.fieldslot :nameslot.key v-bindslotProps/slot/template/templatetemplatev-for(slot, name) in item.componentProps?.slots || {}#[name]slotProps:key${item.field}_componentProps_${name}!-- 这里是关键 渲染slot --component :isslot v-bindslotProps/component/template/component/template/a-form-item/a-form/div /templatescript setup import { ref, watch, onMounted, computed, useSlots } from vue; import { componentsMap, defaultComponentProps } from ./config.js; import { LoadingOutlined } from ant-design/icons-vue; import dayjs from dayjs; const props defineProps({// 表单项配置schema: {type: Array,default: () [],},// 表单model配置一般用于默认值、回显数据model: {type: Object,default: () ({}),},// 组件属性配置componentProps: {type: Object,default: () ({}),}, });const slots useSlots();// 表单formItem slots const formItemPropsSlots ref([]);// 表单项组件slots const componentPropsSlots ref([]);// 用于获取componentProps、formItemProps插槽 const createPropsSlots (type) {// 对象转数组, 这里表单项slots规则为 对应的filed -type- slot名称,可自行定义规则对应字段匹配上即可const slotsArr Object.entries(slots);return slotsArr.filter((x) x[0].indexOf(type) ! -1).map((x) {const slotParams x[0].split(-);return {key: x[0],value: x[1],name: slotParams[2],field: slotParams[0],};}); }; const createSlots () {formItemPropsSlots.value createPropsSlots(formItemProps);componentPropsSlots.value createPropsSlots(componentProps); };const formRef ref(null);const formSchema ref([]); const formModel ref({});// 组件placeholder const getPlaceholder (x) {let placeholder ;switch (x.component) {case Text:case Textarea:placeholder 请输入${x.label};break;case RangePicker:placeholder [开始时间, 结束时间];break;default:placeholder 请选择${x.label};break;}return placeholder; };// 组件属性componentProps, 注意优先级组件自己配置的componentProps props.componentProps config.js中的componentProps const getComponentProps (x) {if (!x?.componentProps) x.componentProps {};// 使得外层可以直接配置optionsif (x.hasOwnProperty(options) x.options) {x.componentProps.options [];const isFunction typeof x.options function;const isArray Array.isArray(x.options);if (isFunction || isArray) {// 函数时先赋值空数组x.componentProps.options isFunction ? [] : x.options;}}return {placeholder: x?.componentProps?.placeholder ?? getPlaceholder(x),...(defaultComponentProps[x.component] || {}), // config.js带过来的基础componentProps默认配置...(props.componentProps[x.component] || {}), // props传进来的组件componentProps配置...x.componentProps, // 组件自身的componentProps}; };// 表单属性formItemProps const getFormItemProps (x) {let result { ...(x.formItemProps || {}) };// 使得外层可以直接配置required必填项if (x.hasOwnProperty(required) x.required) {result.rules [...(x?.formItemProps?.rules || []),{required: true,message: getPlaceholder(x),trigger: blur,},];}return result; };// 各组件为空时的默认值 const getDefaultEmptyValue (x) {let defaultEmptyValue ;switch (x.component) {case Text:case Textarea:defaultEmptyValue ;break;case Select:defaultEmptyValue [tag, multiple].includes(x?.componentProps?.mode)? []: undefined;case Cascader:defaultEmptyValue x?.value?.length ? x.value : [];default:defaultEmptyValue undefined;break;}return defaultEmptyValue; };// 格式化各组件值 const getValue (x) {let formatValue x.value;if (!!x.value) {switch (x.component) {case DatePicker:formatValue dayjs(x.value, YYYY-MM-DD);break;}}return formatValue; };const getSchemaConfig (x) {return {...x,componentProps: getComponentProps(x),formItemProps: getFormItemProps(x),value: x.value ?? getDefaultEmptyValue(x),label:x.formItemProps?.slots?.label ||formItemPropsSlots.value.find((y) y.field x.field)?.field? undefined: x.label,}; };const setFormModel () {formModel.value formSchema.value.reduce((pre, cur) {if (!pre[cur.field]) {// 表单初始数据(默认值)pre[cur.field] getValue(cur);return pre;}}, {}); };// 表单初始化 const initForm () {formSchema.value props.schema.map((x) getSchemaConfig(x));// model初始数据setFormModel();// options-获取异步数据formSchema.value.forEach(async (x) {if (x.options typeof x.options function) {x.loading true;x.componentProps.options await x.options(formModel.value);x.loading false;}}); };onMounted(() {createSlots();initForm();watch(() props.model,(newVal) {// 重新赋值给formSchemaformSchema.value.forEach((x) {for (const key in newVal) {if (x.field key) {x.value newVal[key];}}});setFormModel();},{immediate: true,deep: true,}); });const hasLoadingSchema computed(() formSchema.value.some((x) x.loading) );// 表单验证 const validateFields () {if (hasLoadingSchema.value) {console.log(正在加载表单项数据...);return;}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使用动态表单组件 templatediv stylepadding: 200pxDynamicFormrefformRef:schemaschema:modelmodel:labelCol{ span: 4 }:wrapperCol{ span: 20 }template #country-formItemProps-labelspan stylecolor: green国家/span/template!-- 表单项field为name的slotcomponentProps配置的slot优先级高于此处 --template #name-componentProps-addonAfterspan我是slot/span/templatetemplate #country-componentProps-suffixIconspan我也是slot/span/templatetemplate #someComponentXformModeldivBellFilled stylecolor: red /我是特殊的某某组件/divdiv表单信息:{{ formModel }}/div/template/DynamicFormdiv styledisplay: flex; justify-content: centera-button clickhandleReset(true)重置(全部清空)/a-buttona-button stylemargin-left: 50px clickhandleReset(false)重置/a-buttona-button typeprimary stylemargin-left: 50px clickhandleSubmit提交/a-button/div/div /templatescript langjsx setup import DynamicForm from /components/form/dynamic-form.vue; import { ref, reactive } from vue; import dayjs from dayjs; import { getRemoteData } from /common/utils; import { UserOutlined, BellFilled } from ant-design/icons-vue; const formRef ref(null);const schema ref([{label: 姓名,field: name,component: Text,required: true,componentProps: {slots: {addonAfter: () UserOutlined /,},},},{label: 性别,field: sex,component: Radio,options: [{ value: 1, label: 男 },{ value: 2, label: 女 },{ value: 3, label: 保密 },],value: 1,required: true,formItemProps: {slots: {label: () div stylecolor: blue性别/div}}},{label: 生日,field: birthday,component: DatePicker,required: true,},{label: 兴趣,field: hobby,component: Checkbox,options: async () {// 后台返回的数据listconst list [{ value: 1, label: 足球 },{ value: 2, label: 篮球 },{ value: 3, label: 排球 },];return await getRemoteData(list);},},{label: 国家,field: country,component: Select,options: [{ value: 1, label: 中国 },{ value: 2, label: 美国 },{ value: 3, label: 俄罗斯 },],},{label: 简介,field: desc,component: Textarea,},{label: 插槽组件X,field: someComponentX,slot: someComponentX,}, ]); const model reactive({ name: 百里守约, someComponentB: ok }); // 提交 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效果图 注意这里使用了jsx需要安装相关插件(本人用的前端构建工具是vite) 安装插件 npm install vitejs/plugin-vue-jsx --save在vite.config.js配置该插件
http://www.zqtcl.cn/news/291500/

相关文章:

  • 江苏丹阳建设公司网站做网站中的剪辑图片
  • 纯静态网站怎样广州工程造价信息网
  • 为什么网页不能打开建设银行网站企业网站开发综合实训
  • 企业网站制作 深圳网站建站行业公司主页建设
  • 外汇直播网站建设开发做网站空间商需要办什么手续
  • 源码哥网站的模板皮肤病在线咨询医生免费咨询
  • 温岭市市住房和城乡建设规划局网站附近的电脑培训班在哪里
  • 网站备案百度站长提交减肥网站源码
  • 网站添加文章机械代加工厂家
  • 学做各种糕点的网站cn网站建设多少钱
  • 首页网站关键词优化教程如何查询网站点击率
  • 文章类型的网站模版北京朝阳区房价2023年最新房价
  • wap网站发布注销主体和注销网站
  • 微信小程序 做网站满足客户的分销管理系统
  • 高佣联盟做成网站怎么做wordpress 更新版本
  • 杭州营销网站建设公司成都网站排名优化报价
  • 网站建设设计哪家好太原新建火车站
  • 医疗网站建设信息cps推广平台有哪些
  • rp怎么做网站备案 添加网站
  • 汕尾手机网站设计淘宝客做网站怎么做
  • 营口公司网站建设网站百度seo关键词优化
  • 网站开发命名规范汉中网站制作
  • 嘉定网站建设公司泗水做网站ys178
  • 邯郸网站设计招聘网齐家网和土巴兔装修哪家好
  • 京东网站推广方式jquery网页设计成品
  • 做本地网站卖四川省建设科技协会网站首页
  • 注册网站引流wordpress5.0.2图集怎么发布
  • 360产品展示网站哈尔滨个人建站模板
  • 怎么做网站的浏览量陕西省住房和建设厅官方网站
  • 上海网站 备案查询平面设计接单网站有哪些