├── src ├── styles │ ├── utils │ │ ├── var │ │ │ └── index.less │ │ ├── index.less │ │ └── mixins │ │ │ └── index.less │ ├── fonts │ │ ├── iconfont.eot │ │ ├── iconfont.ttf │ │ ├── iconfont.woff │ │ ├── iconfont.woff2 │ │ ├── iconfont.css │ │ └── iconfont.svg │ └── components │ │ ├── json-editor.less │ │ ├── index.less │ │ ├── form-editor-item.less │ │ ├── form-editor.less │ │ └── form-schemer.less ├── scripts │ └── utils │ │ ├── bus.js │ │ └── helper.js └── components │ ├── form-schemer │ ├── rule-type-map.js │ ├── index.js │ ├── type-map.js │ ├── regexes.js │ ├── form-schemer.vue │ └── field-config.vue │ ├── form-editor │ ├── index.js │ └── form-editor.vue │ ├── json-editor │ ├── index.js │ └── json-editor.vue │ ├── form-editor-item │ ├── index.js │ └── types.js │ ├── render-cell.js │ ├── form-editor-draggable │ ├── index.js │ └── form-editor-draggable.vue │ ├── README.md │ └── index.js ├── images └── jg.png ├── .eslintignore ├── docs ├── README.md ├── .vuepress │ ├── theme │ │ ├── styles │ │ │ ├── toc.styl │ │ │ ├── wrapper.styl │ │ │ ├── config.styl │ │ │ ├── arrow.styl │ │ │ ├── custom-blocks.styl │ │ │ ├── mobile.styl │ │ │ ├── nprogress.styl │ │ │ ├── code.styl │ │ │ └── theme.styl │ │ ├── search.svg │ │ ├── NotFound.vue │ │ ├── DropdownTransition.vue │ │ ├── SidebarButton.vue │ │ ├── NavLink.vue │ │ ├── SidebarGroup.vue │ │ ├── SWUpdatePopup.vue │ │ ├── Sidebar.vue │ │ ├── SidebarLink.vue │ │ ├── Navbar.vue │ │ ├── Home.vue │ │ ├── NavLinks.vue │ │ ├── Layout.vue │ │ ├── AlgoliaSearchBox.vue │ │ ├── DropdownLink.vue │ │ ├── util.js │ │ ├── SearchBox.vue │ │ └── Page.vue │ ├── components │ │ ├── source-block.vue │ │ ├── form-schemer │ │ │ └── base.vue │ │ ├── form-editor │ │ │ ├── options.vue │ │ │ ├── dep-styles.vue │ │ │ ├── dep-rules.vue │ │ │ └── base.vue │ │ └── client-code.vue │ └── config.js ├── components │ ├── form-schemer.md │ └── form-editor.md └── guide │ ├── start.md │ └── schema.md ├── .gitignore ├── docs-dist ├── assets │ ├── js │ │ ├── 16.c784a25c.js │ │ ├── 11.6ae859cf.js │ │ ├── 10.b052ddc0.js │ │ ├── 7.5cbbe6f7.js │ │ ├── 9.e41b73a7.js │ │ ├── 6.2bd85cfa.js │ │ ├── 5.fc71b28b.js │ │ ├── 4.ae5ef6e8.js │ │ ├── 13.da83fe8f.js │ │ └── 15.16f22b06.js │ ├── fonts │ │ ├── iconfont.35c9461c.eot │ │ ├── iconfont.e7863ee9.ttf │ │ └── iconfont.9163fbb8.woff │ └── img │ │ ├── cavil-grey.fdc9c111.jpg │ │ ├── search.83621669.svg │ │ └── iconfont.46c33c79.svg ├── 404.html ├── index.html └── components │ └── form-schemer.html ├── .babelrc ├── README.md ├── .eslintrc.js └── package.json /src/styles/utils/var/index.less: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /images/jg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soneway/form-engine/HEAD/images/jg.png -------------------------------------------------------------------------------- /src/scripts/utils/bus.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | 3 | export default new Vue(); 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | wefe.config.js 3 | dist 4 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | home: true 3 | actionText: 快速上手 → 4 | actionLink: /guide/start 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | dist 3 | dist.zip 4 | node_modules 5 | .DS_Store 6 | package-lock.json 7 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/styles/toc.styl: -------------------------------------------------------------------------------- 1 | .table-of-contents 2 | .badge 3 | vertical-align middle 4 | -------------------------------------------------------------------------------- /src/styles/fonts/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soneway/form-engine/HEAD/src/styles/fonts/iconfont.eot -------------------------------------------------------------------------------- /src/styles/fonts/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soneway/form-engine/HEAD/src/styles/fonts/iconfont.ttf -------------------------------------------------------------------------------- /docs-dist/assets/js/16.c784a25c.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[16],{336:function(n,w,o){}}]); -------------------------------------------------------------------------------- /src/styles/fonts/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soneway/form-engine/HEAD/src/styles/fonts/iconfont.woff -------------------------------------------------------------------------------- /src/styles/fonts/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soneway/form-engine/HEAD/src/styles/fonts/iconfont.woff2 -------------------------------------------------------------------------------- /docs-dist/assets/fonts/iconfont.35c9461c.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soneway/form-engine/HEAD/docs-dist/assets/fonts/iconfont.35c9461c.eot -------------------------------------------------------------------------------- /docs-dist/assets/fonts/iconfont.e7863ee9.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soneway/form-engine/HEAD/docs-dist/assets/fonts/iconfont.e7863ee9.ttf -------------------------------------------------------------------------------- /docs-dist/assets/img/cavil-grey.fdc9c111.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soneway/form-engine/HEAD/docs-dist/assets/img/cavil-grey.fdc9c111.jpg -------------------------------------------------------------------------------- /docs-dist/assets/fonts/iconfont.9163fbb8.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soneway/form-engine/HEAD/docs-dist/assets/fonts/iconfont.9163fbb8.woff -------------------------------------------------------------------------------- /src/styles/utils/index.less: -------------------------------------------------------------------------------- 1 | // gdui工具 2 | @import "../../../node_modules/@soneway/gdui2/src/styles/utils/index"; 3 | @import "var/index"; 4 | @import "mixins/index"; 5 | -------------------------------------------------------------------------------- /src/styles/components/json-editor.less: -------------------------------------------------------------------------------- 1 | @import '../../../node_modules/codemirror/lib/codemirror.css'; 2 | @import '../../../node_modules/codemirror/addon/fold/foldgutter.css'; 3 | -------------------------------------------------------------------------------- /src/styles/components/index.less: -------------------------------------------------------------------------------- 1 | @import "../utils/index"; 2 | // 组件 3 | @import "form-editor"; 4 | @import "form-editor-item"; 5 | @import "form-schemer"; 6 | @import "json-editor"; 7 | -------------------------------------------------------------------------------- /src/styles/utils/mixins/index.less: -------------------------------------------------------------------------------- 1 | .form-icon() { 2 | font-family: "form-icon" !important; 3 | font-style: normal; 4 | -webkit-font-smoothing: antialiased; 5 | -moz-osx-font-smoothing: grayscale; 6 | } 7 | -------------------------------------------------------------------------------- /src/components/form-schemer/rule-type-map.js: -------------------------------------------------------------------------------- 1 | export default { 2 | number: 'number', 3 | checkbox: 'array', 4 | boolean: 'boolean', 5 | region: 'array', 6 | object: 'object', 7 | array: 'array', 8 | }; 9 | -------------------------------------------------------------------------------- /src/components/form-editor/index.js: -------------------------------------------------------------------------------- 1 | import FormEditor from './form-editor'; 2 | 3 | FormEditor.install = function (Vue) { 4 | Vue.component(FormEditor.name, FormEditor); 5 | }; 6 | 7 | export default FormEditor; 8 | -------------------------------------------------------------------------------- /src/components/json-editor/index.js: -------------------------------------------------------------------------------- 1 | import JsonEditor from './json-editor'; 2 | 3 | JsonEditor.install = function (Vue) { 4 | Vue.component(JsonEditor.name, JsonEditor); 5 | }; 6 | 7 | export default JsonEditor; 8 | -------------------------------------------------------------------------------- /src/components/form-schemer/index.js: -------------------------------------------------------------------------------- 1 | import FormSchemer from './form-schemer'; 2 | 3 | FormSchemer.install = function (Vue) { 4 | Vue.component(FormSchemer.name, FormSchemer); 5 | }; 6 | 7 | export default FormSchemer; 8 | -------------------------------------------------------------------------------- /docs/.vuepress/components/source-block.vue: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/search.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/components/form-editor-item/index.js: -------------------------------------------------------------------------------- 1 | import FormEditorItem from './form-editor-item'; 2 | 3 | FormEditorItem.install = function (Vue) { 4 | Vue.component(FormEditorItem.name, FormEditorItem); 5 | }; 6 | 7 | export default FormEditorItem; 8 | -------------------------------------------------------------------------------- /src/components/render-cell.js: -------------------------------------------------------------------------------- 1 | export default { 2 | name: 'render-cell', 3 | functional: true, 4 | props: { 5 | render: Function, 6 | }, 7 | render: (h, ctx) => { 8 | return ctx.props.render(h, ctx.data.attrs); 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /docs-dist/assets/img/search.83621669.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/styles/wrapper.styl: -------------------------------------------------------------------------------- 1 | $wrapper 2 | // max-width $contentWidth 3 | margin 0 auto 4 | padding 2rem 1.5rem 5 | @media (max-width: $MQNarrow) 6 | padding 2rem 7 | @media (max-width: $MQMobileNarrow) 8 | padding 1.5rem 9 | 10 | -------------------------------------------------------------------------------- /src/components/form-editor-draggable/index.js: -------------------------------------------------------------------------------- 1 | import FormEditorDraggable from './form-editor-draggable'; 2 | 3 | FormEditorDraggable.install = function (Vue) { 4 | Vue.component(FormEditorDraggable.name, FormEditorDraggable); 5 | }; 6 | 7 | export default FormEditorDraggable; 8 | -------------------------------------------------------------------------------- /docs-dist/assets/js/11.6ae859cf.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[11],{344:function(t,n,e){"use strict";e.r(n);var s=e(0),c=Object(s.a)({},function(){var t=this.$createElement;return(this._self._c||t)("div",{staticClass:"content"})},[],!1,null,null,null);n.default=c.exports}}]); -------------------------------------------------------------------------------- /src/components/form-editor-item/types.js: -------------------------------------------------------------------------------- 1 | export default [ 2 | 'label', 3 | 'text', 4 | 'number', 5 | 'textarea', 6 | 'radio', 7 | 'select', 8 | 'checkbox', 9 | 'boolean', 10 | 'region', 11 | 'object', 12 | 'array', 13 | 'nation', 14 | 'date', 15 | 'year', 16 | 'month', 17 | 'datetime', 18 | 'time', 19 | ]; 20 | -------------------------------------------------------------------------------- /docs-dist/assets/js/10.b052ddc0.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[10],{349:function(t,e,n){"use strict";n.r(e);var l=n(0),s=Object(l.a)({},function(){var t=this.$createElement,e=this._self._c||t;return e("div",{staticClass:"source-block"},[e("ClientOnly",[e("client-code",[this._t("default")],2)],1)],1)},[],!1,null,null,null);e.default=s.exports}}]); -------------------------------------------------------------------------------- /src/components/form-schemer/type-map.js: -------------------------------------------------------------------------------- 1 | export default { 2 | label: '标题', 3 | text: '文本', 4 | number: '数字', 5 | textarea: '长文本', 6 | radio: '单选', 7 | select: '选择', 8 | checkbox: '复选', 9 | boolean: '是否', 10 | region: '地区', 11 | object: '对象', 12 | array: '数组', 13 | nation: '民族', 14 | date: '日期', 15 | year: '年份', 16 | month: '月份', 17 | datetime: '日期时间', 18 | time: '时间', 19 | }; 20 | -------------------------------------------------------------------------------- /docs/components/form-schemer.md: -------------------------------------------------------------------------------- 1 | # FormSchemer 表单配置 2 | 3 | ## 基础用法 4 | 5 | 6 | 7 | <<< @/docs/.vuepress/components/form-schemer/base.vue 8 | 9 | 10 | 11 | ## 属性配置 12 | 13 | ### props 14 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 15 | |---------- |-------- |---------- |------------- |-------- | 16 | | value/v-model | 表单配置 | Object | — | - | 17 | -------------------------------------------------------------------------------- /docs/.vuepress/components/form-schemer/base.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 22 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "env", 5 | { 6 | "targets": { 7 | "browsers": [ 8 | "last 3 Chrome versions", 9 | "last 3 Firefox versions", 10 | "Safari >= 10", 11 | "Explorer >= 9", 12 | "Edge >= 12" 13 | ] 14 | }, 15 | "useBuiltIns": true, 16 | "modules": false 17 | } 18 | ], 19 | "stage-2" 20 | ], 21 | "plugins": [ 22 | "transform-vue-jsx" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /docs-dist/assets/js/7.5cbbe6f7.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[7],{204:function(t,n,e){},251:function(t,n,e){"use strict";var a=e(204);e.n(a).a},343:function(t,n,e){"use strict";e.r(n);var a={functional:!0,props:{type:{type:String,default:"tip"},text:String,vertical:{type:String,default:"top"}},render:function(t,n){var e=n.props,a=n.slots;return t("span",{class:["badge",e.type,e.vertical]},e.text||a().default)}},r=(e(251),e(0)),i=Object(r.a)(a,void 0,void 0,!1,null,"099ab69c",null);n.default=i.exports}}]); -------------------------------------------------------------------------------- /src/components/README.md: -------------------------------------------------------------------------------- 1 | ## 组件开发规范 2 | 3 | ### 文件夹 4 | 1. 一个组件对应一个文件夹 5 | 2. 文件夹名小写; 如遇多个单调,使用中划线连接; 如: page-loading 6 | 7 | ### 文件 8 | 1. index.js文件表示组件入口文件 9 | 2. 可有多个vue文件, 如为组件vue,一般与文件夹名相同 10 | 3. 文件名使用小写, 如遇多个单词,使用中划线连接; 如: page-loading.vue 11 | 12 | ### 组件编码规范 13 | 1. 为减少与data或props中的属性冲突, 计算属性中的元素类名使用下划线打头, 如: _contentClass; 元素样式类似, 如: _contentStyle 14 | 2. 组件必须有name属性, 标识组件名称, 以"gd-"前缀打头, 如: gd-button 15 | 3. 组件样式类名须以"gd-"前缀打头, 如: gd-radio 16 | 4. 组件响应事件方法名以on打头, 小驼峰法命名, 如: onClick或onBtnOkClick 17 | > 其他规范请遵循js最佳实践 -------------------------------------------------------------------------------- /docs/.vuepress/theme/styles/config.styl: -------------------------------------------------------------------------------- 1 | // colors 2 | $accentColor = #3eaf7c 3 | $textColor = #2c3e50 4 | $borderColor = #eaecef 5 | $codeBgColor = #282c34 6 | $arrowBgColor = #ccc 7 | 8 | // layout 9 | $navbarHeight = 3.6rem 10 | $sidebarWidth = 16rem 11 | $contentWidth = 740px 12 | 13 | // responsive breakpoints 14 | $MQNarrow = 959px 15 | $MQMobile = 719px 16 | $MQMobileNarrow = 419px 17 | 18 | // code 19 | $lineNumbersWrapperWidth = 3.5rem 20 | $codeLang = js ts html md vue css sass scss less stylus go java c sh yaml py 21 | -------------------------------------------------------------------------------- /src/styles/components/form-editor-item.less: -------------------------------------------------------------------------------- 1 | .form-editor-item { 2 | // 标题类型 3 | &-label { 4 | &.gd-form-item { 5 | margin-bottom: 1.2em; 6 | } 7 | 8 | .gd-form-item-label { 9 | flex: 1; 10 | padding-bottom: 1em; 11 | border-bottom: 2px solid currentColor; 12 | font-weight: bold; 13 | 14 | & + .gd-form-item-content { 15 | flex: 0; 16 | } 17 | } 18 | } 19 | 20 | .gd-check-list { 21 | .gd-radio, 22 | .gd-checkbox { 23 | margin-top: 0.3em; 24 | margin-bottom: 0.3em; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/NotFound.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 27 | -------------------------------------------------------------------------------- /docs-dist/assets/js/9.e41b73a7.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[9],{341:function(t,e,a){"use strict";a.r(e);var s={select:{label:"单选-select",type:"select",options:[]}},l={data:function(){return{formData:{},schema:s}},mounted:function(){var t=this;setTimeout(function(){t.schema.select.options=[{label:"广东",value:"gd"},{label:"江西",value:"jx"},{label:"山东",value:"sd"}]},5e3)}},n=a(0),i=Object(n.a)(l,function(){var t=this.$createElement,e=this._self._c||t;return e("div",{staticClass:"wrapper"},[e("form-editor",{ref:"formEditor",attrs:{schema:this.schema,value:this.formData}}),this._v("\n "+this._s(this.formData)+"\n")],1)},[],!1,null,null,null);e.default=i.exports}}]); -------------------------------------------------------------------------------- /docs/.vuepress/theme/styles/arrow.styl: -------------------------------------------------------------------------------- 1 | @require './config' 2 | 3 | .arrow 4 | display inline-block 5 | width 0 6 | height 0 7 | &.up 8 | border-left 4px solid transparent 9 | border-right 4px solid transparent 10 | border-bottom 6px solid $arrowBgColor 11 | &.down 12 | border-left 4px solid transparent 13 | border-right 4px solid transparent 14 | border-top 6px solid $arrowBgColor 15 | &.right 16 | border-top 4px solid transparent 17 | border-bottom 4px solid transparent 18 | border-left 6px solid $arrowBgColor 19 | &.left 20 | border-top 4px solid transparent 21 | border-bottom 4px solid transparent 22 | border-right 6px solid $arrowBgColor 23 | -------------------------------------------------------------------------------- /src/components/index.js: -------------------------------------------------------------------------------- 1 | import FormEditor from './form-editor'; 2 | import FormEditorDraggable from './form-editor-draggable'; 3 | import FormEditorItem from './form-editor-item'; 4 | import FormSchemer from './form-schemer'; 5 | import JsonEditor from './json-editor'; 6 | 7 | const components = { 8 | FormEditor, 9 | FormEditorDraggable, 10 | FormEditorItem, 11 | FormSchemer, 12 | JsonEditor, 13 | }; 14 | 15 | function install (Vue) { 16 | Object.keys(components).forEach(key => { 17 | Vue.component(key, components[key]); 18 | }); 19 | } 20 | 21 | // install 22 | if (typeof window !== 'undefined' && window.Vue) { 23 | install(window.Vue); 24 | } 25 | 26 | export default { 27 | install, 28 | ...components, 29 | }; 30 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/DropdownTransition.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 28 | 29 | 34 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/styles/custom-blocks.styl: -------------------------------------------------------------------------------- 1 | .custom-block 2 | .custom-block-title 3 | font-weight 600 4 | margin-bottom -0.4rem 5 | &.tip, &.warning, &.danger 6 | padding .1rem 1.5rem 7 | border-left-width .5rem 8 | border-left-style solid 9 | margin 1rem 0 10 | &.tip 11 | background-color #f3f5f7 12 | border-color #42b983 13 | &.warning 14 | background-color rgba(255,229,100,.3) 15 | border-color darken(#ffe564, 35%) 16 | color darken(#ffe564, 70%) 17 | .custom-block-title 18 | color darken(#ffe564, 50%) 19 | a 20 | color $textColor 21 | &.danger 22 | background-color #ffe6e6 23 | border-color darken(red, 20%) 24 | color darken(red, 70%) 25 | .custom-block-title 26 | color darken(red, 40%) 27 | a 28 | color $textColor 29 | -------------------------------------------------------------------------------- /src/components/form-schemer/regexes.js: -------------------------------------------------------------------------------- 1 | export default { 2 | phone: { 3 | name: '手机', 4 | regex: '^([1][3,4,5,6,7,8,9])\\d{9}$', 5 | }, 6 | tel: { 7 | name: '固话', 8 | regex: '\\d{3}-\\d{8}|\\d{4}-\\d{7}', 9 | }, 10 | email: { 11 | name: '邮箱', 12 | regex: '^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$', 13 | }, 14 | url: { 15 | name: '链接', 16 | regex: '[a-zA-z]+://[^\\s]*', 17 | }, 18 | idCard: { 19 | name: '身份证', 20 | regex: '(^\\d{8}(0\\d|10|11|12)([0-2]\\d|30|31)\\d{3}$)|(^\\d{6}(18|19|20)\\d{2}(0\\d|10|11|12)([0-2]\\d|30|31)\\d{3}(\\d|X|x)$)', 21 | }, 22 | chinese: { 23 | name: '中文', 24 | regex: '[\u4e00-\u9fa5]', 25 | }, 26 | zipCode: { 27 | name: '邮编', 28 | regex: '^(0[1-7]|1[0-356]|2[0-7]|3[0-6]|4[0-7]|5[1-7]|6[1-7]|7[0-5]|8[013-6])\\d{4}$', 29 | }, 30 | }; 31 | -------------------------------------------------------------------------------- /docs/.vuepress/components/form-editor/options.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 介绍 2 | form-engine基于vue+gdui2, 可解决各种各样的表单需求, 编程中使用form-editor来实现表单需求, 代码量可减少60%左右 3 | 4 | ![image](images/jg.png) 5 | 6 | ## form-editor 7 | 实现用schema(表单描述数据)来配置表单 8 | 9 | ## form-schemer 10 | 实现schema配置的可视 11 | 12 | ## 进入开发 13 | 14 | ### 第1步: 安装依赖 15 | ```bash 16 | npm i @soneway/form-engine 17 | ``` 18 | 19 | ### 第2步: 引入gdui2 20 | 由于form-engine基于gdui2, 需要引入gdui2, 详情参考: [gdui2文档](https://soneway.github.io/gdui2/docs-dist/guide/start.html) 21 | 22 | ### 第3步: js中注册组件 23 | ```javascript 24 | import Vue from 'vue'; 25 | import formEngine from '@soneway/form-engine'; 26 | Vue.use(formEngine); 27 | ``` 28 | 29 | ### 第4步: less中引用样式 30 | ```less 31 | @import "~@soneway/form-engine/dist/css/index.css"; 32 | ``` 33 | 34 | ### 第5步: html中使用组件 35 | ```html 36 | 37 | ``` 38 | 39 | 详情请参考: [form-engine文档](https://soneway.github.io/form-engine/docs-dist/guide/start.html) 40 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/styles/mobile.styl: -------------------------------------------------------------------------------- 1 | @require './config' 2 | 3 | $mobileSidebarWidth = $sidebarWidth * 0.82 4 | 5 | // narrow desktop / iPad 6 | @media (max-width: $MQNarrow) 7 | .sidebar 8 | font-size 15px 9 | width $mobileSidebarWidth 10 | .page 11 | padding-left $mobileSidebarWidth 12 | 13 | // wide mobile 14 | @media (max-width: $MQMobile) 15 | .sidebar 16 | top 0 17 | padding-top $navbarHeight 18 | transform translateX(-100%) 19 | transition transform .2s ease 20 | .page 21 | padding-left 0 22 | .theme-container 23 | &.sidebar-open 24 | .sidebar 25 | transform translateX(0) 26 | &.no-navbar 27 | .sidebar 28 | padding-top: 0 29 | 30 | // narrow mobile 31 | @media (max-width: $MQMobileNarrow) 32 | h1 33 | font-size 1.9rem 34 | .content 35 | div[class*="language-"] 36 | margin 0.85rem -1.5rem 37 | border-radius 0 38 | -------------------------------------------------------------------------------- /docs/.vuepress/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | host: '127.0.0.1', 3 | port: '8320', 4 | title: '表单引擎', 5 | base: '/form-engine/docs-dist/', 6 | lastUpdated: 'Last Updated', 7 | themeConfig: { 8 | nav: [ 9 | { text: '指南', link: '/guide/start' }, 10 | { text: '访问github', link: 'https://github.com/soneway/form-engine' }, 11 | { text: 'gdui2', link: 'https://soneway.github.io/gdui2/docs-dist/guide/start.html' }, 12 | ], 13 | sidebar: [ 14 | { 15 | title: '指南', 16 | collapsable: false, 17 | children: [ 18 | ['/guide/start', '快速上手'], 19 | ['/guide/schema', '表单数据配置规范'], 20 | ], 21 | }, 22 | { 23 | title: '组件', 24 | collapsable: false, 25 | children: [ 26 | ['/components/form-editor', 'FormEditor 表单填写'], 27 | ['/components/form-schemer', 'FormSchemer 表单配置'], 28 | ], 29 | }, 30 | ], 31 | }, 32 | }; 33 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/SidebarButton.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 29 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/NavLink.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 50 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/styles/nprogress.styl: -------------------------------------------------------------------------------- 1 | #nprogress 2 | pointer-events none 3 | .bar 4 | background $accentColor 5 | position fixed 6 | z-index 1031 7 | top 0 8 | left 0 9 | width 100% 10 | height 2px 11 | .peg 12 | display block 13 | position absolute 14 | right 0px 15 | width 100px 16 | height 100% 17 | box-shadow 0 0 10px $accentColor, 0 0 5px $accentColor 18 | opacity 1.0 19 | transform rotate(3deg) translate(0px, -4px) 20 | .spinner 21 | display block 22 | position fixed 23 | z-index 1031 24 | top 15px 25 | right 15px 26 | .spinner-icon 27 | width 18px 28 | height 18px 29 | box-sizing border-box 30 | border solid 2px transparent 31 | border-top-color $accentColor 32 | border-left-color $accentColor 33 | border-radius 50% 34 | animation nprogress-spinner 400ms linear infinite 35 | 36 | .nprogress-custom-parent 37 | overflow hidden 38 | position relative 39 | 40 | .nprogress-custom-parent #nprogress .spinner, 41 | .nprogress-custom-parent #nprogress .bar 42 | position absolute 43 | 44 | @keyframes nprogress-spinner 45 | 0% 46 | transform rotate(0deg) 47 | 100% 48 | transform rotate(360deg) 49 | -------------------------------------------------------------------------------- /src/components/json-editor/json-editor.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 52 | -------------------------------------------------------------------------------- /docs/guide/start.md: -------------------------------------------------------------------------------- 1 | # 快速上手 2 | 3 | ## 进入开发 4 | 5 | ### 第1步: 安装依赖 6 | ```bash 7 | npm i @soneway/form-engine 8 | ``` 9 | 10 | ### 第2步: 引入gdui2 11 | 由于form-engine基于gdui2, 需要引入gdui2, 详情参考: [gdui2文档](https://soneway.github.io/gdui2/docs-dist/guide/start.html) 12 | 13 | ### 第3步: js中注册组件 14 | ```javascript 15 | import Vue from 'vue'; 16 | import formEngine from '@soneway/form-engine'; 17 | Vue.use(formEngine); 18 | ``` 19 | 20 | ### 第4步: less中引用样式 21 | ```less 22 | @import "~@soneway/form-engine/dist/css/index.css"; 23 | ``` 24 | 25 | ### 第5步: html中使用组件 26 | ```html 27 | 28 | ``` 29 | 30 | ## 按需引入 31 | 32 | 借助 [babel-plugin-component](https://www.npmjs.com/package/babel-plugin-component),我们可以只引入需要的组件,以达到减小项目体积的目的。 33 | 34 | ### 第1步: 安装 `babel-plugin-component` 35 | ```bash 36 | npm install babel-plugin-component -D 37 | ``` 38 | 39 | ### 第2步: 添加 babel.config/babelrc 配置: 40 | ```json 41 | { 42 | "plugins": [ 43 | [ 44 | "component", 45 | { 46 | "libraryName": "@soneway/form-engine", 47 | "libDir": "dist", 48 | "styleLibrary": { 49 | "base": false, 50 | "name": "css" 51 | } 52 | } 53 | ] 54 | ] 55 | } 56 | ``` 57 | 58 | ### 第3步: 在less中删除样式引用 59 | ```less 60 | // 删除以下引用代码 61 | @import "~@soneway/form-engine/dist/css/index.css"; 62 | ``` 63 | 64 | ### 第4步: 在js中引入部分需要用到的组件, 如: 65 | ```js 66 | import Vue from 'vue'; 67 | import { 68 | FormEditor, 69 | } from '@soneway/form-engine'; 70 | 71 | Vue.use(FormEditor); 72 | ``` 73 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: [ 3 | 'standard', 4 | 'plugin:vue/essential', 5 | ], 6 | env: { 7 | browser: true, 8 | node: true, 9 | }, 10 | plugins: [ 11 | // lint .vue文件 12 | 'vue', 13 | ], 14 | parserOptions: { 15 | // import()不报错 16 | parser: 'babel-eslint', 17 | }, 18 | 19 | rules: { 20 | // 对象最后一个属性后的逗号 21 | 'comma-dangle': [2, 'always-multiline'], 22 | // 语句强制分号结束 23 | 'semi': [2, 'always'], 24 | // 大括号风格 25 | 'brace-style': ['error', 'stroustrup'], 26 | // 强制驼峰法命名 27 | 'camelcase': 0, 28 | // 禁止在使用new构造一个实例后不赋值 29 | 'no-new': 1, 30 | }, 31 | overrides: [ 32 | // .vue文件重写规则 33 | { 34 | files: ['*.vue'], 35 | rules: { 36 | 'indent': 'off', 37 | // template缩进 38 | 'vue/html-indent': ['error', 2, { 39 | 'alignAttributesVertically': false, 40 | }], 41 | // script缩进 42 | 'vue/script-indent': ['error', 2, { 43 | 'baseIndent': 1, 44 | }], 45 | // computed必须返回值 46 | 'vue/return-in-computed-property': 1, 47 | // 模板空格 48 | 'vue/mustache-interpolation-spacing': ['error', 'always'], 49 | // 简写 50 | 'vue/v-bind-style': ['error', 'shorthand'], 51 | 'vue/v-on-style': ['error', 'shorthand'], 52 | // 组件属性顺序 53 | 'vue/order-in-components': 'error', 54 | // 组件名大小写 55 | 'vue/component-name-in-template-casing': ['error', 'PascalCase'], 56 | }, 57 | }, 58 | ], 59 | }; 60 | -------------------------------------------------------------------------------- /docs/guide/schema.md: -------------------------------------------------------------------------------- 1 | # 表单数据配置规范 2 | 3 | ## 典型示例 4 | ```json 5 | { 6 | "field": { 7 | "type": "type", 8 | "label": "label", 9 | "placeholder": "placeholder", 10 | "rules": [ 11 | { 12 | "type": "string", 13 | "required": true, 14 | "message": "不能为空" 15 | }, 16 | { 17 | "type": "string", 18 | "pattern": "^[a-z]+$", 19 | "message": "格式不符合正式表达式" 20 | }, 21 | { 22 | "type": "string", 23 | "min": 5, 24 | "message": "字符长度必须大于{min}, 数字必须大于{min}" 25 | }, 26 | { 27 | "max": 5, 28 | "message": "字符长度必须小于{max}, 数字必须小于{max}" 29 | }, 30 | { 31 | "len": 5, 32 | "message": "字符长度必须等于{len}, 数字必须等于{len}, 数组长度必须等于{len}" 33 | } 34 | ], 35 | "depRules": [ 36 | { 37 | "dep": { 38 | "key": "text", 39 | "opt": "eq/lt/gt/lte/gte/in/reg", 40 | "value": "1" 41 | }, 42 | "type": "string", 43 | "pattern": "^[a-z]+$", 44 | "message": "格式不符合正式表达式" 45 | } 46 | ], 47 | "depStyles": [ 48 | { 49 | "dep": { 50 | "key": "text", 51 | "opt": "eq/lt/gt/lte/gte/in/reg", 52 | "value": "1" 53 | }, 54 | "type": "disabled" 55 | } 56 | ] 57 | } 58 | } 59 | ``` 60 | 61 | ## 配置说明 62 | ### field 63 | - 数据字段名称, 配置表单数据中包含的字段 64 | ```json 65 | { 66 | "name": {}, 67 | "age": {} 68 | } 69 | ``` 70 | 以上配置可使表单产生数据: { name: value, age: value } 71 | 72 | -------------------------------------------------------------------------------- /docs-dist/assets/js/6.2bd85cfa.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[6],{223:function(e,t,l){},334:function(e,t,l){"use strict";var a=l(223);l.n(a).a},340:function(e,t,l){"use strict";l.r(t);var a={labelHidden:{type:"label",label:"依赖隐藏",span:12},depHidden:{label:"依赖",type:"text",placeholder:"依赖为空时, 隐藏文本输入框(依赖不为空时, 显示文本输入框)"},textHidden:{label:"文本",type:"text",depStyles:[{dep:{key:"depHidden",opt:"ie"},type:"hidden"},{dep:{key:"depHidden",opt:function(e){return e>10}},type:"hidden"}]},labelDisabled:{type:"label",label:"依赖禁用",span:12},depDisabled:{label:"依赖",type:"text",placeholder:"依赖大于等于10时, 禁用文本输入框"},textDisabled:{label:"文本",type:"text",depStyles:[{dep:{key:"depDisabled",opt:"gte",val:"10"},type:"disabled"}]},labelReadonly:{type:"label",label:"依赖只读",span:12},depReadonly:{label:"依赖",type:"text",placeholder:"依赖小于等于10时, 文本输入框只读"},textReadonly:{label:"文本",type:"text",depStyles:[{dep:{key:"depReadonly",opt:"lte",val:"10"},type:"readonly"}]}},n={data:function(){return{formData:{},schema:a}},methods:{onClick:function(){var e=this;this.$refs.formEditor.validate(function(t){e.$toast.success("验证成功"),console.log("验证成功",t)},function(t){e.$toast.error("验证失败"),console.log("验证失败",t)})}}},d=(l(334),l(0)),o=Object(d.a)(n,function(){var e=this,t=e.$createElement,l=e._self._c||t;return l("div",{staticClass:"wrapper"},[l("form-editor",{ref:"formEditor",attrs:{colcount:2,schema:e.schema,value:e.formData}}),e._v(" "),l("p",{staticStyle:{"padding-bottom":"20px"}},[l("gd-button",{on:{click:e.onClick}},[e._v("表单校验\n ")])],1),e._v("\n "+e._s(e.formData)+"\n")],1)},[],!1,null,null,null);t.default=o.exports}}]); -------------------------------------------------------------------------------- /docs-dist/assets/js/5.fc71b28b.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[5],{222:function(e,t,a){},333:function(e,t,a){"use strict";var l=a(222);a.n(l).a},339:function(e,t,a){"use strict";a.r(t);var l={labelRequired:{type:"label",label:"依赖非空",span:12},depRequired:{label:"依赖",type:"text"},textRequired:{label:"文本",type:"text",depRules:[{dep:{key:"depRequired",opt:"eq",val:"1"},type:"string",required:!0,message:"依赖为1时, 文本不能为空"},{dep:{key:"depRequired",opt:"gt",val:"10"},type:"string",required:!0,message:"依赖大于10时, 文本不能为空"}]},labelPattern:{type:"label",label:"依赖正则",span:12},depPattern:{label:"依赖",type:"text"},textPattern:{label:"文本",type:"text",default:"1",depRules:[{dep:{key:"depPattern",opt:"reg",val:"^([1][3,4,5,6,7,8,9])\\d{9}$"},type:"string",pattern:"^([1][3,4,5,6,7,8,9])\\d{9}$",message:"依赖符合正则时, 文本不符合正则"},{dep:{key:"depPattern",opt:"in",val:"1,3,5"},type:"string",pattern:"^([1][3,4,5,6,7,8,9])\\d{9}$",message:"依赖为1,3,5其中之一时, 文本不符合正则"}]},labelLen:{type:"label",label:"依赖大小",span:12},depLen:{label:"依赖",type:"text"},textLen:{label:"文本",type:"text",default:"1",depRules:[{dep:{key:"depLen",opt:"nie"},type:"string",len:10,message:"依赖不为空时, 文本长度需为10"}]}},n={data:function(){return{formData:{},schema:l}},methods:{onClick:function(){var e=this;this.$refs.formEditor.validate(function(t){e.$toast.success("验证成功"),console.log("验证成功",t)},function(t){e.$toast.error("验证失败"),console.log("验证失败",t)})}}},r=(a(333),a(0)),p=Object(r.a)(n,function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("div",{staticClass:"wrapper"},[a("form-editor",{ref:"formEditor",attrs:{colcount:2,schema:e.schema,value:e.formData}}),e._v(" "),a("p",{staticStyle:{"padding-bottom":"20px"}},[a("gd-button",{on:{click:e.onClick}},[e._v("表单校验\n ")])],1),e._v("\n "+e._s(e.formData)+"\n")],1)},[],!1,null,null,null);t.default=p.exports}}]); -------------------------------------------------------------------------------- /docs/.vuepress/theme/SidebarGroup.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 43 | 44 | 78 | -------------------------------------------------------------------------------- /docs-dist/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 表单引擎 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

