有了域名怎么建设网站,外贸网站响应式,推销网站话术,wordpress acg风格有自动解析表单的vue组件如下#xff0c;其原理是调用一个配置表单定义的接口#xff0c;然后再调用获取表单配置的接口并将配置的数据覆盖表单的默认值。其中el-switch的配置值没有覆盖默认值#xff0c;分析其原因。 主页面如下#xff1a; template div cla…有自动解析表单的vue组件如下其原理是调用一个配置表单定义的接口然后再调用获取表单配置的接口并将配置的数据覆盖表单的默认值。其中el-switch的配置值没有覆盖默认值分析其原因。 主页面如下 template div classdivBox el-card classbox-card el-tabs v-modelactiveNamel1 tab-clickhandleTabClick v-loadingloading v-ifcheckPermi([admin:system:config:info]) el-tab-pane v-fortab,index in treeList :keyindex :labeltab.name :nametab.id.toString() template el-tabs v-iftab.child.length 0 v-modelactiveNamel2 typeborder-card tab-clickhandleItemTabClick el-tab-pane v-fortabItem,itemIndex in tab.child :keyitemIndex :labeltabItem.name :nametabItem.extra parser v-ifformConfChild.render :is-editformConfChild.isEdit :form-confformConfChild.content :form-edit-datacurrentEditData submithandlerSubmit / /el-tab-pane /el-tabs span v-else parser v-ifformConf.render :is-editformConf.isEdit :form-confformConf.content :form-edit-datacurrentEditData submithandlerSubmit / /span /template /el-tab-pane /el-tabs /el-card /div /template script import parser from /components/FormGenerator/components/parser/Parser import * as categoryApi from /api/categoryApi.js import * as selfUtil from /utils/XMutil.js import * as systemFormConfigApi from /api/systemFormConfig.js import * as systemSettingApi from /api/systemSetting.js import * as systemConfigApi from /api/systemConfig.js import Template from /views/appSetting/wxAccount/wxTemplate/index; import {beautifierConf} from /components/FormGenerator/utils; import { checkPermi } from /utils/permission; // 权限判断函数 import {Debounce} from /utils/validate export default { // name: index, components: {Template, parser }, data() { return { loading: false, formConf: { content: { fields: [] }, id: null, render: false, isEdit: false }, formConfChild: { content: { fields: [] }, id: null, render: false, isEdit: false }, activeNamel1: null, activeNamel2: ,//针对文件特殊处理 treeList: [], editDataChild: {}, isCreate: 0, currentEditId: null, currentEditData: null, currentSelectedUploadFlag:null, } }, mounted() { this.handlerGetTreeList() this.getCurrentUploadSelectedFlag() }, methods: { checkPermi, handleTabClick(tab) { this.activeNamel2 tab.$children[0].panes[0].name; this.handlerGetLevel2FormConfig(this.activeNamel2); }, handlerGetLevel1FormConfig(id) { const formPram { id: id } this.currentEditId id this.formConf.content { fields: [] } this.formConf.render false this.loading true systemFormConfigApi.getFormConfigInfo(formPram).then(data { const { id, name, info, content } data this.formConf.content JSON.parse(content) this.formConf.id id this.handlerGetSettingInfo(id, 1) this.loading false }).catch(() { this.loading false }) }, handleItemTabClick(tab, event) { //这里对tabstab.name和radioid做了兼容 let _id tab.name ? tab.name : tab if(!_id) return this.$message.error(表单配置不正确请关联正确表单后使用) this.handlerGetLevel2FormConfig(_id) }, handlerGetLevel2FormConfig(id) { const formPram { id: id } this.currentEditId id this.formConfChild.content { fields: [] } this.formConfChild.render false this.loading true systemFormConfigApi.getFormConfigInfo(formPram).then(data { const { id, name, info, content } data this.formConfChild.content JSON.parse(content) this.formConfChild.id id this.handlerGetSettingInfo(id, 2) this.loading false }).catch(() { this.loading false }) }, handlerGetSettingInfo(id, level) { systemSettingApi.systemConfigInfo({ id: id }).then(data { this.currentEditData data if (level 1) { this.formConf.isEdit this.currentEditData ! null this.formConf.render true } else { this.formConfChild.isEdit this.currentEditData ! null this.formConfChild.render true } }) }, handlerSubmit:Debounce(function(formValue) { this.handlerSave(formValue) }), handlerSave(formValue) { const _pram this.buildFormPram(formValue) let _formId 0 systemSettingApi.systemConfigSave(_pram).then(data { this.$message.success(添加数据成功) }) }, handlerGetTreeList() { const _pram { type: this.$constants.categoryType[5].value, status: 1 } this.loading true categoryApi.treeCategroy(_pram).then(data { this.treeList this.handleAddArrt(data) if (this.treeList.length 0) this.activeNamel1 this.treeList[0].id.toString(); if (this.treeList.length 0 this.treeList[0].child.length 0) { this.activeNamel2 this.treeList[0].child[0].extra } if (this.activeNamel2) { this.handlerGetLevel2FormConfig(this.treeList[0].child[0].extra) } // else { // this.handlerGetLevel1FormConfig(this.treeList[0].extra) //} this.loading false }).catch(() { this.loading false }) }, handleAddArrt(treeData) { // let _result this.addTreeListLabel(treeData) const _result selfUtil.addTreeListLabel(treeData) return _result }, buildFormPram(formValue) { const _pram { fields: [], id: this.currentEditId, sort: 0, // 参数暂时无用 status: true // 参数暂时无用 } const _fields [] Object.keys(formValue).forEach((key) { _fields.push({ name: key, title: key, value: formValue[key] }) }) _pram.fields _fields return _pram }, getCurrentUploadSelectedFlag(){ systemConfigApi.configGetUniq({key:uploadType}).then(data { this.currentSelectedUploadFlag parseInt(data) }) } } } /script style scoped /style 获取表单定义的接口及报文如下 http://127.0.0.1:8080/api/admin/system/form/temp/info?id77temp1739687295 { code: 200, message: 操作成功, data: { id: 77, name: 商城基础配置, info: 商城配置-商城基础配置, content: {\formRef\:\elForm\,\formModel\:\formData\,\size\:\medium\,\labelPosition\:\right\,\labelWidth\:300,\formRules\:\rules\,\gutter\:15,\disabled\:false,\span\:24,\formBtns\:true,\fields\:[{\__config__\:{\label\:\商品捐赠是否开启\,\tag\:\el-switch\,\tagIcon\:\switch\,\defaultValue\:true,\span\:24,\showLabel\:true,\labelWidth\:null,\layout\:\colFormItem\,\required\:true,\tips\:false,\tipsDesc\:\\,\tipsIsLink\:false,\tipsLink\:\\,\regList\:[],\changeTag\:true,\document\:\Element - The worlds most popular Vue UI framework \,\formId\:102,\renderKey\:1738534828949},\style\:{},\disabled\:false,\active-text\:\\,\inactive-text\:\\,\active-color\:null,\inactive-color\:null,\active-value\:true,\inactive-value\:false,\__vModel__\:\donation\},{\__config__\:{\label\:\商品捐赠比例设置\,\tag\:\el-input-number\,\tagIcon\:\number\,\defaultValue\:19,\span\:24,\showLabel\:true,\layout\:\colFormItem\,\labelWidth\:\\,\required\:true,\tips\:false,\tipsDesc\:\\,\tipsIsLink\:false,\tipsLink\:\\,\regList\:[],\changeTag\:true,\document\:\Element - The worlds most popular Vue UI framework \,\formId\:103,\renderKey\:1738534896059},\disabled\:false,\min\:0,\max\:100,\step\:1,\show-stops\:false,\range\:false,\__vModel__\:\donation_rate\},{\__config__\:{\label\:\警戒库存\,\showLabel\:true,\changeTag\:true,\labelWidth\:300,\tag\:\el-input-number\,\tagIcon\:\number\,\span\:24,\layout\:\colFormItem\,\required\:true,\regList\:[],\document\:\Element - The worlds most popular Vue UI framework \,\formId\:102,\renderKey\:1590032029141,\defaultValue\:2,\tips\:false},\placeholder\:\警戒库存\,\step\:1,\step-strictly\:false,\controls-position\:\\,\disabled\:false,\__vModel__\:\store_stock\,\max\:99999,\min\:0},{\__config__\:{\label\:\退货理由\,\labelWidth\:300,\showLabel\:true,\tag\:\el-input\,\tagIcon\:\textarea\,\required\:true,\layout\:\colFormItem\,\span\:24,\regList\:[],\changeTag\:true,\document\:\Element - The worlds most popular Vue UI framework \,\formId\:103,\renderKey\:1590032054065,\defaultValue\:\收货地址填错了 与描述不符 信息填错了重新拍 收到商品损坏了 未按预定时间发货 其它原因\,\tips\:false},\type\:\textarea\,\placeholder\:\请填写退货理由退货理由\,\autosize\:{\minRows\:4,\maxRows\:4},\style\:{\width\:\100%\},\maxlength\:null,\show-word-limit\:false,\readonly\:false,\disabled\:false,\__vModel__\:\stor_reason\},{\__config__\:{\label\:\移动端顶部logo图标(127*45)\,\tag\:\self-upload\,\tagIcon\:\upload\,\layout\:\colFormItem\,\defaultValue\:null,\showLabel\:true,\labelWidth\:300,\required\:true,\span\:24,\showTip\:false,\buttonText\:\点击上传\,\regList\:[],\changeTag\:true,\fileSize\:2,\sizeUnit\:\MB\,\document\:\Element - The worlds most popular Vue UI framework \,\formId\:124,\renderKey\:1595659136385,\tips\:false},\__slot__\:{\list-type\:true},\action\:\https://jsonplaceholder.typicode.com/posts/ \,\disabled\:true,\accept\:\\,\name\:\file\,\auto-upload\:true,\list-type\:\text\,\multiple\:false,\__vModel__\:\mobile_top_logo\},{\__config__\:{\label\:\移动端登录页logo(90x90)\,\tag\:\self-upload\,\tagIcon\:\upload\,\layout\:\colFormItem\,\defaultValue\:null,\showLabel\:true,\labelWidth\:300,\required\:true,\span\:24,\showTip\:false,\buttonText\:\点击上传\,\regList\:[],\changeTag\:true,\fileSize\:2,\sizeUnit\:\MB\,\document\:\Element - The worlds most popular Vue UI framework \,\formId\:102,\renderKey\:1629094835969,\tips\:false},\__slot__\:{\list-type\:true},\action\:\https://jsonplaceholder.typicode.com/posts/ \,\disabled\:true,\accept\:\\,\name\:\file\,\auto-upload\:true,\list-type\:\text\,\multiple\:false,\__vModel__\:\mobile_login_logo\},{\__config__\:{\label\:\普通商品未支付取消订单时间(单位:小时)\,\showLabel\:true,\changeTag\:true,\labelWidth\:300,\tag\:\el-input-number\,\tagIcon\:\number\,\span\:24,\layout\:\colFormItem\,\required\:true,\regList\:[],\document\:\Element - The worlds most popular Vue UI framework \,\formId\:105,\renderKey\:1590032096481,\defaultValue\:2,\tips\:false},\placeholder\:\普通商品未支付取消订单时间(单位:小时)\,\step\:1,\step-strictly\:false,\controls-position\:\\,\disabled\:false,\__vModel__\:\order_cancel_time\,\max\:99999,\min\:0,\precision\:0},{\__config__\:{\label\:\活动商品未支付取消订单时间(单位小时)\,\showLabel\:true,\changeTag\:true,\labelWidth\:300,\tag\:\el-input-number\,\tagIcon\:\number\,\span\:24,\layout\:\colFormItem\,\required\:true,\regList\:[],\document\:\Element - The worlds most popular Vue UI framework \,\formId\:106,\renderKey\:1590032112020,\defaultValue\:2,\tips\:false},\placeholder\:\活动商品未支付取消订单时间(单位:小时)\,\step\:1,\step-strictly\:false,\controls-position\:\\,\disabled\:false,\__vModel__\:\order_activity_time\,\max\:99999,\min\:0,\precision\:0},{\__config__\:{\label\:\网站名称\,\labelWidth\:null,\showLabel\:true,\changeTag\:true,\tag\:\el-input\,\tagIcon\:\input\,\required\:true,\layout\:\colFormItem\,\span\:24,\document\:\Element - The worlds most popular Vue UI framework \,\regList\:[],\formId\:101,\renderKey\:1629086692739,\tips\:false},\__slot__\:{\prepend\:\\,\append\:\\},\placeholder\:\请输入网站名称\,\style\:{\width\:\100%\},\clearable\:true,\prefix-icon\:\\,\suffix-icon\:\\,\maxlength\:null,\show-word-limit\:false,\readonly\:false,\disabled\:false,\__vModel__\:\site_name\},{\__config__\:{\label\:\网站地址\,\labelWidth\:null,\showLabel\:true,\changeTag\:true,\tag\:\el-input\,\tagIcon\:\input\,\required\:true,\layout\:\colFormItem\,\span\:24,\document\:\Element - The worlds most popular Vue UI framework \,\regList\:[],\formId\:102,\renderKey\:1629086763346,\tips\:false},\__slot__\:{\prepend\:\\,\append\:\\},\placeholder\:\webSiet网站地址网站地址网站地址\,\style\:{\width\:\100%\},\clearable\:true,\prefix-icon\:\\,\suffix-icon\:\\,\maxlength\:null,\show-word-limit\:true,\readonly\:false,\disabled\:false,\__vModel__\:\site_url\},{\__config__\:{\label\:\SEO标题\,\labelWidth\:null,\showLabel\:true,\changeTag\:true,\tag\:\el-input\,\tagIcon\:\input\,\required\:true,\layout\:\colFormItem\,\span\:24,\document\:\Element - The worlds most popular Vue UI framework \,\regList\:[],\formId\:102,\renderKey\:1629087874359,\tips\:false},\__slot__\:{\prepend\:\\,\append\:\\},\placeholder\:\请输入SEO标题\,\style\:{\width\:\100%\},\clearable\:true,\prefix-icon\:\\,\suffix-icon\:\\,\maxlength\:null,\show-word-limit\:false,\readonly\:false,\disabled\:false,\__vModel__\:\seo_title\},{\__config__\:{\label\:\新闻幻灯片数量上限\,\showLabel\:true,\changeTag\:true,\labelWidth\:null,\tag\:\el-input-number\,\tagIcon\:\number\,\span\:24,\layout\:\colFormItem\,\required\:true,\regList\:[],\document\:\Element - The worlds most popular Vue UI framework \,\formId\:101,\renderKey\:1629087608122,\defaultValue\:1,\tips\:false},\placeholder\:\新闻幻灯片数量上限新闻幻灯片数量上限新闻幻灯片数量上限新闻幻灯片数量上限\,\step\:1,\step-strictly\:false,\controls-position\:\\,\disabled\:false,\__vModel__\:\news_slides_limit\,\min\:1,\max\:3},{\__config__\:{\label\:\移动商城api\,\labelWidth\:null,\showLabel\:true,\changeTag\:true,\tag\:\el-input\,\tagIcon\:\input\,\required\:true,\layout\:\colFormItem\,\span\:24,\document\:\Element - The worlds most popular Vue UI framework \,\regList\:[],\formId\:101,\renderKey\:1639127436585,\tips\:false},\__slot__\:{\prepend\:\\,\append\:\\},\placeholder\:\移动商城api_小程序源码下载前必须配置\,\style\:{\width\:\100%\},\clearable\:true,\prefix-icon\:\\,\suffix-icon\:\\,\maxlength\:null,\show-word-limit\:true,\readonly\:false,\disabled\:false,\__vModel__\:\front_api_url\}]}, createTime: 2020-05-16 02:19:37, updateTime: 2025-02-16 14:27:39 } } 获取配置的接口及报文如下 api/admin/system/config/info?formId77temp1739687295 { code: 200, message: 操作成功, data: { news_slides_limit: 3, mobile_login_logo: http://127.0.0.1:8080/yczjimage/public/operation/2025/02/02/71622984926b44a485fc962f153804ecddvigsrbm3.jpg , donation_rate: 19, store_stock: 22, order_cancel_time: 1, mobile_top_logo: http://127.0.0.1:8080/yczjimage/public/maintain/2021/12/25/54d7a09f1dee463fa12ec01c02294b31z66prnux9w.png , seo_title: 一码秦川, site_name: 一马秦川, order_activity_time: 1, stor_reason: 收货地址填错了\n与描述不符 \n信息填错了重新拍 \n收到商品损坏了 \n未按预定时间发货 \n其它原因\n测试111, site_url: https://app.net , donation: true, id: 77, front_api_url: http://127.0.0.1:8081 } } 表单组件转化的Vue组件如下 script import render from /components/FormGenerator/components/render/render.js const ruleTrigger { el-input: blur, el-input-number: blur, el-switch: change, el-select: change, el-radio-group: change, el-checkbox-group: change, el-cascader: change, el-time-picker: change, el-date-picker: change, el-rate: change } function renderFrom(h) { const { formConfCopy } this return ( el-row gutter{formConfCopy.gutter} el-form size{formConfCopy.size} label-position{formConfCopy.labelPosition} disabled{formConfCopy.disabled} label-width{${formConfCopy.labelWidth}px} ref{formConfCopy.formRef} // model不能直接赋值 https://github.com/vuejs/jsx/issues/49#issuecomment-472013664 props{{ model: this[formConfCopy.formModel] }} rules{this[formConfCopy.formRules]} {renderFormItem.call(this, h, formConfCopy.fields)} {formConfCopy.formBtns formBtns.call(this, h)} /el-form /el-row ) } function formBtns(h) { return el-col el-form-item sizemini el-button typeprimary onClick{this.submitForm}提交/el-button /el-form-item /el-col } function renderFormItem(h, elementList) { return elementList.map(scheme { const config scheme.__config__ const layout layouts[config.layout] if (layout) { return layout.call(this, h, scheme) } throw new Error(没有与${config.layout}匹配的layout) }) } function renderChildren(h, scheme) { const config scheme.__config__ if (!Array.isArray(config.children)) return null return renderFormItem.call(this, h, config.children) } function setValue(event, config, scheme) { this.$set(config, defaultValue, event) this.$set(this[this.formConf.formModel], scheme.__vModel__, event) } function buildListeners(scheme) { const config scheme.__config__ const methods this.formConf.__methods__ || {} const listeners {} // 给__methods__中的方法绑定this和event Object.keys(methods).forEach(key { listeners[key] event methods[key].call(this, event) }) // 响应 render.js 中的 vModel $emit(input, val) listeners.input event setValue.call(this, event, config, scheme) return listeners } const layouts { colFormItem(h, scheme) { const config scheme.__config__ const listeners buildListeners.call(this, scheme) let labelWidth config.labelWidth ? ${config.labelWidth}px : null if (config.showLabel false) labelWidth 0 if(config.tips !config.tipsIsLink){ return ( el-col span{config.span} el-form-item label-width{labelWidth} prop{scheme.__vModel__} label{config.showLabel ? config.label : } el-tooltip effectdark placementtop-start stylepadding:10px 5px 0 0; i classel-icon-warning-outline / div slotcontent stylemax-width:400px;{config.tipsDesc}/div /el-tooltip render conf{scheme} {...{ on: listeners }} / /el-form-item /el-col ) }else if(config.tips config.tipsIsLink){ return ( el-col span{config.span} el-form-item label-width{labelWidth} prop{scheme.__vModel__} label{config.showLabel ? config.label : } el-tooltip effectdark placementtop-start stylepadding:10px 5px 0 0; i classel-icon-warning-outline / div slotcontent stylemax-width:400px; a href{config.tipsLink} target_blank{config.tipsDesc}/a /div /el-tooltip render conf{scheme} {...{ on: listeners }} / /el-form-item /el-col ) }else{ return ( el-col span{config.span} el-form-item label-width{labelWidth} prop{scheme.__vModel__} label{config.showLabel ? config.label : } render conf{scheme} {...{ on: listeners }} / /el-form-item /el-col ) } }, rowFormItem(h, scheme) { let child renderChildren.apply(this, arguments) if (scheme.type flex) { child el-row type{scheme.type} justify{scheme.justify} align{scheme.align} {child} /el-row } return ( el-col span{scheme.span} el-row gutter{scheme.gutter} {child} /el-row /el-col ) } } export default { components: { render }, props: { formConf: { type: Object, required: true }, formEditData: { type: Object }, isEdit: { type: Boolean, default: false } }, data() { if (this.isEdit) { // 初始化待编辑数据 this.formConf.fields.forEach(conf { // 设置现有的数据 const hasValueForEdit this.formEditData[conf.__vModel__] if(hasValueForEdit){ conf.__config__.defaultValue hasValueForEdit } // 如果是el-select标签 判断数据后改变实现默认选中效果 if(conf.__config__.tag el-select || conf.__config__.tag el-radio-group){ const perValue conf.__slot__.options.filter(option option.value this.formEditData[conf.__vModel__]) if(perValue.length 0){ // 有表单数据 conf.__config__.defaultValue perValue[0].value } } }) } const data { formConfCopy: JSON.parse(JSON.stringify(this.formConf)), [this.formConf.formModel]: {}, [this.formConf.formRules]: {} } this.initFormData(data.formConfCopy.fields, data[this.formConf.formModel]) this.buildRules(data.formConfCopy.fields, data[this.formConf.formRules]) return data }, methods: { initFormData(componentList, formData) { componentList.forEach(cur { const config cur.__config__ if (cur.__vModel__) formData[cur.__vModel__] config.defaultValue if (config.children) this.initFormData(config.children, formData) }) }, buildRules(componentList, rules) { componentList.forEach(cur { const config cur.__config__ if (Array.isArray(config.regList)) { if (config.required) { const required { required: config.required, message: cur.placeholder } if (Array.isArray(config.defaultValue)) { required.type array required.message 请至少选择一个${config.label} } required.message undefined (required.message ${config.label}不能为空) config.regList.push(required) } rules[cur.__vModel__] config.regList.map(item { item.pattern (item.pattern eval(item.pattern)) item.trigger ruleTrigger ruleTrigger[config.tag] return item }) } if (config.children) this.buildRules(config.children, rules) }) }, resetForm() { this.$emit(resetForm, this.formConf) this.formConfCopy JSON.parse(JSON.stringify(this.formConf)) this.$refs[this.formConf.formRef].resetFields() }, submitForm() { this.$refs[this.formConf.formRef].validate(valid { if (!valid) return false // 触发sumit事件 this.$emit(submit, this[this.formConf.formModel]) return true }) } }, render(h) { return renderFrom.call(this, h) } } /script 组件渲染的js如下 function vModel(self, dataObject, defaultValue) { dataObject.props.value defaultValue dataObject.on.input val { self.$emit(input, val) } } const componentChild {} /** * 将./slots中的文件挂载到对象componentChild上 * 文件名为key对应JSON配置中的__config__.tag * 文件内容为value解析JSON配置中的__slot__ */ const slotsFiles require.context(./slots, true, /\.js$/) const keys slotsFiles.keys() || [] keys.forEach(key { const tag key.replace(/^\.\/(.*)\.\w$/, $1) const value slotsFiles(key).default componentChild[tag] value }) export default { render(h) { const dataObject { attrs: {}, props: {}, on: {}, style: {} } const confClone JSON.parse(JSON.stringify(this.conf)) const children [] const childObjs componentChild[confClone.__config__.tag] if (childObjs) { Object.keys(childObjs).forEach(key { const childFunc childObjs[key] if (confClone.__slot__ confClone.__slot__[key]) { children.push(childFunc(h, confClone, key)) } }) } Object.keys(confClone).forEach(key { const val confClone[key] if (key __vModel__) { vModel(this, dataObject, confClone.__config__.defaultValue) } else if (dataObject[key]) { console.log(__vModel__: ${JSON.stringify(dataObject)}) dataObject[key] { ...dataObject[key], ...val } } else { dataObject.attrs[key] val } }) delete dataObject.attrs.__config__ delete dataObject.attrs.__slot__ return h(this.conf.__config__.tag, dataObject, children) }, props: [conf] } 从代码和接口报文来看el-switch 的配置值没有覆盖默认值的原因可能如下
1. 数据绑定问题
在 parser 组件的 data 中formConfCopy 是通过 JSON.parse(JSON.stringify(this.formConf)) 深拷贝而来。而 formConf 是通过接口获取的表单定义数据其中 el-switch 的配置如下
JSONCopy
{__config__: {label: 商品捐赠是否开启,tag: el-switch,tagIcon: switch,defaultValue: true,span: 24,showLabel: true,labelWidth: null,layout: colFormItem,required: true,tips: false,tipsDesc: ,tipsIsLink: false,tipsLink: ,regList: [],changeTag: true,document: https://element.eleme.cn/#/zh-CN/component/switch,formId: 102,renderKey: 1738534828949},style: {},disabled: false,active-text: ,inactive-text: ,active-color: null,inactive-color: null,active-value: true,inactive-value: false,__vModel__: donation
}
在 parser 组件的 data 初始化时formConfCopy 的 fields 中的每个配置项的 __config__.defaultValue 会被赋值给 formData 对应的字段通过 initFormData 方法。但是el-switch 的 __vModel__ 是 donation而接口返回的配置数据中 donation 的值是 true字符串而不是 true布尔值。
JSONCopy
donation: true
这可能导致 el-switch 的值没有正确绑定因为 el-switch 的 active-value 和 inactive-value 分别是 true 和 false布尔值而绑定的值是字符串 true类型不匹配。
2. 数据更新问题
在 parser 组件的 data 初始化时虽然会根据 formEditData 更新 formConfCopy.fields 中的 __config__.defaultValue但是 el-switch 的值没有正确更新。
在 parser 组件的 data 初始化代码中
JavaScriptCopy
if (this.isEdit) { // 初始化待编辑数据this.formConf.fields.forEach(conf {// 设置现有的数据const hasValueForEdit this.formEditData[conf.__vModel__]if(hasValueForEdit){conf.__config__.defaultValue hasValueForEdit}// 如果是el-select标签 判断数据后改变实现默认选中效果if(conf.__config__.tag el-select || conf.__config__.tag el-radio-group){const perValue conf.__slot__.options.filter(option option.value this.formEditData[conf.__vModel__])if(perValue.length 0){ // 有表单数据conf.__config__.defaultValue perValue[0].value}}})
}
这里只处理了 el-select 和 el-radio-group 的情况没有处理 el-switch 的情况。因此el-switch 的值没有被正确更新。
3. 组件渲染问题
在组件渲染的 render.js 中vModel 函数会根据 __vModel__ 和 __config__.defaultValue 设置 dataObject.props.value并绑定 input 事件。
JavaScriptCopy
function vModel(self, dataObject, defaultValue) {dataObject.props.value defaultValuedataObject.on.input val {self.$emit(input, val)}
}
但是el-switch 的值是布尔值而绑定的值是字符串 true这可能导致 el-switch 的值没有正确渲染。
解决方法 修正接口返回的数据类型确保接口返回的 donation 的值是布尔值 true而不是字符串 true。 在 parser 组件中处理 el-switch 的值在 data 初始化时添加对 el-switch 的处理逻辑将字符串 true 转换为布尔值 true。
JavaScriptCopy
if (this.isEdit) { // 初始化待编辑数据this.formConf.fields.forEach(conf {// 设置现有的数据const hasValueForEdit this.formEditData[conf.__vModel__]if(hasValueForEdit){if(conf.__config__.tag el-switch){ // 处理 el-switch 的值conf.__config__.defaultValue hasValueForEdit true ? true : false}else{conf.__config__.defaultValue hasValueForEdit}}// 如果是el-select标签 判断数据后改变实现默认选中效果if(conf.__config__.tag el-select || conf.__config__.tag el-radio-group){const perValue conf.__slot__.options.filter(option option.value this.formEditData[conf.__vModel__])if(perValue.length 0){ // 有表单数据conf.__config__.defaultValue perValue[0].value}}})
} 在组件渲染的 render.js 中处理 el-switch 的值在 vModel 函数中添加对 el-switch 的处理逻辑将字符串 true 转换为布尔值 true。
JavaScriptCopy
function vModel(self, dataObject, defaultValue) {if(self.conf.__config__.tag el-switch){ // 处理 el-switch 的值dataObject.props.value defaultValue true ? true : false}else{dataObject.props.value defaultValue}dataObject.on.input val {self.$emit(input, val)}
}