├── .browserslistrc
├── .editorconfig
├── .env.lib
├── .eslintrc.js
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── app
├── App.vue
├── main.js
├── router.js
└── views
│ ├── test-common
│ ├── const.js
│ └── index.vue
│ └── test-extend
│ ├── const.js
│ └── index.vue
├── babel.config.js
├── deploy.sh
├── docs
├── .vuepress
│ ├── components
│ │ ├── add-item.vue
│ │ ├── attrs
│ │ │ └── select-side.vue
│ │ ├── basic-validate.vue
│ │ ├── code-contain.vue
│ │ ├── custom-input.vue
│ │ ├── custom
│ │ │ └── custom-number.vue
│ │ ├── dynamic-input.vue
│ │ ├── expand-code-mirror.vue
│ │ ├── layout-flexible.vue
│ │ ├── layout-gutter.vue
│ │ ├── layout-offset.vue
│ │ ├── slot-front.vue
│ │ ├── slot-label.vue
│ │ ├── slot-rear.vue
│ │ ├── slot-slot.vue
│ │ ├── slot-tool.vue
│ │ ├── slot-tooltip.vue
│ │ └── validate-number.vue
│ ├── config.js
│ ├── enhanceApp.js
│ ├── public
│ │ └── element-schema-form__logo.jpg
│ └── styles
│ │ └── index.styl
├── README.md
└── guide
│ ├── README.md
│ ├── component
│ ├── README.md
│ ├── SchemaForm.md
│ ├── attr.md
│ ├── custom.md
│ ├── dynamic.md
│ ├── expand.md
│ ├── layout.md
│ ├── schema.md
│ └── slot.md
│ ├── 在线示例.md
│ ├── 快速开始.md
│ └── 更新日志.md
├── lib
├── SchemaFormCodemirror.common.min.js
├── SchemaFormCodemirror.umd.min.js
├── SchemaFormQuill.common.min.js
├── SchemaFormQuill.umd.min.js
├── demo.html
├── element-schema-form.common.js
├── element-schema-form.umd.js
└── element-schema-form.umd.min.js
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
├── favicon.ico
└── index.html
├── rollup.config.js
├── src
├── components.js
├── index.js
└── packages
│ ├── SchemaForm.vue
│ ├── SchemaFormItem.vue
│ ├── components
│ ├── SchemaFormCascader.vue
│ ├── SchemaFormCheckbox.vue
│ ├── SchemaFormColorpicker.vue
│ ├── SchemaFormDatepicker.vue
│ ├── SchemaFormInput.vue
│ ├── SchemaFormPlaceholder.vue
│ ├── SchemaFormProgress.vue
│ ├── SchemaFormRadio.vue
│ ├── SchemaFormRate.vue
│ ├── SchemaFormSelect.vue
│ ├── SchemaFormSlider.vue
│ ├── SchemaFormSwitch.vue
│ ├── SchemaFormTags.vue
│ ├── SchemaFormTimepicker.vue
│ ├── SchemaFormTimeselect.vue
│ ├── schema-form-codemirror
│ │ ├── SchemaFormCodemirror.vue
│ │ └── index.js
│ ├── schema-form-jsoneditor
│ │ ├── SchemaFormJsoneditor.vue
│ │ └── index.js
│ └── schema-form-quill
│ │ ├── SchemaFormQuill.vue
│ │ └── index.js
│ └── mixins
│ ├── form-code-mirror-mixin.js
│ ├── form-json-editor-mixin.js
│ ├── form-mixin.js
│ ├── form-tags-mixin.js
│ └── layout-mixin.js
└── vue.config.js
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.{js,jsx,ts,tsx,vue}]
2 | indent_style = space
3 | indent_size = 2
4 | trim_trailing_whitespace = true
5 | insert_final_newline = true
6 |
--------------------------------------------------------------------------------
/.env.lib:
--------------------------------------------------------------------------------
1 | NODE_ENV=production
2 | VUE_APP_BUILD_MODE=lib
3 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: {
4 | node: true
5 | },
6 | 'extends': [
7 | 'plugin:vue/essential',
8 | '@vue/standard'
9 | ],
10 | rules: {
11 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
12 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
13 | },
14 | parserOptions: {
15 | parser: 'babel-eslint'
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 | /docs/.vuepress/dist
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 |
15 | # Editor directories and files
16 | .idea
17 | .vscode
18 | *.suo
19 | *.ntvs*
20 | *.njsproj
21 | *.sln
22 | *.sw?
23 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [0.1.3](https://github.com/vueblocks/element-schema-form/compare/v0.1.2...v0.1.3) (2019-11-01)
2 |
3 |
4 | ### Bug Fixes
5 |
6 | * schema-form插槽错误 ([fe43fbb](https://github.com/vueblocks/element-schema-form/commit/fe43fbb4c47984f092254536eff93c800617e6e7))
7 |
8 |
9 |
10 | ## [0.1.2](https://github.com/vueblocks/element-schema-form/compare/v0.1.1...v0.1.2) (2019-10-30)
11 |
12 |
13 |
14 | ## [0.1.1](https://github.com/vueblocks/element-schema-form/compare/v0.1.0...v0.1.1) (2019-10-29)
15 |
16 |
17 | ### Features
18 |
19 | * 新增【重置表单】功能 ([9da36a3](https://github.com/vueblocks/element-schema-form/commit/9da36a37cadf06bedabf4bbdb9994ac620fa13e3))
20 |
21 |
22 |
23 | # [0.1.0](https://github.com/vueblocks/element-schema-form/compare/9c615890fe925a11c33f3b3534381332b9867cf7...v0.1.0) (2019-10-28)
24 |
25 |
26 | ### Bug Fixes
27 |
28 | * copy 激活行数调整,api将module修改为model ([d3682be](https://github.com/vueblocks/element-schema-form/commit/d3682be362dec1c3f96ee120fcebaf27664a75e4))
29 |
30 |
31 | ### Features
32 |
33 | * 🌈完成生成 Vue 代码功能 ([215dac0](https://github.com/vueblocks/element-schema-form/commit/215dac0ce0987f5e59b3507a51f5431da59af09e))
34 | * 💥引入 vuex-persistedstate 数据持久化插件 ([e825350](https://github.com/vueblocks/element-schema-form/commit/e825350561a37de53ecb78fa4d789bc7875ada5e))
35 | * 📋添加复制代码到剪切板功能 ([8e069b3](https://github.com/vueblocks/element-schema-form/commit/8e069b36113d7357705d30acf77b208b4a8d70b9))
36 | * 修改布局算法 ([0d38a49](https://github.com/vueblocks/element-schema-form/commit/0d38a493503b80369276d6756de037571ea9847d))
37 | * 基础组件 ([9c61589](https://github.com/vueblocks/element-schema-form/commit/9c615890fe925a11c33f3b3534381332b9867cf7))
38 | * 增加json编辑器 ([3887414](https://github.com/vueblocks/element-schema-form/commit/38874147675504d40a670bacd4373dd109bc5f45))
39 | * 增加列跨度配置 ([b6d72c6](https://github.com/vueblocks/element-schema-form/commit/b6d72c60720645b02076466f3bbd67e215934b3e))
40 | * 增加拓展组件 ([d635fdd](https://github.com/vueblocks/element-schema-form/commit/d635fdd40349e93eecda0f52a9c249d2b87b0a6a))
41 | * 增加组件个性化属性(1) ([2ca9dc7](https://github.com/vueblocks/element-schema-form/commit/2ca9dc74b296f6d0de97d6493245cde3aeca5afe))
42 | * 增加组件基础属性编辑 ([30d335e](https://github.com/vueblocks/element-schema-form/commit/30d335ebede61056ca1c5c941d673a638c14429c))
43 | * 增加表单预览 ([a70c222](https://github.com/vueblocks/element-schema-form/commit/a70c2222bc5358cd2e440299d0acd78032649599))
44 | * 处理左侧布局删除列逻辑 ([c047010](https://github.com/vueblocks/element-schema-form/commit/c04701062e7eb8fbc2b59f66b8675cb15c172c5e))
45 | * 完成生成 Schema 功能 ([dcbe5c5](https://github.com/vueblocks/element-schema-form/commit/dcbe5c51500a3f6b63985597b275d954a464ac3c))
46 | * 搭建表单生成器页面 ([62d3085](https://github.com/vueblocks/element-schema-form/commit/62d30855341080e3de09b4291263fca3228cd5e5))
47 | * 新增/删除行 ([f99ad57](https://github.com/vueblocks/element-schema-form/commit/f99ad57357db78ba3fc4f31aaee6a61e17d1a49b))
48 | * 新增tag等基本组件 ([3e8c38d](https://github.com/vueblocks/element-schema-form/commit/3e8c38d56962faeb4e9f13a28f9af1fa9b8b863e))
49 | * 新增列排序功能 ([0a74c03](https://github.com/vueblocks/element-schema-form/commit/0a74c03c62e4ada86d98127566a8cb5449cc324e))
50 | * 新增行复制 ([6698e11](https://github.com/vueblocks/element-schema-form/commit/6698e11a3505fa884026ccfe981d543b82086cb4))
51 | * 新增表单列删除功能 ([c08c8c0](https://github.com/vueblocks/element-schema-form/commit/c08c8c0c44bdb3ed76d9fce333992069cfb972d6))
52 | * 新增表单配置面板 ([ecdbee5](https://github.com/vueblocks/element-schema-form/commit/ecdbee5557f6cddfe28617939f189d4f9de61992))
53 | * 私有属性调整 ([cf61919](https://github.com/vueblocks/element-schema-form/commit/cf6191953e5117db4138d255dfd438022c03ddf5))
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Vue Blocks
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # element-schema-form
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | A schema-based element-ui form component for Vue2.x.
11 |
12 | ## Installation
13 |
14 | ```bash
15 | npm i @vueblocks/element-schema-form -S
16 | ```
17 |
18 | ## Document
19 |
20 | [https://vueblocks.github.io/element-schema-form/](https://vueblocks.github.io/element-schema-form/)
21 |
22 | ## Online Demo
23 |
24 | ### 表单验证
25 |
26 | [](https://codesandbox.io/s/biaodanyanzheng-er1t1?fontsize=14&hidenavigation=1&theme=dark)
27 |
28 | ### 数字类型验证
29 |
30 | [](https://codesandbox.io/s/shuzileixingyanzheng-eezhn?fontsize=14&hidenavigation=1&theme=dark)
31 |
32 | ### 动态增减表单项
33 |
34 | [](https://codesandbox.io/s/dongtaizengjianbiaodanxiang-h0ogx?fontsize=14&hidenavigation=1&theme=dark)
35 |
36 | ## License
37 |
38 | MIT
--------------------------------------------------------------------------------
/app/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
41 |
42 |
57 |
--------------------------------------------------------------------------------
/app/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | import 'normalize.css'
4 |
5 | import router from './router'
6 |
7 | import ElementUI from 'element-ui'
8 | import 'element-ui/lib/theme-chalk/index.css'
9 |
10 | import SchemaForm, { SchemaFormItem } from '../src/index'
11 | import SchemaFormJsoneditor from '../src/packages/components/schema-form-jsoneditor'
12 | import SchemaFormQuill from '../src/packages/components/schema-form-quill'
13 | import SchemaFormCodemirror from '../src/packages/components/schema-form-codemirror'
14 | // 引入codeMirror的样式
15 | import 'codemirror/lib/codemirror.css'
16 | import 'codemirror/theme/cobalt.css'
17 | import 'codemirror/mode/javascript/javascript.js'
18 | // 引入jsoneditor的样式
19 | import 'jsoneditor/dist/jsoneditor.min.css'
20 |
21 | import App from './App.vue'
22 |
23 | Vue.use(ElementUI, {
24 | size: 'small'
25 | })
26 | Vue.component('SchemaFormJsoneditor', SchemaFormJsoneditor)
27 | Vue.component('SchemaFormQuill', SchemaFormQuill)
28 | Vue.component('SchemaFormCodemirror', SchemaFormCodemirror)
29 |
30 | Vue.component('SchemaFormItem', SchemaFormItem)
31 |
32 | Vue.use(SchemaForm, {
33 | 'codemirror': {
34 | cmOptions: {
35 | tabSize: 2,
36 | mode: 'text/javascript',
37 | theme: 'cobalt',
38 | lineNumbers: true,
39 | line: true
40 | }
41 | },
42 | input: {
43 | placeholder: '全局定义变量实验'
44 | }
45 | })
46 |
47 | Vue.config.productionTip = false
48 |
49 | new Vue({
50 | router,
51 | render: h => h(App)
52 | }).$mount('#app')
53 |
--------------------------------------------------------------------------------
/app/router.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 |
4 | Vue.use(Router)
5 |
6 | export default new Router({
7 | routes: [
8 | {
9 | path: '/',
10 | redirect: '/test-common'
11 | },
12 | {
13 | path: '/test-common',
14 | component: () => import('@/views/test-common/index.vue')
15 | },
16 | {
17 | path: '/test-extend',
18 | component: () => import('@/views/test-extend/index.vue')
19 | }
20 | ]
21 | })
22 |
--------------------------------------------------------------------------------
/app/views/test-common/const.js:
--------------------------------------------------------------------------------
1 | export const model = {
2 | name: 'lk',
3 | age: '18',
4 | phone: '',
5 | sex: 'male',
6 | expire: '',
7 | location: [],
8 | isOn: false,
9 | city: ['beijing'],
10 | sliderVal: 60,
11 | sleepTime: '',
12 | star: 0,
13 | color: '#409EFF',
14 | label: ['小清新'],
15 | percent: 20
16 | }
17 | export const schema = [
18 | [
19 | {
20 | type: 'input',
21 | prop: 'name',
22 | formItem: { label: '电话' },
23 | attrs: { placeholder: '测试优先级' },
24 | colGrid: { span: 8 },
25 | labelSlot: 'inputName'
26 | }, {
27 | type: 'input',
28 | prop: 'age',
29 | formItem: { label: '年龄' },
30 | colGrid: { span: 8 },
31 | labelTooltip: '初三'
32 | }
33 | ],
34 | [
35 | {
36 | type: 'select',
37 | prop: 'phone',
38 | formItem: { label: '电话' }
39 | },
40 | {
41 | type: 'radio',
42 | prop: 'sex',
43 | formItem: { label: '性别' }
44 | }, {
45 | type: 'datepicker',
46 | prop: 'expire',
47 | formItem: { label: '有效期' },
48 | attrs: {
49 | type: 'monthrange',
50 | 'range-separator': '至',
51 | 'start-placeholder': '开始月份',
52 | 'end-placeholder': '结束月份'
53 | }
54 | }
55 | ],
56 | [
57 | { type: 'cascader',
58 | prop: 'location',
59 | formItem: { label: '地域' },
60 | attrs: { 'show-all-levels': false }
61 | }, {
62 | type: 'switch',
63 | prop: 'isOn',
64 | formItem: { label: '开关' }
65 | }, {
66 | type: 'checkbox',
67 | prop: 'city',
68 | formItem: { label: '地域' }
69 | }
70 | ],
71 | [
72 | {
73 | type: 'slider',
74 | prop: 'sliderVal',
75 | formItem: { label: '成绩' },
76 | attrs: { 'show-stops': true, step: 10 }
77 | }, {
78 | type: 'timepicker',
79 | prop: 'sleepTime',
80 | formItem: { label: '晚睡时间' },
81 | attrs: {
82 | 'picker-options': {
83 | selectableRange: '18:30:00 - 20:30:00'
84 | },
85 | 'arrow-control': true
86 | }
87 | }, {
88 | type: 'rate',
89 | prop: 'star',
90 | formItem: { label: '观影得分' }
91 | }
92 | ],
93 | [
94 | {
95 | type: 'colorpicker',
96 | prop: 'color',
97 | formItem: { label: '颜色' }
98 | }, {
99 | type: 'tags',
100 | prop: 'label',
101 | formItem: { label: '标签' },
102 | attrs: { size: 'medium', buttonSize: 'mini', 'show-add': true }
103 | }, {
104 | type: 'progress',
105 | prop: 'percent',
106 | formItem: { label: '进度' }
107 | }
108 | ]
109 | ]
110 | export const options = {
111 | phone: [{ label: '1881031****', value: '1881031****' }, { label: '1861031****', value: '1861031****' }],
112 | sex: [{ label: '男', value: 'male' }, { label: '女', value: 'female' }],
113 | location: [
114 | { label: '北京', value: 'beijing', children: [{ label: '通州', value: 'tongzhou' }] },
115 | { label: '天津', value: 'tianjin' }
116 | ],
117 | city: [
118 | { label: '北京', value: 'beijing' },
119 | { label: '上海', value: 'shanghai' },
120 | { label: '广州', value: '广州', disabled: true }
121 | ]
122 | }
123 |
--------------------------------------------------------------------------------
/app/views/test-common/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
12 |
13 |
14 |
17 |
18 |
19 |
20 |
57 |
58 |
61 |
--------------------------------------------------------------------------------
/app/views/test-extend/const.js:
--------------------------------------------------------------------------------
1 | export const model = {
2 | json: {
3 | a: 10,
4 | b: 20,
5 | customer: 10
6 | },
7 | quill: '一段文字
',
8 | code: 'let a = 100'
9 | }
10 | export const schema = [
11 | [
12 | {
13 | type: 'jsoneditor',
14 | prop: 'json',
15 | frontSlot: 'json',
16 | formItem: { label: '' },
17 | attrs: { mode: 'code' }
18 | }
19 | ],
20 | [
21 | {
22 | type: 'quill',
23 | prop: 'quill',
24 | formItem: { label: '富文本编辑' },
25 | attrs: { 'editor-toolbar': [
26 | ['bold', 'italic', 'underline'],
27 | [{ list: 'ordered' }, { list: 'bullet' }],
28 | ['code-block']]
29 | }
30 | }
31 | ],
32 | [
33 | {
34 | type: 'codemirror',
35 | prop: 'code',
36 | formItem: { label: '代码镜像' }
37 | }
38 | ]
39 | ]
40 | export const options = {}
41 |
--------------------------------------------------------------------------------
/app/views/test-extend/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 | 预览
12 |
13 |
14 |
15 |
16 |
17 |
77 |
78 |
85 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | const plugins = [
2 | 'lodash',
3 | [
4 | 'component',
5 | {
6 | 'libraryName': 'element-ui',
7 | 'styleLibraryName': '~theme'
8 | }
9 | ]
10 | ]
11 |
12 | // 生产模式使用 transform-remove-console 插件
13 | if (process.env.NODE_ENV === 'production') {
14 | plugins.push('transform-remove-console')
15 | }
16 |
17 | module.exports = {
18 | presets: [
19 | '@vue/cli-plugin-babel/preset'
20 | ],
21 | plugins
22 | }
23 |
--------------------------------------------------------------------------------
/deploy.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | # 确保脚本抛出遇到的错误
4 | set -e
5 |
6 | # 生成静态文件
7 | npm run docs:build
8 |
9 | # 进入生成的文件夹
10 | cd docs/.vuepress/dist
11 |
12 | # 如果是发布到自定义域名
13 | # echo 'www.example.com' > CNAME
14 |
15 | git init
16 | git add -A
17 | git commit -m 'chore: deploy docs'
18 |
19 | # 如果发布到 https://.github.io
20 | # git push -f git@github.com:/.github.io.git master
21 |
22 | # 如果发布到 https://.github.io/
23 | git push -f https://github.com/vueblocks/element-schema-form.git master:gh-pages
24 |
25 | cd -
--------------------------------------------------------------------------------
/docs/.vuepress/components/add-item.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 | 删除
17 |
18 | 立即创建
19 | 新增域名
20 | 重置
21 |
22 |
23 |
24 |
25 |
26 |
27 |
89 |
90 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/attrs/select-side.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 |
12 |
43 |
44 |
52 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/basic-validate.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 | 立即创建
13 | 重置
14 |
15 |
16 |
17 |
18 |
19 |
20 |
137 |
138 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/code-contain.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
{{visible ? '隐藏代码' : '显示代码'}}
11 |
在线运行
12 |
13 |
14 |
15 |
16 |
75 |
76 |
81 |
82 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/custom-input.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
30 |
31 |
34 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/custom/custom-number.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
20 |
21 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/dynamic-input.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
44 |
45 |
48 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/expand-code-mirror.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
46 |
47 |
50 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/layout-flexible.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
14 |
15 |
16 |
17 |
18 |
37 |
38 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/layout-gutter.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
14 |
15 |
16 |
17 |
18 |
37 |
38 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/layout-offset.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
13 |
14 |
15 |
16 |
17 |
38 |
39 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/slot-front.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 | 姓名
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
38 |
39 |
42 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/slot-label.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 | 标签插槽
9 |
10 |
11 |
12 |
13 |
14 |
37 |
38 |
43 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/slot-rear.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 | {{model.name.length}}字
9 |
10 |
11 |
12 |
13 |
14 |
36 |
37 |
45 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/slot-slot.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
28 |
29 |
32 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/slot-tool.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
33 |
34 |
39 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/slot-tooltip.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
34 |
35 |
40 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/validate-number.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 | 立即创建
10 | 重置
11 |
12 |
13 |
14 |
15 |
16 |
17 |
56 |
57 |
--------------------------------------------------------------------------------
/docs/.vuepress/config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | title: 'Element Schema Form',
3 | description: '基于 JSON Schema 构建 Element 表单,表单页面开发从未如此高效',
4 | base: '/element-schema-form/',
5 | port: 5454,
6 | themeConfig: {
7 | sidebarDepth: 2,
8 | nav: [
9 | { text: '指南', link: '/guide/' },
10 | { text: '组件', link: '/guide/component/SchemaForm/' },
11 | {
12 | text: '表单设计器',
13 | link: 'https://vueblocks.github.io/element-form-generator/'
14 | },
15 | {
16 | text: 've-charts',
17 | link: 'https://github.com/vueblocks/ve-charts'
18 | },
19 | {
20 | text: 'GitHub',
21 | link: 'https://github.com/vueblocks/element-schema-form'
22 | },
23 | ],
24 | sidebar: {
25 | '/guide/': [
26 | {
27 | title: '指南',
28 | collapsable: false,
29 | children: [
30 | '',
31 | '快速开始',
32 | '更新日志',
33 | '在线示例',
34 | ]
35 | },
36 | {
37 | title: '组件',
38 | collapsable: false,
39 | sidebarDepth: 1,
40 | children: [
41 | '/guide/component/SchemaForm',
42 | ['/guide/component/schema', 'schema 详解'],
43 | ['/guide/component/layout', 'layout 布局'],
44 | ['/guide/component/slot', 'slot 插槽'],
45 | ['/guide/component/dynamic', 'dynamicAttrs 动态属性'],
46 | ['/guide/component/custom', '自定义组件'],
47 | ['/guide/component/expand', '第三方拓展'],
48 | ['/guide/component/attr', '拓展属性']
49 | ]
50 | }
51 | ]
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/docs/.vuepress/enhanceApp.js:
--------------------------------------------------------------------------------
1 | import SchemaForm from '../../src/index.js'
2 | import ElementUI from "element-ui"
3 | import CustomNumber from './components/custom/custom-number.vue'
4 |
5 | import "element-ui/lib/theme-chalk/index.css"
6 | import '@vuepress/theme-default'
7 |
8 |
9 | export default ({ Vue }) => {
10 | Vue.use(SchemaForm)
11 | Vue.use(ElementUI)
12 | // Vue.use(SchemaFormQuill)
13 | Vue.component('CustomNumber', CustomNumber)
14 | }
15 |
--------------------------------------------------------------------------------
/docs/.vuepress/public/element-schema-form__logo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vueblocks/element-schema-form/ff2a3ae205d3034d0dd38ab666c68eb2171cc2de/docs/.vuepress/public/element-schema-form__logo.jpg
--------------------------------------------------------------------------------
/docs/.vuepress/styles/index.styl:
--------------------------------------------------------------------------------
1 |
2 | table thead th {
3 | color: #909399;
4 | font-size: 14px;
5 | }
6 | table tbody td {
7 | color: #606266;
8 | font-size: 14px;
9 | }
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | home: true
3 | heroImage: /element-schema-form__logo.jpg
4 | actionText: 快速开始 →
5 | actionLink: /guide/
6 | features:
7 | - title: JSON Schema Based
8 | details: 基于 JSON Schema 规范的数据驱动
9 | - title: Element UI Based
10 | details: 基于 Element UI 组件库的 Form 表单
11 | - title: Responsive Form
12 | details: 灵活的响应式的栅格表单布局
13 | footer: MIT Licensed | Copyright © 2019-present VueBlocks
14 | ---
--------------------------------------------------------------------------------
/docs/guide/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | {
3 | "title": "介绍",
4 | }
5 | ---
6 |
7 | ## 背景
8 |
9 | 前端领域里,在中后台实际业务场景中,基本上逃不过表单页面的开发,表单页面承担着数据输入的角色,是数据收集的重要来源。
10 |
11 | 而对于工程中使用 **Element** 作为UI组件库的项目而言,前端开发者在使用 `el-form` 的时候可能更多的都在关注:
12 |
13 | * 如何布局表单
14 | * 表单控件类型
15 | * 表单控件配置项
16 | * 表单的状态管理
17 | * 表单校验
18 |
19 | 从而为了实现一个业务场景复杂的表单,往往要编写大量重复的代码,以及产生篇幅巨大的单页面组件,而这样的开发方式是不必要的。
20 |
21 | ## 方案
22 |
23 | 经过我们在表单领域的不断探索与尝试,总结出了一套基于 **JSON Schema** 规范的数据动态生成表单的解决方案 **Element Schema Form**。
24 |
25 | **Element Schema Form** 是一个基于 `Vue`、`element-ui` 技术栈封装的表单组件,用于解决大型、复杂表单页面开发过程中所做的大量重复性工作。使用一份 JSON Schema 即可生成一个成型的 form 表单,使表单组件代码变得简洁并便于维护。开发表单更高效。
26 |
27 | ## 核心功能
28 |
29 | * 基于 JSON Schema 的数据结构生成表单
30 | * 基于 `el-row`/`el-col` 的灵活表单布局
31 | * 支持所有 `element-ui` 基础表单组件
32 | * 支持常用第三方扩展组件,如 `codemirror`、`quill editor`、`markdown editor` 等
33 | * 支持个性化的自定义插槽组件
34 | * 支持可视化构建表单
35 |
36 | ## JSON Schema 规范
37 |
38 | 如果你还不了解什么是 JSON Schema,请移步这里 [JSON Schema](https://json-schema.org/)
39 |
40 | ## 可视化探索
41 |
42 | 为了开发更高效,我们提供了基于 **Element Schema Form** 开发的可视化配置工具
43 |
44 | 表单设计器 [element-form-generator](https://github.com/vueblocks/element-form-generator)
45 |
46 | 只需简单操作几步即可配置好一个 form 表单
47 |
--------------------------------------------------------------------------------
/docs/guide/component/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | {
3 | "title": "组件",
4 | }
5 | ---
--------------------------------------------------------------------------------
/docs/guide/component/SchemaForm.md:
--------------------------------------------------------------------------------
1 | ---
2 | {
3 | "title": "SchemaForm",
4 | }
5 | ---
6 |
7 |
8 | ## 组件使用
9 |
10 | ```vue
11 |
12 |
13 |
19 |
20 |
21 |
22 |
23 |
39 | ```
40 |
41 | ## Props
42 |
43 | ### layout
44 |
45 | #### 表单布局信息,详见 [layout布局](layout.html)
46 |
47 |
48 | ### model
49 |
50 | #### 表单数据对象,表单绑定值的集合,例如
51 | ``` js
52 | {
53 | model: {
54 | name: '',
55 | age: ''
56 | }
57 | }
58 | ```
59 |
60 | ### schema
61 | #### 表单模板,用于表单的构建。详情见 [schema 详解](schema.html)
62 |
63 | 参数|说明|类型|可选值|默认值
64 | :--|:--|:--|:--|:--
65 | prop|数据字段|string|-|-
66 | type|组件类型|string|-|-
67 | formItem|表单属性|object|-|-
68 | modifier|修饰符|string|number,trim|-
69 | attrs|组件属性|object|-|-
70 | dynamicAttrs|组件动态属性| object|-|-
71 | on|组件事件|object|-|-
72 | hide|是否隐藏|boolean|-|false
73 | colGrid|栅格布局,与el-col属性相同|object|-|-
74 |
75 | ### options
76 |
77 | #### 表单可选数据源,如我们常用的 el-select 的数据源
78 | ``` js
79 | {
80 | options: {
81 | foods: [
82 | {
83 | value: '选项1',
84 | label: '黄金糕'
85 | }, {
86 | value: '选项2',
87 | label: '双皮奶'
88 | }]
89 | }
90 | }
91 | ```
--------------------------------------------------------------------------------
/docs/guide/component/attr.md:
--------------------------------------------------------------------------------
1 | ### 拓展属性
2 |
3 | ### select 拓展
4 |
5 | 新增 `optionSides` 属性,用于适应下拉框中展示多种属性
6 |
7 |
8 | <<< @/docs/.vuepress/components/attrs/select-side.vue
9 |
10 |
--------------------------------------------------------------------------------
/docs/guide/component/custom.md:
--------------------------------------------------------------------------------
1 | ### 自定义组件
2 |
3 | SchemaForm 组件提供了便于创建自定义组件的方案,使用 `FormMixin` 创建你的自定义组件
4 |
5 | #### 创建自定义组件
6 |
7 | ``` vue
8 | // @/components/CustomNumber.vue
9 |
10 |
15 |
16 |
17 |
24 | ```
25 |
26 | #### main.js 全局引入组件
27 |
28 | ``` js
29 | import ElementUI from 'element-ui'
30 | import 'element-ui/lib/theme-chalk/index.css'
31 | import SchemaForm from '@vueblocks/element-schema-form'
32 | import CustomNumber from '@/components/CustomNumber.vue'
33 |
34 | Vue.use(ElementUI)
35 | Vue.use(SchemaForm)
36 | Vue.component('CustomNumber', CustomNumber)
37 | ```
38 |
39 | #### 使用自定义组件
40 |
41 |
42 | <<< @/docs/.vuepress/components/custom-input.vue
43 |
--------------------------------------------------------------------------------
/docs/guide/component/dynamic.md:
--------------------------------------------------------------------------------
1 | ### 使用动态属性联动
2 |
3 |
4 | <<< @/docs/.vuepress/components/dynamic-input.vue
5 |
--------------------------------------------------------------------------------
/docs/guide/component/expand.md:
--------------------------------------------------------------------------------
1 | ## codemirror
2 |
3 | 基于 [vue-codemirror-lite](https://github.com/cnu4/vue-codemirror-lite) 拓展的组件
4 |
5 | 安装组件依赖
6 | ``` js
7 | npm i vue-codemirror-lite -S
8 | ```
9 | main.js 按需引入 SchemaFormCodemirror 组件, 语言模式和主题
10 |
11 | ``` js
12 | import SchemaFormCodemirror from '@vueblocks/element-schema-form/lib/SchemaFormCodemirror.common.min.js'
13 |
14 | import 'codemirror/lib/codemirror.css'
15 | import 'codemirror/theme/night.css' // theme: night
16 | import 'codemirror/mode/javascript/javascript.js' // mode: text/javascript
17 |
18 | Vue.use(SchemaFormCodemirror)
19 | ```
20 |
21 | <<< @/docs/.vuepress/components/expand-code-mirror.vue
22 |
23 | 查看 [CodeMirror Manual](https://codemirror.net/doc/manual.html#modloader) 了解更多配置和主题
24 |
25 | ## quill
26 |
27 | 基于 [vue2-editor](https://github.com/davidroyer/vue2-editor) 拓展的组件
28 |
29 | 安装组件依赖
30 | ``` js
31 | npm i vue2-editor -S
32 | ```
33 | main.js 按需引入 SchemaFormQuill 组件
34 |
35 | ``` js
36 | import SchemaFormQuill from '@vueblocks/element-schema-form/lib/SchemaFormQuill.common.min.js'
37 |
38 | Vue.use(SchemaFormQuill)
39 | ```
40 |
41 | 使用
42 | ``` js
43 |
44 |
45 |
49 |
50 |
51 |
52 |
53 |
76 | ```
--------------------------------------------------------------------------------
/docs/guide/component/layout.md:
--------------------------------------------------------------------------------
1 |
2 | ### 简介
3 |
4 | SchemaForm 整体布局采用 el-row 和 el-col 进行封装, 通过基础的24分栏,迅速简便地创建布局
5 |
6 | ### 分栏间隔
7 |
8 |
9 | <<< @/docs/.vuepress/components/layout-gutter.vue
10 |
11 |
12 | ### 分栏偏移
13 |
14 |
15 | <<< @/docs/.vuepress/components/layout-offset.vue
16 |
17 |
18 | ### 响应式布局
19 |
20 |
21 | <<< @/docs/.vuepress/components/layout-flexible.vue
22 |
23 |
24 | ### layout Attributes
25 |
26 | 参数|说明|类型|可选值|默认值
27 | :--|:--|:--|:--|:--|
28 | gutter|栅格间隔|number|—|0
29 | type|布局模式,可选 flex,现代浏览器下有效|string|—|—
30 | justify|flex布局下的水平排列方式|string|start/end/center/space-around/space-between|start
31 | align|flex布局下的垂直排列方式|string|top/middle/bottom|top
32 | tag|自定义元素标签|string|*|div
33 |
34 | ### colGrid Attributes
35 |
36 | 参数|说明|类型|可选值|默认值
37 | :--|:--|:--|:--|:--|
38 | span|栅格占据的列数|number|—|24
39 | offset|栅格左侧的间隔格数|number|—|0
40 | push|栅格向右移动格数|number|—|0
41 | pull|栅格向左移动格数|number|—|0
42 | xs|<768px|响应式栅格数或者栅格属性对象|number/object (例如: {span: 4, offset: 4})|—|—
43 | sm|≥768px|响应式栅格数或者栅格属性对象|number/object (例如: {span: 4, offset: 4})|—|—
44 | md|≥992px|响应式栅格数或者栅格属性对象|number/object (例如: {span: 4, offset: 4})|—|—
45 | lg|≥1200px|响应式栅格数或者栅格属性对象|number/object (例如: {span: 4, offset: 4})|—|—
46 | xl|≥1920px|响应式栅格数或者栅格属性对象|number/object (例如: {span: 4, offset: 4})|—|—
47 | tag|自定义元素标签|string * div
48 |
--------------------------------------------------------------------------------
/docs/guide/component/schema.md:
--------------------------------------------------------------------------------
1 | ## 数据字段 prop
2 |
3 | > prop 是辨别当前组件的唯一字段,既是 ```model 和 options 的键值 key ```,又是```el-form``` 使用 ```validate、resetFields``` 方法的必填字段,所以需保证 prop的 唯一性
4 |
5 | ## 组件类型 type
6 |
7 | > SchemaForm 的组件是基于 Element 进行封装,目标是完美兼容原组件的所有属性
8 |
9 | ### 内置类型
10 |
11 | 类型|含义|属性参考
12 | :--|:--|:--
13 | input| 输入框 | [el-input](https://element.eleme.cn/#/zh-CN/component/input)
14 | select| 选择器 | [el-select](https://element.eleme.cn/#/zh-CN/component/select)
15 | radio| 单选框组 | [el-radio-group](https://element.eleme.cn/#/zh-CN/component/radio)
16 | checkbox| 多选框组 | [el-checkbox-group](https://element.eleme.cn/#/zh-CN/component/checkbox)
17 | cascader| 级联选择器 | [el-cascader](https://element.eleme.cn/#/zh-CN/component/cascader)
18 | switch| 开关 | [el-switch](https://element.eleme.cn/#/zh-CN/component/switch)
19 | slider| 滑块 | [el-slider](https://element.eleme.cn/#/zh-CN/component/slider)
20 | datepicker| 日期选择器 | [el-date-picker](https://element.eleme.cn/#/zh-CN/component/date-picker)
21 | timeselect| 固定时间 | [el-time-select](https://element.eleme.cn/#/zh-CN/component/time-picker)
22 | timepicker| 任意时间 | [el-time-picker](https://element.eleme.cn/#/zh-CN/component/time-picker)
23 | colorpicker| 颜色选择器 | [el-color-picker](https://element.eleme.cn/#/zh-CN/component/color-picker)
24 | progress| 进度条 | [el-progress](https://element.eleme.cn/#/zh-CN/component/progress)
25 | rate| 评分 | [el-rate](https://element.eleme.cn/#/zh-CN/component/rate)
26 |
27 | ## 表单属性 formItem
28 |
29 | > 兼容所有el-form-item的属性,以下内容为常用属性
30 |
31 | 参数|说明|类型|可选值|默认值
32 | :--|:--|:--|:--|:--
33 | label|标签文本|string|—|—
34 | label-width|表单域标签的的宽度,例如 '50px'。支持 auto|string|—|—
35 | show-message|是否显示校验错误信息|boolean|—|true
36 | inline-message|以行内形式展示校验信息|boolean|—|false
37 | size|用于控制该表单域下组件的尺寸|string|medium / small / mini|-
38 |
39 | ## 绑定值修饰符 modifier
40 |
41 | > 为了更好的支持数值绑定,增加了```v-model```的修饰符,现支持
42 |
43 | 参数|说明
44 | :--|:--
45 | number|自动将用户的输入值转为数值类型
46 | trim|自动过滤用户输入的首尾空白字符
47 |
48 | ## 属性绑定 attrs
49 |
50 | > 支持Element组件的属性,以```el-input```为例,具体参数 可参考 [Element](https://element.eleme.cn/#/zh-CN)
51 |
52 | ``` js
53 | {
54 | type: 'input',
55 | prop: 'name',
56 | attrs: { type: 'textarea' }
57 | }
58 | ```
59 |
60 | ## 动态属性绑定 dynamicAttrs
61 |
62 | > 除了绑定的静态属性外,还支持动态属性的绑定,例如用于与其它操作联动
63 |
64 | ``` js
65 | {
66 | type: 'input',
67 | prop: 'name',
68 | dynamicAttrs: { disabled: !!this.model.id }
69 | }
70 | ```
71 |
72 | ## 事件绑定 on
73 |
74 | > 支持Element组件的事件,以```el-input```为例,具体参数 可参考 [Element](https://element.eleme.cn/#/zh-CN)
75 |
76 | ``` js
77 | {
78 | type: 'input',
79 | prop: 'name',
80 | on: { focus: this.onNameFocus }
81 | }
82 | ```
83 |
84 | ### 事件 & 按键修饰符
85 |
86 | > 对于 .passive、.capture 和 .once 这些事件修饰符, Vue 提供了相应的前缀可以用于 on
87 |
88 | 修饰符|前缀
89 | :--|:--
90 | .passive|&
91 | .capture|!
92 | .once|~
93 | .capture.once 或 .once.capture|~!
94 |
95 | ``` js
96 | on: {
97 | '!click': this.doThisInCapturingMode,
98 | '~keyup': this.doThisOnce,
99 | '~!mouseover': this.doThisOnceInCapturingMode
100 | }
101 | ```
102 |
103 | > 对于所有其它的修饰符,私有前缀都不是必须的,因为你可以在事件处理函数中使用事件方法:
104 |
105 | ``` js
106 | on: {
107 | keyup: function (event) {
108 | // .self 等价于 如果触发事件的元素不是事件绑定的元素则返回
109 | if (event.target !== event.currentTarget) return
110 | // 如果按下去的不是 enter 键或者
111 | // 没有同时按下 shift 键
112 | // 则返回
113 | if (!event.shiftKey || event.keyCode !== 13) return
114 | // 阻止 事件冒泡
115 | event.stopPropagation()
116 | // 阻止该元素默认的 keyup 事件
117 | event.preventDefault()
118 | // ...
119 | }
120 | }
121 | ```
122 |
123 | ## 插槽 slot
124 |
125 | 参数|说明|
126 | :--|:--
127 | slot| 自定义完整组件
128 | labelSlot| 用于 el-form-item 中的 label插槽
129 | frontSlot| 定义element 组件前的插槽
130 | rearSlot| 定义element 组件后的插槽
131 |
--------------------------------------------------------------------------------
/docs/guide/component/slot.md:
--------------------------------------------------------------------------------
1 | ### 插槽
2 |
3 |
4 | <<< @/docs/.vuepress/components/slot-slot.vue
5 |
6 |
7 | ### 前置插槽
8 |
9 |
10 | <<< @/docs/.vuepress/components/slot-front.vue
11 |
12 |
13 | ### 后置插槽
14 |
15 |
16 | <<< @/docs/.vuepress/components/slot-rear.vue
17 |
18 |
19 |
20 | ### 标签插槽
21 |
22 |
23 | <<< @/docs/.vuepress/components/slot-label.vue
24 |
25 |
26 | ### 自定义前置/后置文本
27 |
28 | <<< @/docs/.vuepress/components/slot-tool.vue
29 |
30 |
31 | ### 自定义标题说明
32 |
33 | <<< @/docs/.vuepress/components/slot-tooltip.vue
34 |
--------------------------------------------------------------------------------
/docs/guide/在线示例.md:
--------------------------------------------------------------------------------
1 | ---
2 | {
3 | "title": "在线示例",
4 | }
5 | ---
6 |
7 | ### 表单验证
8 |
9 |
10 | <<< @/docs/.vuepress/components/basic-validate.vue
11 |
12 |
13 | ### 数字类型验证
14 |
15 |
16 | <<< @/docs/.vuepress/components/validate-number.vue
17 |
18 |
19 | ### 动态增减表单项
20 |
21 |
22 | <<< @/docs/.vuepress/components/add-item.vue
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/docs/guide/快速开始.md:
--------------------------------------------------------------------------------
1 | ---
2 | {
3 | "title": "快速开始",
4 | }
5 | ---
6 |
7 | ## 安装
8 |
9 | ```bash
10 | npm i @vueblocks/element-schema-form -S
11 | ```
12 |
13 | or
14 |
15 | ```bash
16 | yarn add @vueblocks/element-schema-form
17 | ```
18 |
19 | ## 引入组件
20 |
21 | 完整引入
22 |
23 | ```js
24 | import SchemaForm from '@vueblocks/element-schema-form'
25 |
26 | Vue.use(SchemaForm)
27 | ```
28 |
29 | ## 引入第三方扩展
30 |
31 | `SchemaForm` 支持一些用于表单渲染的高级组件
32 |
33 | 例如 `codemirror`,使用前需要安装组件依赖
34 |
35 | ```bash
36 | npm i codemirror vue-codemirror-lite -S
37 | ```
38 |
39 | 按需引入 `SchemaFormCodemirror` 组件
40 |
41 | ```js
42 | import SchemaFormCodemirror from '@vueblocks/element-schema-form/lib/SchemaFormCodemirror.common.min'
43 |
44 | Vue.component('SchemaFormCodemirror', SchemaFormCodemirror)
45 | ```
46 |
47 | ## 组件预设配置
48 |
49 | ```js
50 | // input 输入框 placeholder 预设
51 | Vue.use(SchemaForm, {
52 | input: {
53 | placeholder: '全局定义变量实验'
54 | }
55 | })
56 |
57 | // codemirror 插件配置项预设
58 | Vue.use(SchemaForm, {
59 | 'codemirror': {
60 | cmOptions: {
61 | tabSize: 2,
62 | mode: 'text/javascript',
63 | theme: 'cobalt',
64 | lineNumbers: true,
65 | line: true
66 | }
67 | }
68 | })
69 | ```
70 |
--------------------------------------------------------------------------------
/docs/guide/更新日志.md:
--------------------------------------------------------------------------------
1 | ---
2 | { "title": "更新日志" }
3 | ---
4 |
5 | ## 0.1.8 (2021-10-25)
6 |
7 | - select 选择器拓展 `optionSides`, 丰富下拉展示
8 |
9 | ## 0.1.7 (2021-02-20)
10 |
11 | - 增加新属性 labelTooltip, 用于自定义标题的说明
12 | - 增加标签插槽 labelSlot
13 |
14 | ## 0.1.6 (2021-01-22)
15 |
16 | ### feat
17 |
18 | - 增加属性 rearHtml、frontHtml ([89b9aa8](https://github.com/vueblocks/element-schema-form/commit/89b9aa8b7cefbd81da8d08e6ae9d857d69809b6b))
19 |
20 | ## [0.1.4](https://github.com/vueblocks/element-schema-form/compare/v0.1.3...v0.1.4) (2019-12-03)
21 |
22 | ### feat
23 |
24 | - 增加 timepicker 任意时间点选择 ([fcf5a3f](https://github.com/vueblocks/element-schema-form/commit/fcf5a3f3c1c275d7d1e02b0e25e2a7ac06638e6b))
25 |
26 | ## [0.1.3](https://github.com/vueblocks/element-schema-form/compare/v0.1.2...v0.1.3) (2019-11-01)
27 |
28 | ### Bug Fixes
29 |
30 | - schema-form 插槽错误 ([fe43fbb](https://github.com/vueblocks/element-schema-form/commit/fe43fbb4c47984f092254536eff93c800617e6e7))
31 |
32 | ## [0.1.2](https://github.com/vueblocks/element-schema-form/compare/v0.1.1...v0.1.2) (2019-10-30)
33 |
34 | ## [0.1.1](https://github.com/vueblocks/element-schema-form/compare/v0.1.0...v0.1.1) (2019-10-29)
35 |
36 | ### Features
37 |
38 | - 新增【重置表单】功能 ([9da36a3](https://github.com/vueblocks/element-schema-form/commit/9da36a37cadf06bedabf4bbdb9994ac620fa13e3))
39 |
40 | ## [0.1.0](https://github.com/vueblocks/element-schema-form/compare/9c615890fe925a11c33f3b3534381332b9867cf7...v0.1.0) (2019-10-28)
41 |
42 | ### Bug Fixes
43 |
44 | - copy 激活行数调整,api 将 module 修改为 model ([d3682be](https://github.com/vueblocks/element-schema-form/commit/d3682be362dec1c3f96ee120fcebaf27664a75e4))
45 |
46 | ### Features
47 |
48 | - 🌈 完成生成 Vue 代码功能 ([215dac0](https://github.com/vueblocks/element-schema-form/commit/215dac0ce0987f5e59b3507a51f5431da59af09e))
49 | - 💥 引入 vuex-persistedstate 数据持久化插件 ([e825350](https://github.com/vueblocks/element-schema-form/commit/e825350561a37de53ecb78fa4d789bc7875ada5e))
50 | - 📋 添加复制代码到剪切板功能 ([8e069b3](https://github.com/vueblocks/element-schema-form/commit/8e069b36113d7357705d30acf77b208b4a8d70b9))
51 | - 修改布局算法 ([0d38a49](https://github.com/vueblocks/element-schema-form/commit/0d38a493503b80369276d6756de037571ea9847d))
52 | - 基础组件 ([9c61589](https://github.com/vueblocks/element-schema-form/commit/9c615890fe925a11c33f3b3534381332b9867cf7))
53 | - 增加 json 编辑器 ([3887414](https://github.com/vueblocks/element-schema-form/commit/38874147675504d40a670bacd4373dd109bc5f45))
54 | - 增加列跨度配置 ([b6d72c6](https://github.com/vueblocks/element-schema-form/commit/b6d72c60720645b02076466f3bbd67e215934b3e))
55 | - 增加拓展组件 ([d635fdd](https://github.com/vueblocks/element-schema-form/commit/d635fdd40349e93eecda0f52a9c249d2b87b0a6a))
56 | - 增加组件个性化属性(1) ([2ca9dc7](https://github.com/vueblocks/element-schema-form/commit/2ca9dc74b296f6d0de97d6493245cde3aeca5afe))
57 | - 增加组件基础属性编辑 ([30d335e](https://github.com/vueblocks/element-schema-form/commit/30d335ebede61056ca1c5c941d673a638c14429c))
58 | - 增加表单预览 ([a70c222](https://github.com/vueblocks/element-schema-form/commit/a70c2222bc5358cd2e440299d0acd78032649599))
59 | - 处理左侧布局删除列逻辑 ([c047010](https://github.com/vueblocks/element-schema-form/commit/c04701062e7eb8fbc2b59f66b8675cb15c172c5e))
60 | - 完成生成 Schema 功能 ([dcbe5c5](https://github.com/vueblocks/element-schema-form/commit/dcbe5c51500a3f6b63985597b275d954a464ac3c))
61 | - 搭建表单生成器页面 ([62d3085](https://github.com/vueblocks/element-schema-form/commit/62d30855341080e3de09b4291263fca3228cd5e5))
62 | - 新增/删除行 ([f99ad57](https://github.com/vueblocks/element-schema-form/commit/f99ad57357db78ba3fc4f31aaee6a61e17d1a49b))
63 | - 新增 tag 等基本组件 ([3e8c38d](https://github.com/vueblocks/element-schema-form/commit/3e8c38d56962faeb4e9f13a28f9af1fa9b8b863e))
64 | - 新增列排序功能 ([0a74c03](https://github.com/vueblocks/element-schema-form/commit/0a74c03c62e4ada86d98127566a8cb5449cc324e))
65 | - 新增行复制 ([6698e11](https://github.com/vueblocks/element-schema-form/commit/6698e11a3505fa884026ccfe981d543b82086cb4))
66 | - 新增表单列删除功能 ([c08c8c0](https://github.com/vueblocks/element-schema-form/commit/c08c8c0c44bdb3ed76d9fce333992069cfb972d6))
67 | - 新增表单配置面板 ([ecdbee5](https://github.com/vueblocks/element-schema-form/commit/ecdbee5557f6cddfe28617939f189d4f9de61992))
68 | - 私有属性调整 ([cf61919](https://github.com/vueblocks/element-schema-form/commit/cf6191953e5117db4138d255dfd438022c03ddf5))
69 |
--------------------------------------------------------------------------------
/lib/demo.html:
--------------------------------------------------------------------------------
1 |
2 | element-schema-form demo
3 |
4 |
5 |
6 |
9 |
--------------------------------------------------------------------------------
/lib/element-schema-form.umd.min.js:
--------------------------------------------------------------------------------
1 | (function(e,t){"object"===typeof exports&&"object"===typeof module?module.exports=t():"function"===typeof define&&define.amd?define([],t):"object"===typeof exports?exports["element-schema-form"]=t():e["element-schema-form"]=t()})("undefined"!==typeof self?self:this,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s="fb15")}({"24fb":function(e,t,n){"use strict";function r(e,t){var n=e[1]||"",r=e[3];if(!r)return n;if(t&&"function"===typeof btoa){var a=o(r),i=r.sources.map((function(e){return"/*# sourceURL=".concat(r.sourceRoot).concat(e," */")}));return[n].concat(i).concat([a]).join("\n")}return[n].join("\n")}function o(e){var t=btoa(unescape(encodeURIComponent(JSON.stringify(e)))),n="sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(t);return"/*# ".concat(n," */")}e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var n=r(t,e);return t[2]?"@media ".concat(t[2],"{").concat(n,"}"):n})).join("")},t.i=function(e,n){"string"===typeof e&&(e=[[null,e,""]]);for(var r={},o=0;on.parts.length&&(r.parts.length=n.parts.length)}else{var i=[];for(o=0;o-1}function Ge(e,t){var n=this.__data__,r=at(n,e);return r<0?n.push([e,t]):n[r][1]=t,this}function He(e){var t=-1,n=e?e.length:0;this.clear();while(++t-1&&e%1==0&&e-1&&e%1==0&&e<=a}function Wt(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function qt(e){return!!e&&"object"==typeof e}function Jt(e){return Bt(e)?rt(e):pt(e)}function Xt(){return[]}function Kt(){return!1}n.exports=Nt}).call(this,n("c8ba"),n("62e4")(e))},e6d7:function(e,t,n){"use strict";var r=n("581d"),o=n.n(r);o.a},f6fd:function(e,t){(function(e){var t="currentScript",n=e.getElementsByTagName("script");t in e||Object.defineProperty(e,t,{get:function(){try{throw new Error}catch(r){var e,t=(/.*at [^\(]*\((.*):.+:.+\)$/gi.exec(r.stack)||[!1])[1];for(e in n)if(n[e].src==t||"interactive"==n[e].readyState)return n[e];return null}}})})(document)},fad4:function(e,t,n){t=e.exports=n("24fb")(!1),t.push([e.i,".schema-form-tag .el-tag+.el-tag{margin-left:10px}.schema-form-tag .button-new-tag{margin-left:10px;height:32px;line-height:30px;padding-top:0;padding-bottom:0}.schema-form-tag .input-new-tag{width:90px;margin-left:10px;vertical-align:bottom}",""])},fb15:function(e,t,n){"use strict";var r;(n.r(t),"undefined"!==typeof window)&&(n("f6fd"),(r=window.document.currentScript)&&(r=r.src.match(/(.+\/)[^/]+\.js(\?.*)?$/))&&(n.p=r[1]));var o=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"schema-form"},e._l(e.formatedSchema,(function(t,r){return n("el-row",e._b({key:r,staticClass:"schema-form__row"},"el-row",e.layout,!1),[e._l(t,(function(t,r){return[t.hide?e._e():n("el-col",e._b({key:r},"el-col",t.colGrid,!1),[t.slot?e._t(t.slot):[n("schema-form-item",e._g(e._b({attrs:{prop:t.prop,col:t,model:e.model,options:e.options}},"schema-form-item",t.formItem,!1),e.$listeners),[t.labelSlot?e._t(t.labelSlot,null,{slot:t.labelSlot}):e._e(),t.frontSlot?e._t(t.frontSlot,null,{slot:t.frontSlot}):e._e(),t.rearSlot?e._t(t.rearSlot,null,{slot:t.rearSlot}):e._e()],2)]],2)]}))],2)})),1)},a=[],i=n("cd3f"),l=n.n(i),c={props:{layout:{type:Object,default(){return{}}},schema:{type:Array,required:!0,validator(e){return e.every(e=>Array.isArray(e)&&e.length>0)}},model:{type:Object,required:!0,default(){return{}}},options:{type:Object,default(){return{}}}},computed:{formatedSchema(){let e=l()(this.schema);return e.map(e=>{let t=e.filter(e=>!e.hide).length||1;e.map(e=>{e.colGrid=e.colGrid||{span:Math.round(24/t)}})}),e}}},s=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-form-item",e._b({staticClass:"schema-form-item",attrs:{prop:e.col.prop}},"el-form-item",e.col.formItem,!1),[e.col.labelSlot?n("template",{slot:"label"},[e._t(e.col.labelSlot)],2):e._e(),e.col.labelTooltip?n("template",{slot:"label"},[n("span",{staticClass:"schema-label"},[e._v(e._s(e.labelContent))]),n("el-tooltip",{attrs:{content:e.col.labelTooltip}},[n("i",{staticClass:"el-icon-warning"})])],1):e._e(),e.col.frontHtml?n("span",{domProps:{innerHTML:e._s(e.col.frontHtml)}}):e._e(),e.col.frontSlot?e._t(e.col.frontSlot):e._e(),n(e.getComponentName(e.col.type),e._g(e._b({tag:"component",attrs:{prop:e.col.prop,value:e.model[e.col.prop],modifier:e.col.modifier,dynamicAttrs:e.col.dynamicAttrs,onEvents:e.col.on,options:e.options[e.col.prop]},on:{"update:value":function(t){return e.$set(e.model,e.col.prop,t)}}},"component",e.col.attrs,!1),e.$listeners)),e.col.rearSlot?e._t(e.col.rearSlot):e._e(),e.col.rearHtml?n("span",{domProps:{innerHTML:e._s(e.col.rearHtml)}}):e._e()],2)},u=[],f={props:{model:{type:Object},options:{type:Object},col:{type:Object}},data(){return{builtInNames:["input","select","radio","datepicker","cascader","placeholder","checkbox","slider","timeselect","timepicker","jsoneditor","quill","codemirror","rate","switch","colorpicker","tags","progress"]}},computed:{labelContent(){let e=this.col.formItem||{};return e.label||""}},methods:{getComponentName(e){return this.builtInNames.includes(e)?"schema-form-"+e:e}}},p=f;n("c5ee");function d(e,t,n,r,o,a,i,l){var c,s="function"===typeof e?e.options:e;if(t&&(s.render=t,s.staticRenderFns=n,s._compiled=!0),r&&(s.functional=!0),a&&(s._scopeId="data-v-"+a),i?(c=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"===typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),o&&o.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(i)},s._ssrRegister=c):o&&(c=l?function(){o.call(this,this.$root.$options.shadowRoot)}:o),c)if(s.functional){s._injectStyles=c;var u=s.render;s.render=function(e,t){return c.call(t),u(e,t)}}else{var f=s.beforeCreate;s.beforeCreate=f?[].concat(f,c):[c]}return{exports:e,options:s}}var h=d(p,s,u,!1,null,"5fc0c8b5",null),m=h.exports,b={name:"SchemaForm",mixins:[c],components:{SchemaFormItem:m},mounted(){}},v=b,_=d(v,o,a,!1,null,null,null),g=_.exports,y=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-input",e._g(e._b({on:{change:function(t){return e.$emit("change",{prop:e.prop,value:t})}},model:{value:e.bindVal,callback:function(t){e.bindVal=t},expression:"bindVal"}},"el-input",e.attrsAll,!1),e.onEvents))},x=[],w={props:{value:[Number,String,Array,Object,Boolean,Date],prop:String,modifier:String,dynamicAttrs:Object,options:Array,onEvents:{type:Object,default(){return{}}}},computed:{bindVal:{get(){return this.formatVal(this.value)},set(e){this.$emit("update:value",this.formatVal(e))}},componentName(){let e=this.$options.name;return e.replace("SchemaForm","").toLowerCase()||""},globalOptions(){return this.$globalParams[this.componentName]||{}},attrsAll(){return{...this.globalOptions,...this.$attrs,...this.dynamicAttrs}}},methods:{formatVal(e){if("number"===this.modifier){let t=parseFloat(e);return isNaN(t)?e:t}return"trim"===this.modifier&&e?e.trim():e}}},S={name:"SchemaFormInput",mixins:[w]},j=S,A=d(j,y,x,!1,null,"0197489a",null),V=A.exports,$=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-select",e._g(e._b({on:{change:function(t){return e.$emit("change",{prop:e.prop,value:t})}},model:{value:e.bindVal,callback:function(t){e.bindVal=t},expression:"bindVal"}},"el-select",e.attrsAll,!1),e.onEvents),e._l(e.options,(function(t,r){return n("el-option",{key:t.value+"_"+r,attrs:{label:t.label,value:t.value,disabled:t.disabled}},[e.hasOptionSides?e._l(e.optionSides,(function(r,o){return n("span",{key:o,class:"side-"+o},[e._v(" "+e._s(t[r])+" ")])})):n("span",[e._v(e._s(t.label))])],2)})),1)},O=[],k={name:"SchemaFormSelect",mixins:[w],computed:{optionSides(){return this.attrsAll.optionSides||""},hasOptionSides(){return Array.isArray(this.optionSides)&&this.optionSides.length>=2}}},E=k,C=d(E,$,O,!1,null,"eb13bf92",null),F=C.exports,T=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-radio-group",e._g(e._b({on:{change:function(t){return e.$emit("change",{prop:e.prop,value:t})}},model:{value:e.bindVal,callback:function(t){e.bindVal=t},expression:"bindVal"}},"el-radio-group",e.attrsAll,!1),e.onEvents),e._l(e.options,(function(t,r){return n("el-radio",{key:t.value+"_"+r,attrs:{label:t.value,disabled:t.disabled}},[e._v(" "+e._s(t.label)+" ")])})),1)},I=[],P={name:"SchemaFormRadio",mixins:[w]},M=P,N=d(M,T,I,!1,null,"64ec35e0",null),R=N.exports,U=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-date-picker",e._g(e._b({on:{change:function(t){return e.$emit("change",{prop:e.prop,value:t})}},model:{value:e.bindVal,callback:function(t){e.bindVal=t},expression:"bindVal"}},"el-date-picker",e.attrsAll,!1),e.onEvents))},z=[],B={name:"SchemaFormDatepicker",mixins:[w]},L=B,D=d(L,U,z,!1,null,"3e551afa",null),G=D.exports,H=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-cascader",e._g(e._b({attrs:{options:e.options},on:{change:function(t){return e.$emit("change",{prop:e.prop,value:t})}},model:{value:e.bindVal,callback:function(t){e.bindVal=t},expression:"bindVal"}},"el-cascader",e.attrsAll,!1),e.onEvents))},W=[],q={name:"SchemaFormCascader",mixins:[w]},J=q,X=d(J,H,W,!1,null,"32fffb86",null),K=X.exports,Q=function(){var e=this,t=e.$createElement;e._self._c;return e._m(0)},Y=[function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"schema-form--placeholder"},[n("span",[e._v("Empty Field")])])}],Z={name:"SchemaFormPlaceholder"},ee=Z,te=d(ee,Q,Y,!1,null,"6c276bcc",null),ne=te.exports,re=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-checkbox-group",e._g(e._b({on:{change:function(t){return e.$emit("change",{prop:e.prop,value:t})}},model:{value:e.bindVal,callback:function(t){e.bindVal=t},expression:"bindVal"}},"el-checkbox-group",e.attrsAll,!1),e.onEvents),e._l(e.options,(function(t,r){return n("el-checkbox",{key:t.label+"_"+r,attrs:{label:t.value,disabled:t.disabled}},[e._v(e._s(t.label))])})),1)},oe=[],ae={name:"SchemaFormCheckbox",mixins:[w]},ie=ae,le=d(ie,re,oe,!1,null,"43dcbff7",null),ce=le.exports,se=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-slider",e._g(e._b({on:{change:function(t){return e.$emit("change",{prop:e.prop,value:t})}},model:{value:e.bindVal,callback:function(t){e.bindVal=t},expression:"bindVal"}},"el-slider",e.attrsAll,!1),e.onEvents))},ue=[],fe={name:"SchemaFormSlider",mixins:[w]},pe=fe,de=d(pe,se,ue,!1,null,"27c19576",null),he=de.exports,me=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-time-select",e._g(e._b({on:{change:function(t){return e.$emit("change",{prop:e.prop,value:t})}},model:{value:e.bindVal,callback:function(t){e.bindVal=t},expression:"bindVal"}},"el-time-select",e.attrsAll,!1),e.onEvents))},be=[],ve={name:"SchemaFormTimeselect",mixins:[w]},_e=ve,ge=d(_e,me,be,!1,null,"15a56bbc",null),ye=ge.exports,xe=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-time-picker",e._g(e._b({on:{change:function(t){return e.$emit("change",{prop:e.prop,value:t})}},model:{value:e.bindVal,callback:function(t){e.bindVal=t},expression:"bindVal"}},"el-time-picker",e.attrsAll,!1),e.onEvents))},we=[],Se={name:"SchemaFormTimepicker",mixins:[w]},je=Se,Ae=d(je,xe,we,!1,null,"2479ae50",null),Ve=Ae.exports,$e=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-rate",e._g(e._b({on:{change:function(t){return e.$emit("change",{prop:e.prop,value:t})}},model:{value:e.bindVal,callback:function(t){e.bindVal=t},expression:"bindVal"}},"el-rate",e.attrsAll,!1),e.onEvents))},Oe=[],ke={name:"SchemaFormRate",mixins:[w]},Ee=ke,Ce=d(Ee,$e,Oe,!1,null,"84ecef38",null),Fe=Ce.exports,Te=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-switch",e._g(e._b({on:{change:function(t){return e.$emit("change",{prop:e.prop,value:t})}},model:{value:e.bindVal,callback:function(t){e.bindVal=t},expression:"bindVal"}},"el-switch",e.attrsAll,!1),e.onEvents))},Ie=[],Pe={name:"SchemaFormSwitch",mixins:[w]},Me=Pe,Ne=d(Me,Te,Ie,!1,null,"46883290",null),Re=Ne.exports,Ue=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-color-picker",e._g(e._b({on:{change:function(t){return e.$emit("change",{prop:e.prop,value:t})}},model:{value:e.bindVal,callback:function(t){e.bindVal=t},expression:"bindVal"}},"el-color-picker",e.attrsAll,!1),e.onEvents))},ze=[],Be={name:"SchemaFormColorpicker",mixins:[w]},Le=Be,De=d(Le,Ue,ze,!1,null,"94550de0",null),Ge=De.exports,He=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"schema-form-tag"},[e._l(e.bindVal,(function(t,r){return n("el-tag",{key:t+"_"+r,attrs:{type:e.type,hit:e.hit,size:e.size,effect:e.effect,color:e.color,closable:e.closable,"disable-transitions":!1},on:{close:function(n){return e.handleClose(t)}}},[e._v(" "+e._s(t)+" ")])})),e.showAdd&&e.inputVisible?n("el-input",{ref:"saveTagInput",staticClass:"input-new-tag",attrs:{size:"small"},on:{blur:e.handleInputConfirm},nativeOn:{keyup:function(t){return!t.type.indexOf("key")&&e._k(t.keyCode,"enter",13,t.key,"Enter")?null:e.handleInputConfirm(t)}},model:{value:e.inputValue,callback:function(t){e.inputValue=t},expression:"inputValue"}}):e._e(),e.showAdd&&!e.inputVisible?n("el-button",{staticClass:"button-new-tag",attrs:{size:e.buttonSize,type:e.buttonType},on:{click:e.showInput}},[e._v(e._s(e.buttonWords))]):e._e()],2)},We=[],qe={computed:{showAdd(){return!!this.attrsAll["show-add"]&&this.attrsAll["show-add"]},closable(){return!this.attrsAll.hasOwnProperty("closable")||this.attrsAll.closable},type(){return this.attrsAll.type?this.attrsAll.type:""},hit(){return!!this.attrsAll.hit&&this.attrsAll.hit},size(){return this.attrsAll.size?this.attrsAll.size:""},effect(){return this.attrsAll.effect?this.attrsAll.effect:"light"},color(){return this.attrsAll.color?this.attrsAll.color:""},buttonSize(){return this.attrsAll["button-size"]?this.attrsAll["button-size"]:"small"},buttonWords(){return this.attrsAll["button-words"]?this.attrsAll["button-words"]:"+ New Tag"},buttonType(){return this.attrsAll["button-type"]?this.attrsAll["button-type"]:""}}},Je={name:"SchemaFormTags",mixins:[w,qe],data(){return{inputVisible:!1,inputValue:""}},methods:{handleClose(e){this.bindVal.splice(this.bindVal.indexOf(e),1),this.$emit("change",{prop:this.prop,value:this.bindVal})},showInput(){this.inputVisible=!0,this.$nextTick(e=>{this.$refs.saveTagInput.$refs.input.focus()})},handleInputConfirm(){let e=this.inputValue;e&&this.bindVal.push(e),this.inputVisible=!1,this.inputValue="",this.$emit("change",{prop:this.prop,value:this.bindVal})}}},Xe=Je,Ke=(n("e6d7"),d(Xe,He,We,!1,null,null,null)),Qe=Ke.exports,Ye=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-progress",e._g(e._b({attrs:{percentage:e.bindVal},on:{change:function(t){return e.$emit("change",{prop:e.prop,value:t})}}},"el-progress",e.attrsAll,!1),e.onEvents))},Ze=[],et={name:"SchemaFormProgress",mixins:[w]},tt=et,nt=d(tt,Ye,Ze,!1,null,"6c700e93",null),rt=nt.exports;const ot=[g,V,F,R,G,K,ne,ce,he,ye,Fe,Re,Ge,Qe,rt,Ve];function at(e,t={}){ot.forEach(t=>{e.component(t.name,t)}),e.prototype.$globalParams=t}var it=at;"undefined"!==typeof window&&window.Vue&&(window.Vue.use(at),at.installed&&(at.installed=!1)),n.d(t,"SchemaForm",(function(){return g})),n.d(t,"SchemaFormItem",(function(){return m})),n.d(t,"FormMixin",(function(){return w})),n.d(t,"LayoutMixin",(function(){return c}));t["default"]=it}})}));
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@vueblocks/element-schema-form",
3 | "version": "0.1.8",
4 | "description": "A schema-based form generator component for Element UI.",
5 | "author": "xiaoluoboding ",
6 | "scripts": {
7 | "serve": "vue-cli-service serve",
8 | "build": "vue-cli-service build",
9 | "lint": "vue-cli-service lint",
10 | "build:lib": "vue-cli-service build --mode lib --target lib --name element-schema-form --dest lib src/index.js",
11 | "build:rollup": "rollup -c rollup.config.js",
12 | "build:demand": "cross-env MINIFY=true npm run build:rollup",
13 | "bundle": "npm run build:lib && npm run build:demand",
14 | "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0",
15 | "docs:build": "vuepress build docs",
16 | "docs:dev": "vuepress dev docs",
17 | "docs:deploy": "sh deploy.sh",
18 | "report": "vue-cli-service build --mode lib --target lib --name element-schema-form --dest lib --report src/index.js"
19 | },
20 | "main": "lib/element-schema-form.umd.min.js",
21 | "unpkg": "lib/element-schema-form.umd.min.js",
22 | "repository": {
23 | "type": "git",
24 | "url": "git+https://github.com/vueblocks/element-schema-form.git"
25 | },
26 | "keywords": [
27 | "element",
28 | "json-schema",
29 | "form"
30 | ],
31 | "license": "MIT",
32 | "peerDependencies": {
33 | "element-ui": "^2.11.1"
34 | },
35 | "dependencies": {
36 | "core-js": "^3.3.2",
37 | "vue": "^2.6.10"
38 | },
39 | "devDependencies": {
40 | "@vue/cli-plugin-babel": "^4.0.5",
41 | "@vue/cli-plugin-eslint": "^4.0.5",
42 | "@vue/cli-service": "^4.0.5",
43 | "@vue/eslint-config-standard": "^4.0.0",
44 | "@vuepress/theme-default": "^1.8.2",
45 | "babel-eslint": "^10.0.1",
46 | "babel-plugin-component": "^1.1.1",
47 | "babel-plugin-lodash": "^3.3.4",
48 | "babel-plugin-transform-remove-console": "^6.9.4",
49 | "cross-env": "^6.0.3",
50 | "element-theme-chalk": "^2.10.1",
51 | "element-ui": "^2.11.1",
52 | "eslint": "^5.16.0",
53 | "eslint-plugin-vue": "^5.0.0",
54 | "jsoneditor": "^7.0.1",
55 | "less": "^3.0.4",
56 | "less-loader": "^4.1.0",
57 | "lodash.clonedeep": "^4.5.0",
58 | "lodash.isequal": "^4.5.0",
59 | "normalize.css": "^8.0.1",
60 | "rollup-plugin-babel": "^4.3.3",
61 | "rollup-plugin-commonjs": "^10.1.0",
62 | "rollup-plugin-filesize": "^6.2.1",
63 | "rollup-plugin-json": "^4.0.0",
64 | "rollup-plugin-node-resolve": "^5.2.0",
65 | "rollup-plugin-terser": "^5.1.2",
66 | "rollup-plugin-vue": "^5.1.0",
67 | "terser": "^4.3.9",
68 | "vue-codemirror-lite": "^1.0.4",
69 | "vue-router": "^3.0.3",
70 | "vue-template-compiler": "^2.6.10",
71 | "vue2-editor": "^2.10.2",
72 | "vuepress": "^0.14.5",
73 | "vuex": "^3.0.1"
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | autoprefixer: {}
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vueblocks/element-schema-form/ff2a3ae205d3034d0dd38ab666c68eb2171cc2de/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | element-schema-form
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import babel from 'rollup-plugin-babel'
2 | import cjs from 'rollup-plugin-commonjs'
3 | import filesize from 'rollup-plugin-filesize'
4 | import json from 'rollup-plugin-json'
5 | import node from 'rollup-plugin-node-resolve'
6 | import vue from 'rollup-plugin-vue'
7 | import { terser } from 'rollup-plugin-terser'
8 |
9 | const components = require('./src/components')
10 |
11 | const isMinify = !!process.env.MINIFY
12 |
13 | const plugins = [
14 | babel({
15 | runtimeHelpers: true,
16 | exclude : 'node_modules/**'
17 | }),
18 | cjs({
19 | sourceMap: false
20 | }),
21 | filesize(),
22 | json(),
23 | node(),
24 | vue()
25 | ]
26 |
27 | if (isMinify) {
28 | plugins.push(terser({
29 | compress: {
30 | drop_console: true
31 | }
32 | }))
33 | }
34 |
35 | const buildOutput = fileName => {
36 | return [
37 | {
38 | file: isMinify
39 | ? `./lib/${fileName}.common.min.js`
40 | : `./lib/${fileName}.common.js`,
41 | format: 'cjs',
42 | sourcemap: false,
43 | exports: 'named',
44 | globals: {
45 | 'vue-codemirror-lite': 'vueCodemirrorLite',
46 | 'vue2-editor': 'vue2Editor'
47 | }
48 | },
49 | {
50 | file: isMinify
51 | ? `./lib/${fileName}.umd.min.js`
52 | : `./lib/${fileName}.umd.js`,
53 | format: 'umd',
54 | name: fileName,
55 | sourcemap: false,
56 | globals: {
57 | 'vue-codemirror-lite': 'vueCodemirrorLite',
58 | 'vue2-editor': 'vue2Editor'
59 | }
60 | }
61 | ]
62 | }
63 |
64 | const buildOptions = components => {
65 | return Object.keys(components).map(key => {
66 | return {
67 | input: components[key],
68 | output: buildOutput(key),
69 | plugins,
70 | external: [
71 | 'vueCodemirrorLite',
72 | 'vue2Editor'
73 | ]
74 | }
75 | })
76 | }
77 |
78 |
79 | export default buildOptions(components)
80 |
--------------------------------------------------------------------------------
/src/components.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'SchemaFormCodemirror': './src/packages/components/schema-form-codemirror/index.js',
3 | 'SchemaFormQuill': './src/packages/components/schema-form-quill/index.js'
4 | // 'SchemaFormJsoneditor': './src/packages/components/schema-form-jsoneditor/index.js'
5 | }
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import SchemaForm from './packages/SchemaForm.vue'
2 | import SchemaFormInput from './packages/components/SchemaFormInput.vue'
3 | import SchemaFormSelect from './packages/components/SchemaFormSelect.vue'
4 | import SchemaFormRadio from './packages/components/SchemaFormRadio.vue'
5 | import SchemaFormDatepicker from './packages/components/SchemaFormDatepicker.vue'
6 | import SchemaFormCascader from './packages/components/SchemaFormCascader.vue'
7 | import SchemaFormPlaceholder from './packages/components/SchemaFormPlaceholder.vue'
8 | import SchemaFormCheckbox from './packages/components/SchemaFormCheckbox.vue'
9 | import SchemaFormSlider from './packages/components/SchemaFormSlider.vue'
10 | import SchemaFormTimeselect from './packages/components/SchemaFormTimeselect.vue'
11 | import SchemaFormTimepicker from './packages/components/SchemaFormTimepicker.vue'
12 | import SchemaFormRate from './packages/components/SchemaFormRate.vue'
13 | import SchemaFormSwitch from './packages/components/SchemaFormSwitch.vue'
14 | import SchemaFormColorpicker from './packages/components/SchemaFormColorpicker.vue'
15 | import SchemaFormTags from './packages/components/SchemaFormTags.vue'
16 | import SchemaFormProgress from './packages/components/SchemaFormProgress.vue'
17 |
18 | import SchemaFormItem from './packages/SchemaFormItem.vue'
19 |
20 | import FormMixin from './packages/mixins/form-mixin'
21 | import LayoutMixin from './packages/mixins/layout-mixin'
22 |
23 | const components = [
24 | SchemaForm,
25 | SchemaFormInput,
26 | SchemaFormSelect,
27 | SchemaFormRadio,
28 | SchemaFormDatepicker,
29 | SchemaFormCascader,
30 | SchemaFormPlaceholder,
31 | SchemaFormCheckbox,
32 | SchemaFormSlider,
33 | SchemaFormTimeselect,
34 | SchemaFormRate,
35 | SchemaFormSwitch,
36 | SchemaFormColorpicker,
37 | SchemaFormTags,
38 | SchemaFormProgress,
39 | SchemaFormTimepicker
40 | ]
41 |
42 | function install (Vue, opts = {}) {
43 | components.forEach(component => {
44 | Vue.component(component.name, component)
45 | })
46 | Vue.prototype.$globalParams = opts
47 | }
48 |
49 | export default install
50 |
51 | export {
52 | SchemaForm,
53 | SchemaFormItem,
54 | FormMixin,
55 | LayoutMixin
56 | }
57 |
58 | if (typeof window !== 'undefined' && window.Vue) {
59 | window.Vue.use(install)
60 | if (install.installed) {
61 | install.installed = false
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/packages/SchemaForm.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
13 |
14 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
48 |
49 |
52 |
--------------------------------------------------------------------------------
/src/packages/SchemaFormItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{ labelContent }}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
71 |
72 |
88 |
--------------------------------------------------------------------------------
/src/packages/components/SchemaFormCascader.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
20 |
21 |
24 |
--------------------------------------------------------------------------------
/src/packages/components/SchemaFormCheckbox.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 | {{option.label}}
14 |
15 |
16 |
17 |
25 |
26 |
29 |
--------------------------------------------------------------------------------
/src/packages/components/SchemaFormColorpicker.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
18 |
19 |
22 |
--------------------------------------------------------------------------------
/src/packages/components/SchemaFormDatepicker.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
19 |
20 |
23 |
--------------------------------------------------------------------------------
/src/packages/components/SchemaFormInput.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
19 |
20 |
23 |
--------------------------------------------------------------------------------
/src/packages/components/SchemaFormPlaceholder.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | Empty Field
4 |
5 |
6 |
7 |
12 |
13 |
16 |
--------------------------------------------------------------------------------
/src/packages/components/SchemaFormProgress.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
18 |
19 |
22 |
--------------------------------------------------------------------------------
/src/packages/components/SchemaFormRadio.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
14 | {{option.label}}
15 |
16 |
17 |
18 |
19 |
27 |
28 |
31 |
--------------------------------------------------------------------------------
/src/packages/components/SchemaFormRate.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
18 |
19 |
22 |
--------------------------------------------------------------------------------
/src/packages/components/SchemaFormSelect.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
15 |
16 |
17 | {{ option[items] }}
18 |
19 |
20 | {{ option.label }}
21 |
22 |
23 |
24 |
25 |
41 |
42 |
45 |
--------------------------------------------------------------------------------
/src/packages/components/SchemaFormSlider.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
18 |
19 |
22 |
--------------------------------------------------------------------------------
/src/packages/components/SchemaFormSwitch.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
18 |
19 |
22 |
--------------------------------------------------------------------------------
/src/packages/components/SchemaFormTags.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
14 | {{tag}}
15 |
16 |
25 |
26 | {{buttonWords}}
33 |
34 |
35 |
36 |
72 |
73 |
93 |
--------------------------------------------------------------------------------
/src/packages/components/SchemaFormTimepicker.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
19 |
20 |
23 |
--------------------------------------------------------------------------------
/src/packages/components/SchemaFormTimeselect.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
19 |
20 |
23 |
--------------------------------------------------------------------------------
/src/packages/components/schema-form-codemirror/SchemaFormCodemirror.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
25 |
26 |
29 |
--------------------------------------------------------------------------------
/src/packages/components/schema-form-codemirror/index.js:
--------------------------------------------------------------------------------
1 | import SchemaFormCodemirror from './SchemaFormCodemirror.vue'
2 |
3 | SchemaFormCodemirror.install = function (Vue) {
4 | Vue.component(SchemaFormCodemirror.name, SchemaFormCodemirror)
5 | }
6 |
7 | export default SchemaFormCodemirror
8 |
--------------------------------------------------------------------------------
/src/packages/components/schema-form-jsoneditor/SchemaFormJsoneditor.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
65 |
66 |
69 |
--------------------------------------------------------------------------------
/src/packages/components/schema-form-jsoneditor/index.js:
--------------------------------------------------------------------------------
1 | import SchemaFormJsoneditor from './SchemaFormJsoneditor.vue'
2 |
3 | SchemaFormJsoneditor.install = function (Vue) {
4 | Vue.component(SchemaFormJsoneditor.name, SchemaFormJsoneditor)
5 | }
6 |
7 | export default SchemaFormJsoneditor
8 |
--------------------------------------------------------------------------------
/src/packages/components/schema-form-quill/SchemaFormQuill.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
23 |
24 |
27 |
--------------------------------------------------------------------------------
/src/packages/components/schema-form-quill/index.js:
--------------------------------------------------------------------------------
1 | import SchemaFormQuill from './SchemaFormQuill.vue'
2 |
3 | SchemaFormQuill.install = function (Vue) {
4 | Vue.component(SchemaFormQuill.name, SchemaFormQuill)
5 | }
6 |
7 | export default SchemaFormQuill
8 |
--------------------------------------------------------------------------------
/src/packages/mixins/form-code-mirror-mixin.js:
--------------------------------------------------------------------------------
1 | export default {
2 | computed: {
3 | cmOptions () { // codeMirror 配置项 详见 https://codemirror.net/doc/manual.html#config
4 | return this.attrsAll.cmOptions ? this.attrsAll.cmOptions : {
5 | tabSize: 2,
6 | lineNumbers: true,
7 | line: true
8 | }
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/packages/mixins/form-json-editor-mixin.js:
--------------------------------------------------------------------------------
1 | export default {
2 | computed: {
3 | width () { // 编辑器宽
4 | return this.attrsAll.width ? this.attrsAll.width : '100%'
5 | },
6 | height () { // 编辑器高
7 | return this.attrsAll.width ? this.attrsAll.width : '400px'
8 | },
9 | mode () { // 编辑器模式
10 | return this.attrsAll.mode ? this.attrsAll.mode : 'code'
11 | },
12 | editorOptions () { // 配置项
13 | return this.attrsAll.options ? this.attrsAll.options : {}
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/packages/mixins/form-mixin.js:
--------------------------------------------------------------------------------
1 | export default {
2 | props: {
3 | value: [Number, String, Array, Object, Boolean, Date], // 绑定值
4 | prop: String,
5 | modifier: String, // v-model修饰符
6 | dynamicAttrs: Object, // 动态属性
7 | options: Array, // 多选项目
8 | onEvents: { // 绑定事件
9 | type: Object,
10 | default () { return {} }
11 | }
12 | },
13 | computed: {
14 | bindVal: {
15 | get () {
16 | return this.formatVal(this.value)
17 | },
18 | set (val) {
19 | this.$emit('update:value', this.formatVal(val))
20 | }
21 | },
22 | componentName () {
23 | let _name = this.$options.name
24 | return _name.replace('SchemaForm', '').toLowerCase() || ''
25 | },
26 | globalOptions () {
27 | return this.$globalParams[this.componentName] || {}
28 | },
29 | attrsAll () {
30 | return { ...this.globalOptions, ...this.$attrs, ...this.dynamicAttrs }
31 | }
32 | },
33 | methods: {
34 | formatVal (val) {
35 | if (this.modifier === 'number') {
36 | let n = parseFloat(val)
37 | return isNaN(n) ? val : n
38 | }
39 | if (this.modifier === 'trim' && val) return val.trim()
40 | return val
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/packages/mixins/form-tags-mixin.js:
--------------------------------------------------------------------------------
1 | export default {
2 | computed: {
3 | showAdd () { // 是否展示新增按钮
4 | return this.attrsAll['show-add'] ? this.attrsAll['show-add'] : false
5 | },
6 | closable () { // 标签是否可删除
7 | return this.attrsAll.hasOwnProperty('closable') ? this.attrsAll.closable : true
8 | },
9 | type () { // 标签类型
10 | return this.attrsAll.type ? this.attrsAll.type : ''
11 | },
12 | hit () { // 标签是否有边框描边
13 | return this.attrsAll.hit ? this.attrsAll.hit : false
14 | },
15 | size () { // 标签尺寸
16 | return this.attrsAll.size ? this.attrsAll.size : ''
17 | },
18 | effect () { // 标签主题
19 | return this.attrsAll.effect ? this.attrsAll.effect : 'light'
20 | },
21 | color () { // 标签背景色
22 | return this.attrsAll.color ? this.attrsAll.color : ''
23 | },
24 | buttonSize () { // 按钮尺寸
25 | return this.attrsAll['button-size'] ? this.attrsAll['button-size'] : 'small'
26 | },
27 | buttonWords () { // 按钮文案
28 | return this.attrsAll['button-words'] ? this.attrsAll['button-words'] : '+ New Tag'
29 | },
30 | buttonType () { // 按钮类型
31 | return this.attrsAll['button-type'] ? this.attrsAll['button-type'] : ''
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/packages/mixins/layout-mixin.js:
--------------------------------------------------------------------------------
1 | import cloneDeep from 'lodash.clonedeep'
2 |
3 | export default {
4 | props: {
5 | layout: { // 关于el-row 的拓展
6 | type: Object,
7 | default () { return {} }
8 | },
9 | schema: { // 表单的格局
10 | type: Array,
11 | required: true,
12 | validator (val) {
13 | return val.every(arr => Array.isArray(arr) && arr.length > 0)
14 | }
15 | },
16 | model: { // 绑定的value值
17 | type: Object,
18 | required: true,
19 | default () { return {} }
20 | },
21 | options: { // 多选值绑定的陪选项目
22 | type: Object,
23 | default () { return {} }
24 | }
25 | },
26 | computed: {
27 | formatedSchema () {
28 | let _schema = cloneDeep(this.schema)
29 | _schema.map(list => {
30 | let _showNum = list.filter(item => !item.hide).length || 1
31 | list.map(obj => { obj.colGrid = obj.colGrid || { span: Math.round(24 / _showNum) } })
32 | })
33 | return _schema
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 |
3 | const isProd = process.env.NODE_ENV === 'production'
4 | const isLib = process.env.VUE_APP_BUILD_MODE === 'lib'
5 | const resolve = dir => path.join(__dirname, dir)
6 |
7 | const setChainWebpack = config => {
8 | // 修改默认目录简写
9 | config.resolve.alias
10 | .set('@', path.resolve('app'))
11 | // 添加对 app 目录的支持
12 | config.module
13 | .rule('js')
14 | .include
15 | .add('/app')
16 | .end()
17 | .use('babel')
18 | .loader('babel-loader')
19 | if (isProd) {
20 | /**
21 | * 清除性能警告
22 | * entrypoint size limit (244 KiB)
23 | * asset size limit (244 KiB)
24 | */
25 | config.performance
26 | .set('maxEntrypointSize', 2500000)
27 | .set('maxAssetSize', 2000000)
28 | // drop console
29 | config.optimization.minimizer('terser').tap((args) => {
30 | args[0].terserOptions.compress.drop_console = true
31 | return args
32 | })
33 | }
34 | }
35 |
36 | const setConfigureWebpack = config => {
37 | const externalLibs = [
38 | 'vue',
39 | 'codemirror',
40 | 'jsoneditor',
41 | 'vue-codemirror-lite',
42 | 'vue2-editor'
43 | ]
44 | // 将 vue 设置为外部依赖
45 | let externals = [
46 | function (context, request, callback) {
47 | for (const lib of externalLibs) {
48 | const reg = new RegExp(`^${lib}`)
49 | if (reg.test(request)) {
50 | return callback(null, lib)
51 | }
52 | }
53 | callback()
54 | }
55 | ]
56 | return isLib ? {
57 | externals
58 | } : {}
59 | }
60 |
61 | module.exports = {
62 | publicPath: './',
63 | pages: {
64 | index: {
65 | entry: resolve('app/main.js') // 修改默认打包文件入口
66 | }
67 | },
68 | lintOnSave: true,
69 | productionSourceMap: false,
70 | chainWebpack: config => setChainWebpack(config),
71 | configureWebpack: config => setConfigureWebpack(config),
72 | css: {
73 | extract: false
74 | },
75 | devServer: {
76 | port: 4545,
77 | open: true,
78 | overlay: {
79 | warnings: true,
80 | errors: true
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------