404

How did we get here?
Take me home.
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/SWUpdatePopup.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 60 | 61 | 86 | -------------------------------------------------------------------------------- /docs-dist/assets/js/4.ae5ef6e8.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[4],{221:function(e,t,a){},332:function(e,t,a){"use strict";var l=a(221);a.n(l).a},338:function(e,t,a){"use strict";a.r(t);var l={text:{label:"文本",type:"text",rules:[{type:"string",required:!0},{type:"string",pattern:"^([1][3,4,5,6,7,8,9])\\d{9}$"}],span:6,default:"11"},number:{label:"数字",type:"number",span:6,depRules:[{dep:{key:"text",opt:"reg",val:"^([1][3,4,5,6,7,8,9])\\d{9}$"},type:"number",required:!0}],depStyles:[{dep:{key:"text",opt:"eq",val:"11"},type:"hidden"}]},label:{type:"label",label:"这是一段label说明"},textarea:{label:"文本域",type:"textarea",maxlength:5,rules:[{type:"string",max:4}],labelAlign:"right",labelWidth:"110px"},radio:{label:"单选-radio",type:"radio",options:[{label:"广东",value:"gd"},{label:"江西",value:"jx"},{label:"山东",value:"sd"}]},select:{label:"单选-select",type:"select",options:[{label:"广东",value:"gd"},{label:"江西",value:"jx"},{label:"山东",value:"sd"}],props:{filterable:!0}},checkbox:{label:"多选",type:"checkbox",options:[{label:"广东",value:"gd"},{label:"江西",value:"jx"},{label:"山东",value:"sd"}]},boolean:{label:"布尔值",type:"boolean"},region:{label:"地区",type:"region"},object:{label:"对象",type:"object",fields:{text:{type:"text",label:"文字"},number:{type:"number"},object:{type:"object",expand:!1,fields:{name:{type:"text",label:"姓名"},age:{type:"number"}}}}},array:{label:"数组",type:"array",fields:{name:{type:"text",rules:[{type:"string",required:!0}]},age:{type:"number"}}},custom:{label:"自定义渲染函数",render:function(e,t){var a=t.value,l=t.keyName;t.schema,t.supKeyName;return e("gd-input",{attrs:{value:a[l]},on:{input:function(e){a[l]=e}}})}},datetime:{type:"datetime",label:"日期"}},n={data:function(){return{formData:{},schema:l}},methods:{onClick:function(){this.$refs.formEditor.validate(function(e){console.log("验证成功",e)},function(e){console.log("验证失败",e)})}},mounted:function(){var e=this;setTimeout(function(){e.formData={object:{object:{name:"2222",age:3333},text:"222",number:333333},array:[],datetime:"2019-11-11 12:00:00"}},1e3)}},r=(a(332),a(0)),o=Object(r.a)(n,function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("div",{staticClass:"wrapper"},[a("form-editor",{ref:"formEditor",attrs:{schema:e.schema,value:e.formData}}),e._v(" "),a("p",{staticStyle:{"padding-bottom":"20px"}},[a("gd-button",{on:{click:e.onClick}},[e._v("表单校验\n ")])],1),e._v("\n "+e._s(e.formData)+"\n")],1)},[],!1,null,null,null);t.default=o.exports}}]); -------------------------------------------------------------------------------- /src/styles/components/form-editor.less: -------------------------------------------------------------------------------- 1 | @import "../../styles/utils/index"; 2 | 3 | .form-editor { 4 | 5 | // 数据添加项按钮 6 | .add-icon { 7 | cursor: pointer; 8 | line-height: @input-height; 9 | 10 | &:hover { 11 | color: @success-color; 12 | } 13 | } 14 | 15 | // 对象/数组中禁止多列显示 16 | .object-wrapper, 17 | .array-wrapper { 18 | 19 | // 复写样式 20 | .gd-col { 21 | padding-left: 0 !important; 22 | padding-right: 0 !important; 23 | } 24 | 25 | .gd-form-item { 26 | float: none; 27 | width: auto; 28 | } 29 | } 30 | 31 | // 对象容器 32 | .object-wrapper { 33 | background: fade(#000, 3%); 34 | padding: 1em; 35 | padding-left: 3em; 36 | 37 | &:after { 38 | content: '⋯'; 39 | } 40 | 41 | & > .form-editor-item { 42 | display: none; 43 | } 44 | 45 | & > .object-toggle-icon { 46 | position: absolute; 47 | left: 1em; 48 | color: #999; 49 | transition: all 0.2s; 50 | transform: rotate(-90deg); 51 | cursor: pointer; 52 | 53 | &:hover { 54 | color: inherit; 55 | } 56 | } 57 | 58 | // 展开状态 59 | &.expand { 60 | 61 | &:after { 62 | display: none; 63 | } 64 | 65 | & > .form-editor-item { 66 | display: flex; 67 | } 68 | 69 | & > .object-toggle-icon { 70 | transform: none; 71 | } 72 | } 73 | 74 | &:hover { 75 | & + .array-delete-icon { 76 | visibility: visible; 77 | } 78 | } 79 | } 80 | 81 | // 数组删除按钮 82 | .array-delete-icon { 83 | position: absolute; 84 | right: 0; 85 | top: 0; 86 | cursor: pointer; 87 | visibility: hidden; 88 | 89 | &:hover { 90 | visibility: visible; 91 | color: @error-color; 92 | } 93 | } 94 | 95 | // 只读/禁用状态 96 | &-readonly, 97 | &-disabled { 98 | .array-wrapper { 99 | // 隐藏数组添加/删除按钮 100 | .add-icon, 101 | .array-delete-icon { 102 | display: none; 103 | } 104 | } 105 | } 106 | 107 | // 兼容IE9 108 | .IE9 & { 109 | // 对象容器 110 | .object-wrapper { 111 | 112 | // 展开状态 113 | &.expand { 114 | & > .form-editor-item { 115 | display: block; 116 | } 117 | } 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/scripts/utils/helper.js: -------------------------------------------------------------------------------- 1 | import { getValueByPath } from 'utils-lib/dist/object'; 2 | 3 | // 获取依赖配置 4 | function getDepConfig (deps = [], formValue) { 5 | return deps.map((item) => { 6 | const { dep, ...rest } = item; 7 | let { key, opt, val } = dep; 8 | const depValue = getValueByPath(formValue, key); 9 | 10 | // 为函数 11 | if (typeof opt === 'function') { 12 | if (opt(depValue, val)) { 13 | return rest; 14 | } 15 | return; 16 | } 17 | 18 | /* eslint-disable */ 19 | switch (opt) { 20 | // 等于 21 | case 'eq': { 22 | // 不用全等 23 | if (depValue == val) { 24 | return rest; 25 | } 26 | break; 27 | } 28 | // 不等于 29 | case 'neq': { 30 | // 不用全等 31 | if (depValue != val) { 32 | return rest; 33 | } 34 | break; 35 | } 36 | // 为空 37 | case 'ie': { 38 | if (!depValue) { 39 | return rest; 40 | } 41 | break; 42 | } 43 | // 不为空 44 | case 'nie': { 45 | if (depValue) { 46 | return rest; 47 | } 48 | break; 49 | } 50 | // 小于 51 | case 'lt': { 52 | if (+depValue < +val) { 53 | return rest; 54 | } 55 | break; 56 | } 57 | // 大于 58 | case 'gt': { 59 | if (+depValue > +val) { 60 | return rest; 61 | } 62 | break; 63 | } 64 | // 小于等于 65 | case 'lte': { 66 | if (+depValue <= +val) { 67 | return rest; 68 | } 69 | break; 70 | } 71 | // 大于等于 72 | case 'gte': { 73 | if (+depValue >= +val) { 74 | return rest; 75 | } 76 | break; 77 | } 78 | // 枚举 79 | case 'in': { 80 | if (typeof val === 'string') { 81 | val = val.split(','); 82 | } 83 | // 不用全等 84 | if (val.filter(i => i == depValue).length) { 85 | return rest; 86 | } 87 | break; 88 | } 89 | // 正则 90 | case 'reg': { 91 | const reg = new RegExp(val); 92 | if (reg.test(depValue)) { 93 | return rest; 94 | } 95 | break; 96 | } 97 | } 98 | /* eslint-enable */ 99 | }).filter(i => i); 100 | } 101 | 102 | export { 103 | getDepConfig, 104 | }; 105 | -------------------------------------------------------------------------------- /docs/.vuepress/components/client-code.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 43 | 44 | 114 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/Sidebar.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 80 | 81 | 114 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/SidebarLink.vue: -------------------------------------------------------------------------------- 1 | 60 | 61 | 92 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@soneway/form-engine", 3 | "version": "1.2.0", 4 | "title": "表单引擎", 5 | "keywords": [ 6 | "vue", 7 | "form", 8 | "components" 9 | ], 10 | "main": "dist/index.js", 11 | "files": [ 12 | "dist", 13 | "packages" 14 | ], 15 | "scripts": { 16 | "up": "rm -rf node_modules && npm i", 17 | "dev": "vuepress dev docs", 18 | "build": "vuepress build docs", 19 | "pack": "rm -rf docs-dist && npm run build && cd docs/.vuepress && mv dist ../../docs-dist", 20 | "dist:css": "gulp --gulpfile build/build-style.js", 21 | "dist:components": "webpack --config build/webpack.components.js", 22 | "dist:utils": "webpack --config build/webpack.utils.js", 23 | "dist:mixins": "webpack --config build/webpack.mixins.js", 24 | "dist:index": "webpack --config build/webpack.index.js", 25 | "dist:js": "npm run dist:components && npm run dist:index", 26 | "dist": "rm -rf dist && npm run dist:css && npm run dist:js", 27 | "pub": "npm run dist && npm publish --access public", 28 | "pub:beta": "npm run dist && npm publish --tag beta --access public", 29 | "lint": "eslint src --ext js,vue --fix", 30 | "lint-staged": "lint-staged" 31 | }, 32 | "pre-commit": [ 33 | "lint-staged" 34 | ], 35 | "lint-staged": { 36 | "*.{js,vue}": [ 37 | "eslint src --ext js,vue --fix", 38 | "git add" 39 | ] 40 | }, 41 | "repository": { 42 | "type": "git", 43 | "url": "https://github.com/soneway/form-engine" 44 | }, 45 | "author": "soneway", 46 | "license": "MIT", 47 | "dependencies": { 48 | "@soneway/gdui2": "latest", 49 | "utils-lib": "latest", 50 | "vue": "^2.6.10", 51 | "vue-codemirror": "^4.0.6", 52 | "vuedraggable": "^2.20.0" 53 | }, 54 | "devDependencies": { 55 | "@soneway/division": "latest", 56 | "autoprefixer-loader": "3.2.0", 57 | "babel-core": "6.26.3", 58 | "babel-eslint": "10.0.1", 59 | "babel-loader": "7.1.4", 60 | "babel-plugin-syntax-jsx": "6.18.0", 61 | "babel-plugin-transform-vue-jsx": "3.7.0", 62 | "babel-preset-env": "1.7.0", 63 | "babel-preset-stage-2": "6.24.1", 64 | "css-loader": "2.1.1", 65 | "eslint": "5.8.0", 66 | "eslint-config-standard": "12.0.0", 67 | "eslint-plugin-import": "2.14.0", 68 | "eslint-plugin-node": "7.0.1", 69 | "eslint-plugin-promise": "4.0.1", 70 | "eslint-plugin-standard": "4.0.0", 71 | "eslint-plugin-vue": "5.2.2", 72 | "gulp": "3.9.1", 73 | "gulp-autoprefixer": "5.0.0", 74 | "gulp-clean-css": "3.10.0", 75 | "gulp-less": "4.0.1", 76 | "gulp-rename": "1.4.0", 77 | "html-loader": "0.5.5", 78 | "less": "3.9.0", 79 | "less-loader": "4.1.0", 80 | "lint-staged": "8.1.5", 81 | "pre-commit": "1.2.2", 82 | "sass-loader": "7.1.0", 83 | "style-loader": "0.23.1", 84 | "url-loader": "1.1.2", 85 | "vue-loader": "14.2.4", 86 | "vue-style-loader": "4.1.2", 87 | "vue-template-compiler": "2.6.10", 88 | "vuepress": "0.14.11", 89 | "webpack": "4.31.0", 90 | "webpack-cli": "3.3.2", 91 | "webpack-merge": "4.2.1", 92 | "webpack-node-externals": "1.7.2" 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /docs/.vuepress/components/form-editor/dep-styles.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 131 | 132 | 140 | -------------------------------------------------------------------------------- /src/components/form-editor/form-editor.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 126 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/styles/code.styl: -------------------------------------------------------------------------------- 1 | @require './config' 2 | 3 | .content 4 | code 5 | color lighten($textColor, 20%) 6 | padding 0.25rem 0.5rem 7 | margin 0 8 | font-size 0.85em 9 | background-color rgba(27,31,35,0.05) 10 | border-radius 3px 11 | 12 | .content 13 | pre, pre[class*="language-"] 14 | line-height 1.4 15 | padding 1.25rem 1.5rem 16 | margin 0.85rem 0 17 | background-color $codeBgColor 18 | border-radius 6px 19 | overflow auto 20 | code 21 | color #fff 22 | padding 0 23 | background-color transparent 24 | border-radius 0 25 | 26 | div[class*="language-"] 27 | position relative 28 | background-color $codeBgColor 29 | border-radius 6px 30 | .highlight-lines 31 | user-select none 32 | padding-top 1.3rem 33 | position absolute 34 | top 0 35 | left 0 36 | width 100% 37 | line-height 1.4 38 | .highlighted 39 | background-color rgba(0, 0, 0, 66%) 40 | pre, pre[class*="language-"] 41 | background transparent 42 | position relative 43 | z-index 1 44 | &::before 45 | position absolute 46 | z-index 3 47 | top 0.8em 48 | right 1em 49 | font-size 0.75rem 50 | color rgba(255, 255, 255, 0.4) 51 | &:not(.line-numbers-mode) 52 | .line-numbers-wrapper 53 | display none 54 | &.line-numbers-mode 55 | .highlight-lines .highlighted 56 | position relative 57 | &:before 58 | content ' ' 59 | position absolute 60 | z-index 3 61 | left 0 62 | top 0 63 | display block 64 | width $lineNumbersWrapperWidth 65 | height 100% 66 | background-color rgba(0, 0, 0, 66%) 67 | pre 68 | padding-left $lineNumbersWrapperWidth + 1 rem 69 | vertical-align middle 70 | .line-numbers-wrapper 71 | position absolute 72 | top 0 73 | width $lineNumbersWrapperWidth 74 | text-align center 75 | color rgba(255, 255, 255, 0.3) 76 | padding 1.25rem 0 77 | line-height 1.4 78 | br 79 | user-select none 80 | .line-number 81 | position relative 82 | z-index 4 83 | user-select none 84 | font-size 0.85em 85 | &::after 86 | content '' 87 | position absolute 88 | z-index 2 89 | top 0 90 | left 0 91 | width $lineNumbersWrapperWidth 92 | height 100% 93 | border-radius 6px 0 0 6px 94 | border-right 1px solid rgba(0, 0, 0, 66%) 95 | background-color $codeBgColor 96 | 97 | 98 | for lang in $codeLang 99 | div{'[class~="language-' + lang + '"]'} 100 | &:before 101 | content ('' + lang) 102 | 103 | div[class~="language-javascript"] 104 | &:before 105 | content "js" 106 | 107 | div[class~="language-typescript"] 108 | &:before 109 | content "ts" 110 | 111 | div[class~="language-markup"] 112 | &:before 113 | content "html" 114 | 115 | div[class~="language-markdown"] 116 | &:before 117 | content "md" 118 | 119 | div[class~="language-json"]:before 120 | content "json" 121 | 122 | div[class~="language-ruby"]:before 123 | content "rb" 124 | 125 | div[class~="language-python"]:before 126 | content "py" 127 | 128 | div[class~="language-bash"]:before 129 | content "sh" 130 | -------------------------------------------------------------------------------- /docs/.vuepress/components/form-editor/dep-rules.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 146 | 147 | 155 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/Navbar.vue: -------------------------------------------------------------------------------- 1 | 38 | 39 | 87 | 88 | 134 | -------------------------------------------------------------------------------- /docs/components/form-editor.md: -------------------------------------------------------------------------------- 1 | # FormEditor表单填写 2 | 3 | ## 基础用法 4 | 5 | 6 | <<< @/docs/.vuepress/components/form-editor/base.vue 7 | 8 | 9 | ## 异步数据 10 | 11 | 12 | <<< @/docs/.vuepress/components/form-editor/options.vue 13 | 14 | 15 | ## 依赖校验 16 | 17 | 18 | <<< @/docs/.vuepress/components/form-editor/dep-rules.vue 19 | 20 | 21 | ## 依赖样式 22 | 23 | 24 | <<< @/docs/.vuepress/components/form-editor/dep-styles.vue 25 | 26 | 27 | 28 | ## 属性配置 29 | 30 | ### props 31 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 32 | |---------- |-------- |---------- |------------- |-------- | 33 | | schema | 表单配置, 请参考[表单数据配置规范](/guide/schema.html) | object | — | - | 34 | | value | 表单数据 | object | — | - | 35 | | size | 表单元素尺寸 | string | large,small,mini | - | 36 | | disabled | 禁用状态 | Boolean | — | false | 37 | | readonly | 只读状态 | Boolean | — | false | 38 | | active-key | 激活的key | String | — | - | 39 | | colcount | 表单显示列数 | Number | 1, 2, 3, 4, 6, 12 | 1 | 40 | | gutter | col之间的间距 | Number | - | 30 | 41 | | label-width | label的宽度 | String | - | - | 42 | | label-align | label的文字对齐方式 | left,center,right | - | - | 43 | 44 | #### schema.field options (字段配置项) 45 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 46 | |---------- |-------- |---------- |------------- |-------- | 47 | | type | 表单域类型 | String | label,text,number,textarea,radio,select,checkbox,boolean,region,object,array,nation,date,year,month,datetime,time | text | 48 | | label | 表单域label说明 | String | — | - | 49 | | rules | 校验规则, 详细请参考: [async-validator](https://github.com/yiminghe/async-validator#rules) | Array | - | - | 50 | | maxlength | 输入的最大长度, 仅field.type=textarea/text有效 | Number | — | - | 51 | | disabled | 禁用状态 | Boolean | — | false | 52 | | readonly | 只读状态 | Boolean | — | false | 53 | | span | 表单项所占的横向格数(栅格布局, 总格数为12) | Number | 1-12 | 12 | 54 | | labelWidth | label的宽度 | String | - | - | 55 | | labelAlign | label的文字对齐方式 | left,center,right | - | - | 56 | | render | 表单域自定义渲染函数, 表单域将渲染该函数返回的值 | Function | - | - | 57 | | options | 选项数据源, radio,select,checkbox时有效, 格式如: [ { label, value }, { label, value } ] 或 [ value, value ] | Array | - | - | 58 | | pcaJson | 地区组件数据源, region时有效 | Array | - | - | 59 | | props | 其他属性对象, 将直接v-bind到表单组件上 | Object | - | - | 60 | | depRules | 依赖校验规则 | Array | - | - | 61 | | depStyles | 依赖样式 | Function | - | - | 62 | 63 | #### depRules.item options (依赖校验规则配置项) 64 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 65 | |---------- |-------- |---------- |------------- |-------- | 66 | | dep | 依赖条件 | Object | - | - | 67 | | ...rule | 校验规则其他属性, 详细请参考: [async-validator](https://github.com/yiminghe/async-validator#rules) | - | - | - | 68 | 69 | #### depStyles.item options (依赖样式配置项) 70 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 71 | |---------- |-------- |---------- |------------- |-------- | 72 | | dep | 依赖条件 | Object | - | - | 73 | | type | 样式类型, 如: 隐藏(hidden) | String | readonly,disabled,hidden | - | 74 | 75 | 76 | #### dep options 77 | | 参数 | 说明 | 类型 | 可选值 | 默认值 | 78 | |---------- |-------- |---------- |------------- |-------- | 79 | | key | 依赖表单域的字段名 | String | - | - | 80 | | opt | 操作符, 如: 相等(eq), 不为空(nie) | String, Function | eq: 等于, neq: 不等于, ie: 为空, nie: 不为空, lt: 小于, lte: 小于等于, gt: 大于, gte: 大于等于, in: 枚举在, reg: 符合正则 | - | 81 | | val | 依赖表单域的值 | String, Number | - | - | 82 | 83 | ### events 84 | | 参数 | 说明 | 返回值 | 85 | |---------- |-------- |--- | 86 | | fieldadd | 添加项事件 | type, keyName | 87 | | fieldsort | 排序 | keys | 88 | | itemclick | 项点击 | {keyName} | 89 | 90 | 91 | ### methods 92 | | 参数 | 说明 | 93 | |---------- |-------- | 94 | | validate | 数据校验 | 95 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/Home.vue: -------------------------------------------------------------------------------- 1 | 51 | 52 | 72 | 73 | 163 | -------------------------------------------------------------------------------- /src/styles/components/form-schemer.less: -------------------------------------------------------------------------------- 1 | @import "../../styles/utils/index"; 2 | @import "../fonts/iconfont.css"; 3 | 4 | .form-schemer { 5 | height: 640px; 6 | 7 | .gd-tabs { 8 | display: flex; 9 | height: 100%; 10 | flex-direction: column; 11 | } 12 | 13 | .gd-tabs-content { 14 | flex: 1; 15 | overflow: hidden; 16 | } 17 | 18 | .gd-tabs-pane { 19 | height: 100%; 20 | } 21 | 22 | &-visual, 23 | .vue-codemirror, 24 | .CodeMirror { 25 | height: 100%; 26 | } 27 | 28 | // 代码编辑器 29 | .CodeMirror { 30 | border: 1px dotted @border-color-light; 31 | } 32 | 33 | // 可视化模式 34 | &-visual { 35 | display: flex; 36 | flex-direction: column; 37 | } 38 | 39 | // 数据类型 40 | &-type { 41 | border-bottom: 1px solid @border-color-light; 42 | padding: 0.8em 0; 43 | background: @background-color-light; 44 | } 45 | 46 | // 数据类型项 47 | .type-item { 48 | .form-icon; 49 | display: inline-block; 50 | color: #505A6E; 51 | padding: 0.5em 0.8em; 52 | text-align: center; 53 | 54 | &:not(:last-child) { 55 | margin-right: 0.5em; 56 | } 57 | 58 | &:before { 59 | display: block; 60 | font-size: 2em; 61 | padding-bottom: 3px; 62 | } 63 | 64 | &:hover { 65 | color: @primary-color; 66 | background: fade(@primary-color, 10%); 67 | box-shadow: 0 0 0 1px @primary-color inset; 68 | } 69 | } 70 | 71 | // 工作区 72 | &-work { 73 | flex: 1; 74 | display: flex; 75 | overflow: hidden; 76 | 77 | & > div { 78 | height: 100%; 79 | overflow: auto; 80 | padding-top: 1em; 81 | } 82 | } 83 | 84 | // 预览区 85 | &-preview { 86 | flex: 1; 87 | border-right: 1px solid @border-color-light; 88 | position: relative; 89 | padding-right: 15px; 90 | 91 | // 复写表单样式 92 | .form-editor { 93 | &-draggable { 94 | & > .form-editor-item { 95 | padding-top: 0.8em; 96 | padding-bottom: 0.8em; 97 | 98 | &:not(:last-of-type) { 99 | margin-bottom: 0.5em; 100 | } 101 | 102 | &:hover { 103 | background: fade(@primary-color, 10%); 104 | } 105 | 106 | &.active { 107 | box-shadow: -2px 0 0 0 @primary-color inset; 108 | background: fade(@primary-color, 10%); 109 | } 110 | 111 | & > .gd-form-item-content { 112 | padding-right: 1.8em; 113 | } 114 | } 115 | 116 | .form-schemer-tools { 117 | position: absolute; 118 | right: 0; 119 | top: 50%; 120 | transform: translate(0, -50%); 121 | } 122 | 123 | // 删除图标 124 | .field-delete-icon { 125 | cursor: pointer; 126 | 127 | &:hover { 128 | color: @error-color; 129 | } 130 | } 131 | 132 | // 空占位 133 | &:empty { 134 | &:before { 135 | display: block; 136 | content: '请点击数据类型, 或拖拽到此'; 137 | text-align: center; 138 | padding-top: 200px; 139 | } 140 | } 141 | } 142 | } 143 | 144 | & > .gd-button { 145 | margin: 1em 0; 146 | } 147 | } 148 | 149 | // 配置区 150 | &-config { 151 | width: 490px; 152 | padding-left: 1em; 153 | } 154 | 155 | .form-icon-label { 156 | &:before { 157 | content: '标'; 158 | text-decoration: underline; 159 | transform: scale(0.7, 0.7); 160 | } 161 | } 162 | } 163 | 164 | // 字段配置 165 | .field-config { 166 | & > h3 { 167 | margin-bottom: 1em; 168 | 169 | &:not(:first-of-type) { 170 | margin-top: 1.5em; 171 | } 172 | } 173 | 174 | .gd-form-item { 175 | &:not(:last-of-type) { 176 | margin-bottom: 1em; 177 | } 178 | } 179 | 180 | &-form { 181 | .gd-form-item.gd-form-item-required { 182 | margin-bottom: 1.5em; 183 | } 184 | } 185 | 186 | .rule-item { 187 | &:not(:last-of-type) { 188 | margin-bottom: 1em; 189 | } 190 | 191 | .gd-input { 192 | margin-left: 0.6em; 193 | } 194 | } 195 | 196 | .CodeMirror { 197 | height: 310px; 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /src/components/form-editor-draggable/form-editor-draggable.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 165 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/NavLinks.vue: -------------------------------------------------------------------------------- 1 | 35 | 36 | 117 | 118 | 152 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/styles/theme.styl: -------------------------------------------------------------------------------- 1 | @require './config' 2 | @require './nprogress' 3 | @require './code' 4 | @require './custom-blocks' 5 | @require './arrow' 6 | @require './wrapper' 7 | @require './toc' 8 | 9 | html, body 10 | padding 0 11 | margin 0 12 | 13 | body 14 | font-family -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif 15 | -webkit-font-smoothing antialiased 16 | -moz-osx-font-smoothing grayscale 17 | font-size 16px 18 | color $textColor 19 | 20 | a 21 | color $accentColor 22 | text-decoration none 23 | 24 | p a code 25 | font-weight 400 26 | color $accentColor 27 | 28 | kbd 29 | background #eee 30 | border solid 0.15rem #ddd 31 | border-bottom solid 0.25rem #ddd 32 | border-radius 0.15rem 33 | padding 0 0.15em 34 | 35 | blockquote 36 | font-size 1.2rem 37 | color #999 38 | border-left .25rem solid #dfe2e5 39 | margin-left 0 40 | padding-left 1rem 41 | 42 | ul, ol 43 | padding-left 1.2em 44 | 45 | strong 46 | font-weight 600 47 | 48 | a.header-anchor 49 | font-size 0.85em 50 | float left 51 | margin-left -0.87em 52 | padding-right 0.23em 53 | margin-top 0.125em 54 | opacity 0 55 | &:hover 56 | text-decoration none 57 | 58 | code, kbd, .line-number 59 | font-family source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace 60 | 61 | p, ul, ol 62 | line-height 1.7 63 | 64 | hr 65 | border 0 66 | border-top 1px solid $borderColor 67 | 68 | .theme-container 69 | &.sidebar-open 70 | .sidebar-mask 71 | display: block 72 | &.no-navbar 73 | .content:not(.custom) > h1, h2, h3, h4, h5, h6 74 | margin-top 1.5rem 75 | padding-top 0 76 | .sidebar 77 | top 0 78 | .custom-layout 79 | padding-top 0 80 | 81 | .page 82 | padding-left $sidebarWidth 83 | 84 | > .content:not(.custom) 85 | @extend $wrapper 86 | > *:first-child 87 | margin-top $navbarHeight 88 | > a:hover 89 | text-decoration underline 90 | > p.demo 91 | padding 1rem 1.5rem 92 | border 1px solid #ddd 93 | border-radius 4px 94 | > img 95 | max-width 100% 96 | > h1, > h2, > h3, > h4, > h5, > h6 97 | margin-top (0.5rem - $navbarHeight) 98 | padding-top ($navbarHeight + 1rem) 99 | margin-bottom 0 100 | &:first-child 101 | margin-top -1.5rem 102 | margin-bottom 1rem 103 | + p, + pre, + .custom-block 104 | margin-top 2rem 105 | 106 | > .content.custom 107 | padding 0 108 | margin 0 109 | img 110 | max-width 100% 111 | 112 | > .content 113 | > h1, > h2, > h3, > h4, > h5, > h6 114 | font-weight 600 115 | line-height 1.25 116 | 117 | &:hover .header-anchor 118 | opacity: 1 119 | 120 | > h1 121 | font-size 1.6rem 122 | 123 | > h2 124 | font-size 1.3rem 125 | padding-bottom .8rem 126 | border-bottom 1px solid $borderColor 127 | 128 | > h3 129 | font-size 1.1rem 130 | 131 | > p 132 | margin 0.8rem 0 133 | 134 | > ul 135 | margin .8rem 0 136 | li 137 | list-style inside 138 | 139 | > table 140 | border-collapse collapse 141 | margin 1rem 0 142 | width 100% 143 | overflow-x: auto 144 | 145 | th 146 | text-align left 147 | 148 | thead 149 | tr 150 | background #f6f6f6 151 | 152 | tr 153 | border-top 1px solid #eee 154 | &:nth-child(2n) 155 | background-color #fafafa 156 | 157 | th, td 158 | border 1px solid #eee 159 | padding .6em 1em 160 | 161 | .navbar 162 | position fixed 163 | z-index 20 164 | top 0 165 | left 0 166 | right 0 167 | height $navbarHeight 168 | background-color #fff 169 | box-sizing border-box 170 | border-bottom 1px solid $borderColor 171 | 172 | .sidebar-mask 173 | position fixed 174 | z-index 9 175 | top 0 176 | left 0 177 | width 100vw 178 | height 100vh 179 | display none 180 | 181 | .sidebar 182 | font-size 15px 183 | background-color #fff 184 | width $sidebarWidth 185 | position fixed 186 | z-index 10 187 | margin 0 188 | top $navbarHeight 189 | left 0 190 | bottom 0 191 | box-sizing border-box 192 | border-right 1px solid $borderColor 193 | overflow-y auto 194 | 195 | .custom-layout 196 | padding-top $navbarHeight 197 | 198 | @media (min-width: ($MQMobile + 1px)) 199 | .theme-container.no-sidebar 200 | .sidebar 201 | display none 202 | .page 203 | padding-left 0 204 | 205 | @require './mobile.styl' 206 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/Layout.vue: -------------------------------------------------------------------------------- 1 | 58 | 59 | 181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /src/styles/fonts/iconfont.css: -------------------------------------------------------------------------------- 1 | @font-face {font-family: "form-icon"; 2 | src: url('iconfont.eot?t=1556589996301'); /* IE9 */ 3 | src: url('iconfont.eot?t=1556589996301#iefix') format('embedded-opentype'), /* IE6-IE8 */ 4 | url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAjEAAsAAAAAEdgAAAh0AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCFCAqRRI5GATYCJANYCy4ABCAFhG0Hgz0bYQ8jEVakBrK/OuAN6R81ELWetSgGS7CedtdXbatYLRZFEDsGDCvv4bX8KTddM52Y4P8cPI95/Z+bpJ2M+4QPgystpd33VkB/uvmtIXztQZGEiZcmFGAYPtDGpAP6Y9k/ei9/9lIKKeQUoL7wZBZAwJEdNpt4JgJavdtoEYHtXRuY3cPenFqucG1qQDJh6S8+uWLLI0s5WUnbH/dr1S0UHdIsFiIhbue7/07eKcPUEhWSSTpIRDFphCYhaUhUWqGkDkSIZ+8z4VNvLjIAN0OAEDkpjtRvaOsKFoNqhSbDh4QHgp0wYwqCBat3M040yGpYrFqizgCsSr5e3qAiFhSORm/VOswsBGo/C3yurWf7g1Bis2nWJ4DaaaCB4oABmZ6ZPhH0gBdPpFBWuqFpsdbQ5nnu+zxHkXxvZdRWaAxO9x94ASxBQoSJECVGHI8EEkkimRQQF60XARDpAKTAcxQgkoACogAVRAMaiAF0EAcwQFzABAkAFogFbJAg4ICEABckDHggEcAHiQIBSAwIQeJABOIBMUgCkIAkAilIEpCBJAM57UgBIDU6oTjQCFCLIfQ0VHfISPru4q6h1DdoHPTdJqksLjXZ5EYKx7huMOiaSIzGjPLdiGM0LWJs260YpdSEMwuTlStP8Wg9bw7aQNPohoKNnLLGndY7eXGJUb/YyBTfFR5SVKISOYGMSniSijcErFFppVI1iFZpjFxaJ+Uk6heoNC4zsiJzieXtLzdS8YzIERULSHVR2xoSAjKyMU5K0cDasLDCIdDnyLrWYlVnpayrS/HM1fzoDjJWDI2twcACrI05lwmiov7Mmbh5P2R002lsynnqgxyadAoMpGDdedgBYNBheBm1oMlJp5EV0seYJDmYLRgWGMWNC1kUgi0b3u/yw6HebeLtmrJxioYzUmU9usDWyCZnOGA5AM7CgQyV9tKD5vb0jcGQ4ZCnLuuwus2nPoRvDT0n7akHTW11S9YRgRLZ5g9GbdMNZ0I3SH/DhjaDzphLnQJrY9VReijqE6zPOeXjKu5vlF+LjgEr9uFDyYPDf/H9jTWal8e1rLum2fQQ0EBYMDJEQGYdjMOKSRdLryJLboizgbnW9vVUy6ZGbARanr9vU0YdOUEcLFnROZBdnwpDKvpP5lgGi/di5burz8K763DtUlZ4dNJpa899zPm6C+lrzrCKCCo4tpA+vvGII45NMYZaAFsh3ZyhwvRhByEMPfS7/29jP/Xe8jB9701BejyenNKpKwD3hcnJ8qmpYq0nj6tc+ra5kd6/2OPHlUlNe/78Q7Hii0umJqUpJiaZmUGLcnEvb2Njby/NMTH28rYsYtXHGxvD16K2Nuz40cKyLXvL2rrw44cLS7e9HlfxyLFol+jxII+mworaeTT3QZAd6e4xNu7Kyrr2PlN697Gy6yqu6OoBqA8KtfRgUKjgQWz8eT5I/VFrtnAcdSoAQ7EmIJwKvfMFy/46w30hQgj8bnBgoAAniIIHP2v7CM1zvHgxvVdlYJCObsWv4l/SSodiq3nVmzs/UyaKZjRgo7a1Z/cP0CS4NuuR8M/KsDMVMHn4XXwVNq3rLO5RKVKuXC5QDoCPspbff646USe1XuJBIL5Zn7qsNR1VRo9RDdkS0vxREpoSw+hhamQ6oMGDEZpWhqE2LxhqnevK6rrz4H6PMDeFrPbn0bkHyRSnM5aWteXLFMW3h4U/QcSJ9MpSdy10tnnAUfgsGQXpDZVUmVZuNlE2viOulLv/3Ln/yDG1bo7JKxZLce+X/49GVrALH+kJqhTWrlyZsbampAS7Hpe3pvaTJ1X2pEyK2+QBjGm6nZKLakvjvoHWyNLoQNSY2o5+v9q2Gw+SMroS3mHLzeMmbH2WnnSRQPSZcRaL3qiRq1PA1dM+t5I0ce14IrMx9cwCYR4aGabuUGtWAXEhcm7WLhzQCxP4ASQGxOFCeJxupaJZyoPW64qV9Fm1PT+onS8YQOD2MNgKepbqB+mXYHcXH9dLaVwCsW+4WEvw3YHs09ucCY1Y2GNUI7sO2zmNoakzDLW52Fx0AfHApzf8Ql5i61j1xYsmrFHLAVj1MU/VQ8dUPj5Hp4OXgZEuIv3dIG9jhsK5ff2TjaRvq7lyndtd9MKzNYzYDEUswCunxKqqYM39KUXpTTWobLWA9rJjuVEllVFdWUFZyclowSPdG5j1/4/m6/PqZxKaQ+24znoN4P90rboBgEH1ztLtdlHJWLMn3au6jw69rW66t89MUStdXV/pehcZzq+LSS1/1PtaKam+NNesW/HnuDXdkh7sBTBW/yaQQafcvF0/ZPL80cBy+VhUhUtT/leocBxhuiq1pJr23wrkW4lMpQ24pQoI2WzwTXYi9/dFl+Ks+C/WpYyIIkAOorHkdzbuxYlDmPLExVKLhChGo9PDJDEWNGKCQFEWeETwOEoUMc4Rjcc1CsX9HnFI5R1x8USTyQjy6YIEQcPyjREEjapfKmgarG+TZdr0G93UAY+rkrB/5BiKVJkV01VfOCCv45A4u0rEKsvUq0/vdth1pEamBrVkXmS857nNOjTT1CdLuIohIFFcQ6m9kgYaGdjJxXLm878hZ9IBXNBnJ+k/xKKwdqWUKRycv6TBqc99aR3NnIqIsFTQmZGe8ikCdbacKGP2dg2kiYxfonR0l8tY1lXKtq/rH4U5QAj0+NQL0WLEEVcCYiX4u/TEiEQlJnHxHh6fnl9e3+zCiPv0Aq2eAjO8TpOO6BGhk8PsOjVRhzAca6kaoj/BILdT9qjbmp7cXPUVJPS4ZeR+fCmOOJhdWdrTID7XRPWN0ZPkDCaQw2Hqa+QpEbFz7oVDz2FoL+13ggQaoAvy2qsVBJ9yGp8GjLDaVaaxIzDu7MB6FglGt9Ke8NeypiQBAAAA') format('woff2'), 5 | url('iconfont.woff?t=1556589996301') format('woff'), 6 | url('iconfont.ttf?t=1556589996301') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ 7 | url('iconfont.svg?t=1556589996301#iconfont') format('svg'); /* iOS 4.1- */ 8 | } 9 | 10 | .form-icon-array:before { 11 | content: "\e625"; 12 | } 13 | 14 | .form-icon-arrowsalt:before { 15 | content: "\e626"; 16 | } 17 | 18 | .form-icon-boolean:before { 19 | content: "\e627"; 20 | } 21 | 22 | .form-icon-cascader:before { 23 | content: "\e628"; 24 | } 25 | 26 | .form-icon-checkbox:before { 27 | content: "\e629"; 28 | } 29 | 30 | .form-icon-datetime:before { 31 | content: "\e62a"; 32 | } 33 | 34 | .form-icon-date:before { 35 | content: "\e62b"; 36 | } 37 | 38 | .form-icon-depend:before { 39 | content: "\e62c"; 40 | } 41 | 42 | .form-icon-month:before { 43 | content: "\e62d"; 44 | } 45 | 46 | .form-icon-object:before { 47 | content: "\e62e"; 48 | } 49 | 50 | .form-icon-radio:before { 51 | content: "\e62f"; 52 | } 53 | 54 | .form-icon-number:before { 55 | content: "\e630"; 56 | } 57 | 58 | .form-icon-select:before { 59 | content: "\e631"; 60 | } 61 | 62 | .form-icon-shrink:before { 63 | content: "\e632"; 64 | } 65 | 66 | .form-icon-nation:before { 67 | content: "\e633"; 68 | } 69 | 70 | .form-icon-text:before { 71 | content: "\e634"; 72 | } 73 | 74 | .form-icon-textarea:before { 75 | content: "\e635"; 76 | } 77 | 78 | .form-icon-upload:before { 79 | content: "\e636"; 80 | } 81 | 82 | .form-icon-time:before { 83 | content: "\e637"; 84 | } 85 | 86 | .form-icon-region:before { 87 | content: "\e638"; 88 | } 89 | 90 | .form-icon-year:before { 91 | content: "\e639"; 92 | } 93 | 94 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/AlgoliaSearchBox.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 60 | 61 | 157 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/DropdownLink.vue: -------------------------------------------------------------------------------- 1 | 51 | 52 | 78 | 79 | 182 | -------------------------------------------------------------------------------- /docs/.vuepress/components/form-editor/base.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 219 | 220 | 228 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/util.js: -------------------------------------------------------------------------------- 1 | export const hashRE = /#.*$/ 2 | export const extRE = /\.(md|html)$/ 3 | export const endingSlashRE = /\/$/ 4 | export const outboundRE = /^(https?:|mailto:|tel:)/ 5 | 6 | export function normalize (path) { 7 | return decodeURI(path) 8 | .replace(hashRE, '') 9 | .replace(extRE, '') 10 | } 11 | 12 | export function getHash (path) { 13 | const match = path.match(hashRE) 14 | if (match) { 15 | return match[0] 16 | } 17 | } 18 | 19 | export function isExternal (path) { 20 | return outboundRE.test(path) 21 | } 22 | 23 | export function isMailto (path) { 24 | return /^mailto:/.test(path) 25 | } 26 | 27 | export function isTel (path) { 28 | return /^tel:/.test(path) 29 | } 30 | 31 | export function ensureExt (path) { 32 | if (isExternal(path)) { 33 | return path 34 | } 35 | const hashMatch = path.match(hashRE) 36 | const hash = hashMatch ? hashMatch[0] : '' 37 | const normalized = normalize(path) 38 | 39 | if (endingSlashRE.test(normalized)) { 40 | return path 41 | } 42 | return normalized + '.html' + hash 43 | } 44 | 45 | export function isActive (route, path) { 46 | const routeHash = route.hash 47 | const linkHash = getHash(path) 48 | if (linkHash && routeHash !== linkHash) { 49 | return false 50 | } 51 | const routePath = normalize(route.path) 52 | const pagePath = normalize(path) 53 | return routePath === pagePath 54 | } 55 | 56 | export function resolvePage (pages, rawPath, base) { 57 | if (base) { 58 | rawPath = resolvePath(rawPath, base) 59 | } 60 | const path = normalize(rawPath) 61 | for (let i = 0; i < pages.length; i++) { 62 | if (normalize(pages[i].path) === path) { 63 | return Object.assign({}, pages[i], { 64 | type: 'page', 65 | path: ensureExt(rawPath) 66 | }) 67 | } 68 | } 69 | console.error(`[vuepress] No matching page found for sidebar item "${rawPath}"`) 70 | return {} 71 | } 72 | 73 | function resolvePath (relative, base, append) { 74 | const firstChar = relative.charAt(0) 75 | if (firstChar === '/') { 76 | return relative 77 | } 78 | 79 | if (firstChar === '?' || firstChar === '#') { 80 | return base + relative 81 | } 82 | 83 | const stack = base.split('/') 84 | 85 | // remove trailing segment if: 86 | // - not appending 87 | // - appending to trailing slash (last segment is empty) 88 | if (!append || !stack[stack.length - 1]) { 89 | stack.pop() 90 | } 91 | 92 | // resolve relative path 93 | const segments = relative.replace(/^\//, '').split('/') 94 | for (let i = 0; i < segments.length; i++) { 95 | const segment = segments[i] 96 | if (segment === '..') { 97 | stack.pop() 98 | } else if (segment !== '.') { 99 | stack.push(segment) 100 | } 101 | } 102 | 103 | // ensure leading slash 104 | if (stack[0] !== '') { 105 | stack.unshift('') 106 | } 107 | 108 | return stack.join('/') 109 | } 110 | 111 | export function resolveSidebarItems (page, route, site, localePath) { 112 | const { pages, themeConfig } = site 113 | 114 | const localeConfig = localePath && themeConfig.locales 115 | ? themeConfig.locales[localePath] || themeConfig 116 | : themeConfig 117 | 118 | const pageSidebarConfig = page.frontmatter.sidebar || localeConfig.sidebar || themeConfig.sidebar 119 | if (pageSidebarConfig === 'auto') { 120 | return resolveHeaders(page) 121 | } 122 | 123 | const sidebarConfig = localeConfig.sidebar || themeConfig.sidebar 124 | if (!sidebarConfig) { 125 | return [] 126 | } else { 127 | const { base, config } = resolveMatchingConfig(route, sidebarConfig) 128 | return config 129 | ? config.map(item => resolveItem(item, pages, base)) 130 | : [] 131 | } 132 | } 133 | 134 | function resolveHeaders (page) { 135 | const headers = groupHeaders(page.headers || []) 136 | return [{ 137 | type: 'group', 138 | collapsable: false, 139 | title: page.title, 140 | children: headers.map(h => ({ 141 | type: 'auto', 142 | title: h.title, 143 | basePath: page.path, 144 | path: page.path + '#' + h.slug, 145 | children: h.children || [] 146 | })) 147 | }] 148 | } 149 | 150 | export function groupHeaders (headers) { 151 | // group h3s under h2 152 | headers = headers.map(h => Object.assign({}, h)) 153 | let lastH2 154 | headers.forEach(h => { 155 | if (h.level === 2) { 156 | lastH2 = h 157 | } else if (lastH2) { 158 | (lastH2.children || (lastH2.children = [])).push(h) 159 | } 160 | }) 161 | return headers.filter(h => h.level === 2) 162 | } 163 | 164 | export function resolveNavLinkItem (linkItem) { 165 | return Object.assign(linkItem, { 166 | type: linkItem.items && linkItem.items.length ? 'links' : 'link' 167 | }) 168 | } 169 | 170 | export function resolveMatchingConfig (route, config) { 171 | if (Array.isArray(config)) { 172 | return { 173 | base: '/', 174 | config: config 175 | } 176 | } 177 | for (const base in config) { 178 | if (ensureEndingSlash(route.path).indexOf(base) === 0) { 179 | return { 180 | base, 181 | config: config[base] 182 | } 183 | } 184 | } 185 | return {} 186 | } 187 | 188 | function ensureEndingSlash (path) { 189 | return /(\.html|\/)$/.test(path) 190 | ? path 191 | : path + '/' 192 | } 193 | 194 | function resolveItem (item, pages, base, isNested) { 195 | if (typeof item === 'string') { 196 | return resolvePage(pages, item, base) 197 | } else if (Array.isArray(item)) { 198 | return Object.assign(resolvePage(pages, item[0], base), { 199 | title: item[1] 200 | }) 201 | } else { 202 | if (isNested) { 203 | console.error( 204 | '[vuepress] Nested sidebar groups are not supported. ' + 205 | 'Consider using navbar + categories instead.' 206 | ) 207 | } 208 | const children = item.children || [] 209 | return { 210 | type: 'group', 211 | title: item.title, 212 | children: children.map(child => resolveItem(child, pages, base, true)), 213 | collapsable: item.collapsable !== false 214 | } 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /docs-dist/assets/js/13.da83fe8f.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[13],{347:function(t,s,a){"use strict";a.r(s);var n=a(0),e=Object(n.a)({},function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("div",{staticClass:"content"},[t._m(0),t._v(" "),t._m(1),t._v(" "),a("source-block",[a("form-schemer-base"),t._v(" "),a("div",{staticClass:"language-vue extra-class"},[a("pre",{pre:!0,attrs:{class:"language-vue"}},[a("code",[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("template")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("form-schemer")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("v-model")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("schema"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v(":pca-json")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("pcaJson"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("script")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),a("span",{pre:!0,attrs:{class:"token script"}},[a("span",{pre:!0,attrs:{class:"token language-javascript"}},[t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" pcaJson "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@soneway/division/dist/pca'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("export")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("default")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("data")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n schema"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n pcaJson"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])]),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])])])],1),t._v(" "),t._m(2),t._v(" "),t._m(3),t._v(" "),t._m(4)],1)},[function(){var t=this.$createElement,s=this._self._c||t;return s("h1",{attrs:{id:"formschemer-表单配置"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#formschemer-表单配置","aria-hidden":"true"}},[this._v("#")]),this._v(" FormSchemer 表单配置")])},function(){var t=this.$createElement,s=this._self._c||t;return s("h2",{attrs:{id:"基础用法"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#基础用法","aria-hidden":"true"}},[this._v("#")]),this._v(" 基础用法")])},function(){var t=this.$createElement,s=this._self._c||t;return s("h2",{attrs:{id:"属性配置"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#属性配置","aria-hidden":"true"}},[this._v("#")]),this._v(" 属性配置")])},function(){var t=this.$createElement,s=this._self._c||t;return s("h3",{attrs:{id:"props"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#props","aria-hidden":"true"}},[this._v("#")]),this._v(" props")])},function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("table",[a("thead",[a("tr",[a("th",[t._v("参数")]),t._v(" "),a("th",[t._v("说明")]),t._v(" "),a("th",[t._v("类型")]),t._v(" "),a("th",[t._v("可选值")]),t._v(" "),a("th",[t._v("默认值")])])]),t._v(" "),a("tbody",[a("tr",[a("td",[t._v("value/v-model")]),t._v(" "),a("td",[t._v("表单配置")]),t._v(" "),a("td",[t._v("Object")]),t._v(" "),a("td",[t._v("—")]),t._v(" "),a("td",[t._v("-")])])])])}],!1,null,null,null);s.default=e.exports}}]); -------------------------------------------------------------------------------- /docs/.vuepress/theme/SearchBox.vue: -------------------------------------------------------------------------------- 1 | 37 | 38 | 153 | 154 | 239 | -------------------------------------------------------------------------------- /docs-dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 表单引擎 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

表单引擎

23 | Welcome to your VuePress site 24 |

快速上手 →

25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/Page.vue: -------------------------------------------------------------------------------- 1 | 63 | 64 | 196 | 197 | 247 | -------------------------------------------------------------------------------- /docs-dist/components/form-schemer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | FormSchemer 表单配置 | 表单引擎 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

FormSchemer 表单配置

基础用法

属性配置

props

参数 说明 类型 可选值 默认值
value/v-model 表单配置 Object -
27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/components/form-schemer/form-schemer.vue: -------------------------------------------------------------------------------- 1 | 88 | 89 | 287 | -------------------------------------------------------------------------------- /src/styles/fonts/iconfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | Created by iconfont 9 | 10 | 11 | 12 | 13 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /docs-dist/assets/img/iconfont.46c33c79.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | Created by iconfont 9 | 10 | 11 | 12 | 13 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /docs-dist/assets/js/15.16f22b06.js: -------------------------------------------------------------------------------- 1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[15],{348:function(t,s,a){"use strict";a.r(s);var e=a(0),n=Object(e.a)({},function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("div",{staticClass:"content"},[t._m(0),t._v(" "),t._m(1),t._v(" "),t._m(2),t._v(" "),t._m(3),t._m(4),t._v(" "),a("p",[t._v("由于form-engine基于gdui2, 需要引入gdui2, 详情参考: "),a("a",{attrs:{href:"https://soneway.github.io/gdui2/docs-dist/guide/start.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("gdui2文档"),a("OutboundLink")],1)]),t._v(" "),t._m(5),t._v(" "),t._m(6),t._m(7),t._v(" "),t._m(8),t._m(9),t._v(" "),t._m(10),t._m(11),t._v(" "),a("p",[t._v("借助 "),a("a",{attrs:{href:"https://www.npmjs.com/package/babel-plugin-component",target:"_blank",rel:"noopener noreferrer"}},[t._v("babel-plugin-component"),a("OutboundLink")],1),t._v(",我们可以只引入需要的组件,以达到减小项目体积的目的。")]),t._v(" "),t._m(12),t._v(" "),t._m(13),t._m(14),t._v(" "),t._m(15),t._m(16),t._v(" "),t._m(17),t._m(18),t._v(" "),t._m(19)])},[function(){var t=this.$createElement,s=this._self._c||t;return s("h1",{attrs:{id:"快速上手"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#快速上手","aria-hidden":"true"}},[this._v("#")]),this._v(" 快速上手")])},function(){var t=this.$createElement,s=this._self._c||t;return s("h2",{attrs:{id:"进入开发"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#进入开发","aria-hidden":"true"}},[this._v("#")]),this._v(" 进入开发")])},function(){var t=this.$createElement,s=this._self._c||t;return s("h3",{attrs:{id:"第1步-安装依赖"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#第1步-安装依赖","aria-hidden":"true"}},[this._v("#")]),this._v(" 第1步: 安装依赖")])},function(){var t=this.$createElement,s=this._self._c||t;return s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[this._v("npm")]),this._v(" i @soneway/form-engine\n")])])])},function(){var t=this.$createElement,s=this._self._c||t;return s("h3",{attrs:{id:"第2步-引入gdui2"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#第2步-引入gdui2","aria-hidden":"true"}},[this._v("#")]),this._v(" 第2步: 引入gdui2")])},function(){var t=this.$createElement,s=this._self._c||t;return s("h3",{attrs:{id:"第3步-js中注册组件"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#第3步-js中注册组件","aria-hidden":"true"}},[this._v("#")]),this._v(" 第3步: js中注册组件")])},function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("div",{staticClass:"language-javascript extra-class"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" Vue "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'vue'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" formEngine "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@soneway/form-engine'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nVue"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("use")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("formEngine"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])},function(){var t=this.$createElement,s=this._self._c||t;return s("h3",{attrs:{id:"第4步-less中引用样式"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#第4步-less中引用样式","aria-hidden":"true"}},[this._v("#")]),this._v(" 第4步: less中引用样式")])},function(){var t=this.$createElement,s=this._self._c||t;return s("div",{staticClass:"language-less extra-class"},[s("pre",{pre:!0,attrs:{class:"language-less"}},[s("code",[s("span",{pre:!0,attrs:{class:"token variable"}},[this._v("@import")]),this._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[this._v('"~@soneway/form-engine/dist/css/index.css"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[this._v(";")]),this._v("\n")])])])},function(){var t=this.$createElement,s=this._self._c||t;return s("h3",{attrs:{id:"第5步-html中使用组件"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#第5步-html中使用组件","aria-hidden":"true"}},[this._v("#")]),this._v(" 第5步: html中使用组件")])},function(){var t=this.$createElement,s=this._self._c||t;return s("div",{staticClass:"language-html extra-class"},[s("pre",{pre:!0,attrs:{class:"language-html"}},[s("code",[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[this._v("<")]),this._v("form-editor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[this._v(">")])]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[this._v("")])]),this._v("\n")])])])},function(){var t=this.$createElement,s=this._self._c||t;return s("h2",{attrs:{id:"按需引入"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#按需引入","aria-hidden":"true"}},[this._v("#")]),this._v(" 按需引入")])},function(){var t=this.$createElement,s=this._self._c||t;return s("h3",{attrs:{id:"第1步-安装-babel-plugin-component"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#第1步-安装-babel-plugin-component","aria-hidden":"true"}},[this._v("#")]),this._v(" 第1步: 安装 "),s("code",[this._v("babel-plugin-component")])])},function(){var t=this.$createElement,s=this._self._c||t;return s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[this._v("npm")]),this._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[this._v("install")]),this._v(" babel-plugin-component -D\n")])])])},function(){var t=this.$createElement,s=this._self._c||t;return s("h3",{attrs:{id:"第2步-添加-babel-config-babelrc-配置:"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#第2步-添加-babel-config-babelrc-配置:","aria-hidden":"true"}},[this._v("#")]),this._v(" 第2步: 添加 babel.config/babelrc 配置:")])},function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("div",{staticClass:"language-json extra-class"},[a("pre",{pre:!0,attrs:{class:"language-json"}},[a("code",[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"plugins"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"component"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"libraryName"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"@soneway/form-engine"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"libDir"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"dist"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"styleLibrary"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"base"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n "),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"name"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"css"')]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])},function(){var t=this.$createElement,s=this._self._c||t;return s("h3",{attrs:{id:"第3步-在less中删除样式引用"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#第3步-在less中删除样式引用","aria-hidden":"true"}},[this._v("#")]),this._v(" 第3步: 在less中删除样式引用")])},function(){var t=this.$createElement,s=this._self._c||t;return s("div",{staticClass:"language-less extra-class"},[s("pre",{pre:!0,attrs:{class:"language-less"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[this._v("// 删除以下引用代码")]),this._v("\n"),s("span",{pre:!0,attrs:{class:"token variable"}},[this._v("@import")]),this._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[this._v('"~@soneway/form-engine/dist/css/index.css"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[this._v(";")]),this._v("\n")])])])},function(){var t=this.$createElement,s=this._self._c||t;return s("h3",{attrs:{id:"第4步-在js中引入部分需要用到的组件-如:"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#第4步-在js中引入部分需要用到的组件-如:","aria-hidden":"true"}},[this._v("#")]),this._v(" 第4步: 在js中引入部分需要用到的组件, 如:")])},function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" Vue "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'vue'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n FormEditor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@soneway/form-engine'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nVue"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("use")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("FormEditor"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])}],!1,null,null,null);s.default=n.exports}}]); -------------------------------------------------------------------------------- /src/components/form-schemer/field-config.vue: -------------------------------------------------------------------------------- 1 | 121 | 122 | 424 | --------------------------------------------------------------------------------