diff --git a/dev_tools/formprops.js b/dev_tools/formprops.js new file mode 100644 index 0000000..3231f9f --- /dev/null +++ b/dev_tools/formprops.js @@ -0,0 +1,391 @@ +module.exports = { + labelCol: { span: 3, offset: 0 }, + labelAlign: 'right', + layout: 'horizontal', + size: 'default', + schemas: [ + { + key: '95b6f464a9604b238ef8722db5d4878c', + field: 'ziDuan16563', + label: '字段1', + type: 'input', + component: 'Input', + colProps: { span: 24 }, + defaultValue: '', + componentProps: { + width: '100%', + span: '', + defaultValue: '', + labelWidthMode: 'fix', + labelFixWidth: 120, + responsive: true, + respNewRow: false, + placeholder: '请输入字段1', + maxlength: null, + prefix: '', + suffix: '', + addonBefore: '', + addonAfter: '', + disabled: false, + allowClear: false, + showLabel: true, + required: false, + rules: [], + events: {}, + isSave: false, + isShow: true, + scan: false, + style: { width: '100%' }, + }, + }, + { + key: 'd7f295f12d2a4ec7863099d875b95515', + field: 'ziDuan28273', + label: '字段2', + type: 'input', + component: 'Input', + colProps: { span: 24 }, + defaultValue: '', + componentProps: { + width: '100%', + span: '', + defaultValue: '', + labelWidthMode: 'fix', + labelFixWidth: 120, + responsive: true, + respNewRow: false, + placeholder: '请输入字段2', + maxlength: null, + prefix: '', + suffix: '', + addonBefore: '', + addonAfter: '', + disabled: false, + allowClear: false, + showLabel: true, + required: false, + rules: [], + events: {}, + isSave: false, + isShow: true, + scan: false, + style: { width: '100%' }, + }, + }, + { + key: '37d86747f1e64aae874f13f29a5697f3', + field: 'ziDuan35193', + label: '字段3', + type: 'input', + component: 'Input', + colProps: { span: 24 }, + defaultValue: '', + componentProps: { + width: '100%', + span: '', + defaultValue: '', + labelWidthMode: 'fix', + labelFixWidth: 120, + responsive: true, + respNewRow: false, + placeholder: '请输入字段3', + maxlength: null, + prefix: '', + suffix: '', + addonBefore: '', + addonAfter: '', + disabled: false, + allowClear: false, + showLabel: true, + required: false, + rules: [], + events: {}, + isSave: false, + isShow: true, + scan: false, + respBreakLine: true, + style: { width: '100%' }, + }, + }, + { + key: 'fa04ee3d955a4659be18331be1819601', + field: 'ziDuan45516', + label: '字段4', + type: 'input', + component: 'Input', + colProps: { span: 24 }, + defaultValue: '', + componentProps: { + width: '100%', + span: '', + defaultValue: '', + labelWidthMode: 'fix', + labelFixWidth: 120, + responsive: true, + respNewRow: false, + placeholder: '请输入字段4', + maxlength: null, + prefix: '', + suffix: '', + addonBefore: '', + addonAfter: '', + disabled: false, + allowClear: false, + showLabel: true, + required: false, + rules: [], + events: {}, + isSave: false, + isShow: true, + scan: false, + style: { width: '100%' }, + }, + }, + { + key: '9dcd8c7ac1e54acd8cee285274b82b0d', + field: 'ziDuan55031', + label: '字段5', + type: 'input', + component: 'Input', + colProps: { span: 24 }, + defaultValue: '', + componentProps: { + width: '100%', + span: '', + defaultValue: '', + labelWidthMode: 'fix', + labelFixWidth: 120, + responsive: false, + respNewRow: false, + placeholder: '请输入字段5', + maxlength: null, + prefix: '', + suffix: '', + addonBefore: '', + addonAfter: '', + disabled: false, + allowClear: false, + showLabel: true, + required: false, + rules: [], + events: {}, + isSave: false, + isShow: true, + scan: false, + style: { width: '100%' }, + }, + }, + { + key: 'a4b8975a9b2f4fda84dbc88cdd2bcfb7', + field: 'jiLianBenTi7352', + label: '级联本体', + type: 'input', + component: 'Input', + colProps: { span: 24 }, + defaultValue: '', + componentProps: { + width: '100%', + span: '', + defaultValue: '', + labelWidthMode: 'fix', + labelFixWidth: 120, + responsive: true, + respNewRow: false, + placeholder: '请输入级联本体', + maxlength: null, + prefix: '', + suffix: '', + addonBefore: '', + addonAfter: '', + disabled: false, + allowClear: false, + showLabel: true, + required: false, + rules: [], + events: {}, + isSave: false, + isShow: true, + scan: false, + style: { width: '100%' }, + }, + }, + { + key: 'a2e8519113f844c3a0ae489b2c8a09d0', + field: 'jiLianWenZi5194', + label: '级联文字', + type: 'input', + component: 'Input', + colProps: { span: 24 }, + defaultValue: '', + componentProps: { + width: '100%', + span: '', + defaultValue: '', + labelWidthMode: 'fix', + labelFixWidth: 120, + responsive: false, + respNewRow: false, + placeholder: '请输入级联文字', + maxlength: null, + prefix: '', + suffix: '', + addonBefore: '', + addonAfter: '', + disabled: false, + allowClear: false, + showLabel: true, + required: false, + rules: [], + events: {}, + isSave: false, + isShow: true, + scan: false, + style: { width: '100%' }, + }, + }, + { + key: '506f9008790c4e72843910da7c36b2d8', + field: '', + label: '标题', + type: 'title', + component: 'Title', + colProps: { span: 24 }, + defaultValue: '明细表', + componentProps: { + defaultValue: '明细表', + color: '', + align: 'left', + fontSize: 18, + isShow: true, + style: {}, + }, + }, + { + key: '25a93adbfba647b2a5398221d2a35952', + label: '表格组件', + field: 'cascadeDemoChild5561List', + type: 'form', + component: 'SubForm', + required: true, + colProps: { span: 24 }, + componentProps: { + mainKey: 'cascadeDemoChild5561List', + columns: [ + { + key: 'af2057f5fa774ec29f91b2114c4af4f7', + title: '列1', + dataIndex: 'lie19747', + componentType: 'Input', + defaultValue: '', + componentProps: { + width: '100%', + span: '', + defaultValue: '', + labelWidthMode: 'fix', + labelFixWidth: 120, + responsive: false, + respNewRow: false, + placeholder: '请输入列1', + maxlength: null, + prefix: '', + suffix: '', + addonBefore: '', + addonAfter: '', + disabled: false, + allowClear: false, + showLabel: true, + required: false, + rules: [], + events: {}, + isSave: false, + isShow: true, + scan: false, + }, + }, + { + key: 'd02e0e1df55249e6a42964143f2d2b48', + title: '级联本体', + dataIndex: 'jiLianBenTi9627', + componentType: 'Input', + defaultValue: '', + componentProps: { + width: '100%', + span: '', + defaultValue: '', + labelWidthMode: 'fix', + labelFixWidth: 120, + responsive: false, + respNewRow: false, + placeholder: '请输入级联本体', + maxlength: null, + prefix: '', + suffix: '', + addonBefore: '', + addonAfter: '', + disabled: false, + allowClear: false, + showLabel: true, + required: false, + rules: [], + events: {}, + isSave: false, + isShow: true, + scan: false, + }, + }, + { + key: '07ea250f2eb84680a01692b078e1d1cc', + title: '级联文字', + dataIndex: 'jiLianWenZi9294', + componentType: 'Input', + defaultValue: '', + componentProps: { + width: '100%', + span: '', + defaultValue: '', + labelWidthMode: 'fix', + labelFixWidth: 120, + responsive: false, + respNewRow: false, + placeholder: '请输入级联文字', + maxlength: null, + prefix: '', + suffix: '', + addonBefore: '', + addonAfter: '', + disabled: false, + allowClear: false, + showLabel: true, + required: false, + rules: [], + events: {}, + isSave: false, + isShow: true, + scan: false, + }, + }, + { title: '操作', key: 'action', fixed: 'right', width: '50px' }, + ], + span: '24', + preloadType: 'api', + apiConfig: {}, + itemId: '', + dicOptions: [], + useSelectButton: false, + buttonName: '选择数据', + showLabel: false, + showComponentBorder: true, + showFormBorder: true, + showIndex: false, + isShow: true, + multipleHeads: [], + }, + }, + ], + showActionButtonGroup: false, + buttonLocation: 'center', + actionColOptions: { span: 24 }, + showResetButton: false, + showSubmitButton: false, + hiddenComponent: [], + }; \ No newline at end of file diff --git a/dev_tools/template_extend.js b/dev_tools/template_extend.js new file mode 100644 index 0000000..7a0f556 --- /dev/null +++ b/dev_tools/template_extend.js @@ -0,0 +1,24 @@ +const formProps = require('./formProps'); + +let tmpl = ''; + +// 用于将config的表单格式展开成字段,以便二开 +formProps.schemas.forEach((prop) => { + let schema = `schemaMap['${prop.key}']`; + tmpl += ` + + + + + `; +}); + +//write to file +const fs = require('fs'); + +fs.writeFile('./template.txt', tmpl, (err) => { + if (err) throw err; + console.log('The file has been saved!'); +}); diff --git a/docs/dev_readme.md b/docs/dev_readme.md index 42e35e7..f696825 100644 --- a/docs/dev_readme.md +++ b/docs/dev_readme.md @@ -76,83 +76,6 @@ onMounted(async () => { emits('form-mounted', formProps); // 补上这一句 }); ``` -## 如何自定义表单字段 -一般情况下,字段会和权限绑定,假设你已经解决了字段的权限问题(对于简单的数据结构,可以建一个纯文本字段,然后在前端换成自定义渲染的)。 - -首先我们定义一个组件,这里为了简单起见只用了一个文本框,一般情况下,你要实现v-model,同时接收disabled参数以处理只读模式。注意vue<3.4的版本并不支持defineModel。 -```vue - - - - -``` -然后在表单页面Form.vue中引入该字段 -```vue - - - -``` -这里需要注意的是,自定义字段中需要自行实现label部分,所以外层用了一个FormItem,如果你需要在表单中间独立成行,也可以去掉FormItem这层。 - -最后在config.ts中换掉字段的类型: -```javascript -export const formProps: FormProps = { - labelCol: { span: 3, offset: 0 }, - labelAlign: 'right', - layout: 'horizontal', - size: 'default', - schemas: [ - { - key: '783e504378024a2c9db35b9e741eb5c3', - field: 'chuChaDiDian3876', - label: '出差地点', - type: 'slot', // type和slotName需要换掉 - slotName: 'addr' // 和template中的插槽名字对应 - } - ] -}; -``` -## 如何自定义列表页字段 -列表页的字段定义比较简单,首先在columns中补充需要的列(或者替换已有的列),然后再bodyCell插槽里替换所需的部分接即可。 -```vue - -``` -注意,根据antd-vue的文档,bodyCell里除了要修改的列,不能写其他内容,否则会将内容覆盖到所有列上。 -## 如何在按钮栏中刚增加按钮 - - ## 如何修改选项卡标题 ```javascript import { useMultipleTabStore } from '/@/store/modules/multipleTab'; @@ -167,3 +90,179 @@ tabStore.changeTitle(fullPath, `选项卡标题`); // 顺便tabStore也支持关闭选项卡 tabStore.closeTab(currentRoute, router); ``` +## 如何进行表单二开 +首先,打开项目dev_tools/formprops.js,将其中的内容替换为模块config,注意nodejs不加参数必须用module.exports不能用export default写法。 + +然后执行template_extend.js,会在同目录生成template.txt,这个文件就是将config文件在第一层展开的模版内容。 + +接下来找到要二开的表单,在components目录里定义新建一个vue文件,然后用下面的内容初始化,这个文件实际上就是SimpleForm的继承,我们要用自己的模版覆盖掉原来的循环。由于不是每个字段都有dataIndex(如布局类、标题),使用数组展开在二次修改后会比较混乱,此处定义了映射表,可以通过key找到组件,同时简化了原来的两个函数。 +```vue + + + +``` +找到components目录下的Form.vue,用我们自己的表单替换掉原来的SimpleForm(假设我们的文件为CascadeDemoForm.vue): +```vue + +``` +展开后的文件和原有表单一致,每个字段都已经拆开,因此可以自由使用v-if/v-show等进行显隐控制,以及在字段之间插入内容、做自动计算等。 + +**注:该展开方法不能用Grid、Tab等布局嵌套,如果需要,建议自行写代码套容器,不要用编辑器自带的布局组件。** + +## 如何在表单二开中自定义布局 +```vue + + +``` +这段代码上的span就是控制字段占位的,满宽度位24,1/3为8,1/4为6,以此类推,我们强烈大家使用响应式布局,以免在屏幕过窄时影响显示效果。同样,响应式布局在编辑器里支持换行、独立成行。 + +如果在二开里要换行,可以用div包裹,也可以加一个空div强制换行 +```html +
+``` + +## 如何添加自定义校验 +可以在config.ts中定义,componentProps里默认有空的rules数组,可以自己添加,antd vue所有支持的校验都可以在这里使用。 +```javascript +{ + rules: [ + { + min: 10, + max: 30, + message: '这个长度在10-30之间' + } + ] +} +``` +## 如何设置字段联动 +编辑器中选择Api即可配置字段联动,只要在magic-api配置参数即可,参数值可以直接选择表单或者明细表字段。 + +选择字典没有效果。 + +## 如何在表单二开中定义字段 +下面的代码为一个支持多层加载的级联选择器,同时值和文字描述分开存储,不会在表单打开时加载数据: +```vue + + + + + + {{ formModel.jiLianWenZi5194 || '请选择' }} + + + +``` +这里特别注意下,因为cascade的值为数组,而数组在数据库是不能存储的,所以这里cascadeValue为数组值,a-input里存储的为逗号分开的id。 + +特别注意,FormItem在本框架里获取值依靠form的validate方法,因此FormItem里必须有**antd vue的表单元素**,如果为纯手动开发的组件,建议用一个a-input储存表单值。 + +脚本部分 +```vue + +``` diff --git a/src/components/Designer/src/components/componentProperty/PropertyOption.vue b/src/components/Designer/src/components/componentProperty/PropertyOption.vue index 475b0cb..c595d1e 100644 --- a/src/components/Designer/src/components/componentProperty/PropertyOption.vue +++ b/src/components/Designer/src/components/componentProperty/PropertyOption.vue @@ -59,6 +59,10 @@ + + + +