├── 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 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
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 |
2 |
3 |
6 |
7 |
8 |
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 |
2 |
3 |
4 |
404
5 |
{{ getMsg() }}
6 |
Take me home.
7 |
8 |
9 |
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 |
2 |
8 |
9 |
10 |
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 |
2 |
3 |
7 |
8 | {{formData}}
9 |
10 |
11 |
12 |
42 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 介绍
2 | form-engine基于vue+gdui2, 可解决各种各样的表单需求, 编程中使用form-editor来实现表单需求, 代码量可减少60%左右
3 |
4 | 
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 |
2 |
7 |
8 |
9 |
29 |
--------------------------------------------------------------------------------
/docs/.vuepress/theme/NavLink.vue:
--------------------------------------------------------------------------------
1 |
2 | {{ item.text }}
8 |
15 | {{ item.text }}
16 |
17 |
18 |
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 |
2 |
5 |
6 |
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 |
2 |
31 |
32 |
33 |
43 |
44 |
78 |
--------------------------------------------------------------------------------
/docs-dist/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 表单引擎
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/docs/.vuepress/theme/SWUpdatePopup.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
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 |
2 |
12 |
13 |
14 |
43 |
44 |
114 |
--------------------------------------------------------------------------------
/docs/.vuepress/theme/Sidebar.vue:
--------------------------------------------------------------------------------
1 |
2 |
20 |
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 |
2 |
3 |
8 |
9 |
10 | 表单校验
12 |
13 |
14 | {{formData}}
15 |
16 |
17 |
18 |
131 |
132 |
140 |
--------------------------------------------------------------------------------
/src/components/form-editor/form-editor.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
20 |
24 |
25 |
26 |
27 |
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 |
2 |
3 |
8 |
9 |
10 | 表单校验
12 |
13 |
14 | {{formData}}
15 |
16 |
17 |
18 |
146 |
147 |
155 |
--------------------------------------------------------------------------------
/docs/.vuepress/theme/Navbar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
15 | {{ $siteTitle }}
21 |
22 |
23 |
36 |
37 |
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 |
2 |
3 |
4 |
![hero]()
9 |
10 |
{{ data.heroText || $title || 'Hello' }}
11 |
12 |
13 | {{ data.tagline || $description || 'Welcome to your VuePress site' }}
14 |
15 |
16 |
20 |
24 |
25 |
26 |
27 |
31 |
36 |
{{ feature.title }}
37 |
{{ feature.details }}
38 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
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 |
2 |
11 |
16 |
25 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
165 |
--------------------------------------------------------------------------------
/docs/.vuepress/theme/NavLinks.vue:
--------------------------------------------------------------------------------
1 |
2 |
34 |
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 |
2 |
8 |
12 |
13 |
17 |
18 |
22 |
26 |
30 |
31 |
32 |
36 |
37 |
38 |
39 |
40 |
41 |
45 |
49 |
53 |
54 |
55 |
56 |
57 |
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 |
2 |
11 |
12 |
13 |
60 |
61 |
157 |
--------------------------------------------------------------------------------
/docs/.vuepress/theme/DropdownLink.vue:
--------------------------------------------------------------------------------
1 |
2 |
50 |
51 |
52 |
78 |
79 |
182 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/form-editor/base.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 | 表单校验
11 |
12 |
13 | {{formData}}
14 |
15 |
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("form-schemer")]),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("template")]),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("script")]),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 |
2 |
36 |
37 |
38 |
153 |
154 |
239 |
--------------------------------------------------------------------------------
/docs-dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 表单引擎
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/docs/.vuepress/theme/Page.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
19 |
20 |
24 | {{ lastUpdatedText }}:
25 | {{ lastUpdated }}
26 |
27 |
28 |
29 |
30 |
31 |
35 | ←
36 |
41 | {{ prev.title || prev.path }}
42 |
43 |
44 |
45 |
49 |
53 | {{ next.title || next.path }}
54 |
55 | →
56 |
57 |
58 |
59 |
60 |
61 |
62 |
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 | 基础用法
属性配置
props
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| value/v-model | 表单配置 | Object | — | - |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/components/form-schemer/form-schemer.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
15 | {{ typeMap[type] }}
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
40 |
44 |
47 |
51 |
52 |
53 |
54 |
55 |
56 | 模拟校验
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
287 |
--------------------------------------------------------------------------------
/src/styles/fonts/iconfont.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
90 |
--------------------------------------------------------------------------------
/docs-dist/assets/img/iconfont.46c33c79.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
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("form-editor")]),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 |
2 |
3 |
{{ title }} - 配置
4 |
8 |
9 |
10 |
11 |
12 | 常用校验规则
13 |
18 |
23 |
24 |
25 |
26 | 校验规则
27 |
28 |
29 | 必填
31 |
32 |
36 |
37 |
38 |
39 |
40 | 正则
44 |
45 |
48 |
49 |
53 |
54 |
55 |
56 |
57 | 最小
61 |
62 |
66 |
67 |
71 |
72 |
73 |
74 |
75 | 最大
79 |
80 |
84 |
85 |
89 |
90 |
91 |
92 |
93 | 长度
97 |
98 |
102 |
103 |
107 |
108 |
109 |
110 |
111 |
112 | 对象/数组代码
113 |
114 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
424 |
--------------------------------------------------------------------------------