├── .npmignore
├── .browserslistrc
├── demo.webp
├── public
├── favicon.ico
└── index.html
├── babel.config.js
├── .prettierrc.json
├── .github
├── ISSUE_TEMPLATE
│ ├── feature_request.md
│ ├── bug_report.md
│ └── question.md
└── workflows
│ └── main.yml
├── src
├── index.js
├── fixtures
│ ├── extends
│ │ ├── codemirror.js
│ │ ├── json-editor.js
│ │ ├── dynamic.js
│ │ ├── bmap.js
│ │ ├── gallery.js
│ │ ├── video-uploader.js
│ │ ├── quill-editor.js
│ │ ├── upload-file.js
│ │ ├── tree-select.js
│ │ ├── image-uploader.js
│ │ ├── data-editor.js
│ │ ├── markdown-editor.js
│ │ └── table-editor.js
│ ├── form-item-common.js
│ └── form-props.js
├── components
│ ├── main
│ │ ├── components
│ │ │ ├── tpl
│ │ │ │ ├── vue-ele-form.js
│ │ │ │ └── f-render.js
│ │ │ ├── preview-dialog.vue
│ │ │ ├── code-dialog.vue
│ │ │ ├── data-dialog.vue
│ │ │ └── batch-dialog.vue
│ │ ├── index.vue
│ │ ├── main-header.vue
│ │ └── main-content.vue
│ ├── right
│ │ ├── components
│ │ │ ├── search-mixin.js
│ │ │ ├── attrs-header.vue
│ │ │ └── form-item-rules.vue
│ │ ├── form-props.vue
│ │ ├── form-item-attrs.vue
│ │ ├── index.vue
│ │ └── form-item-common.vue
│ └── left
│ │ └── index.vue
├── global-components.js
├── form-skeleton.vue
├── utils.js
└── f-render.vue
├── .gitignore
├── .eslintrc.js
├── vue.config.js
├── example
├── App.vue
├── main.js
└── AppHeader.vue
├── LICENSE
├── package.json
├── CHANGELOG.md
└── README.md
/.npmignore:
--------------------------------------------------------------------------------
1 | .github
2 | dist/demo.html
3 |
--------------------------------------------------------------------------------
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 | not ie <= 8
4 | not dead
5 |
--------------------------------------------------------------------------------
/demo.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dream2023/f-render/HEAD/demo.webp
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dream2023/f-render/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ["@vue/cli-plugin-babel/preset"],
3 | plugins: ["lodash"]
4 | };
5 |
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "none",
3 | "tabWidth": 2,
4 | "semi": true,
5 | "singleQuote": false
6 | }
7 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature Request(新功能建议)
3 | about: Suggest an idea for this project
4 | ---
5 |
6 | ## Feature request(新功能建议)
7 |
8 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import FRender from "./f-render";
2 |
3 | if (window !== undefined && window.Vue) {
4 | window.Vue.component("f-render", FRender);
5 | }
6 |
7 | export default FRender;
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
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 | pnpm-debug.log*
15 |
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | const isProd = process.env.NODE_ENV === "production";
2 | module.exports = {
3 | root: true,
4 | env: {
5 | node: true
6 | },
7 | extends: ["plugin:vue/essential", "eslint:recommended", "@vue/prettier"],
8 | parserOptions: {
9 | parser: "babel-eslint"
10 | },
11 | rules: {
12 | "no-unused-vars": isProd ? "error" : "warn",
13 | "vue/no-unused-components": isProd ? "error" : "warn",
14 | "no-console": isProd ? ["error", { allow: ["warn", "error"] }] : "off",
15 | "no-debugger": isProd ? "warn" : "off"
16 | }
17 | };
18 |
--------------------------------------------------------------------------------
/src/fixtures/extends/codemirror.js:
--------------------------------------------------------------------------------
1 | export default {
2 | type: "codemirror",
3 | label: "代码编辑器",
4 | config: {
5 | url: "https://github.com/dream2023/vue-ele-form-codemirror",
6 | attrs: {
7 | config: {
8 | options: {
9 | type: "data-editor",
10 | label: "配置",
11 | attrs: {
12 | types: ["object"],
13 | rows: 10
14 | }
15 | }
16 | }
17 | },
18 | common: {
19 | config: {
20 | default: {
21 | type: "textarea",
22 | label: "默认值"
23 | }
24 | }
25 | }
26 | }
27 | };
28 |
--------------------------------------------------------------------------------
/src/components/main/components/tpl/vue-ele-form.js:
--------------------------------------------------------------------------------
1 | export default function(code) {
2 | return `
3 |
9 |
10 |
11 |
30 | `;
31 | }
32 |
--------------------------------------------------------------------------------
/src/components/main/components/tpl/f-render.js:
--------------------------------------------------------------------------------
1 | export default function(code) {
2 | return `
3 |
10 |
11 |
12 |
31 | `;
32 | }
33 |
--------------------------------------------------------------------------------
/src/components/right/components/search-mixin.js:
--------------------------------------------------------------------------------
1 | const fuzzy = require("fuzzy");
2 | import { objectToArr, arrToObject } from "../../../utils";
3 |
4 | export default {
5 | data() {
6 | return {
7 | keyword: ""
8 | };
9 | },
10 | computed: {
11 | filteredFormDesc() {
12 | if (this.keyword) {
13 | // 将 formDesc 转为数组
14 | const formDescArr = objectToArr(this.formDesc, "field");
15 | const results = fuzzy
16 | .filter(this.keyword, formDescArr, {
17 | extract: item => item.label
18 | })
19 | .map(el => el.original);
20 | return arrToObject(results, "field");
21 | } else {
22 | return this.formDesc;
23 | }
24 | }
25 | }
26 | };
27 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 | const LodashModuleReplacementPlugin = require("lodash-webpack-plugin");
3 | const isProd = process.env.NODE_ENV === "production";
4 |
5 | module.exports = {
6 | publicPath: isProd ? "./" : "/",
7 | transpileDependencies: [
8 | "indent-string",
9 | "vue-ele-form-dynamic",
10 | "vue-ele-form/lib",
11 | "vuedraggable"
12 | ],
13 | configureWebpack: {
14 | devtool: "source-map",
15 | entry: path.resolve(__dirname, "./example/main.js"),
16 | resolve: {
17 | alias: {
18 | "f-render": path.resolve(__dirname, "./src/")
19 | }
20 | },
21 | plugins: [new LodashModuleReplacementPlugin()]
22 | },
23 | css: {
24 | extract: false
25 | }
26 | };
27 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %> | 可视化表单设计器
9 |
10 |
11 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/global-components.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 此文件用于注册全局组件
3 | */
4 |
5 | import Vue from "vue";
6 |
7 | // 滚动
8 | import PerfectScrollbar from "vue2-perfect-scrollbar";
9 | import "vue2-perfect-scrollbar/dist/vue2-perfect-scrollbar.css";
10 |
11 | // 扩展组件
12 | import EleFormDynamic from "vue-ele-form-dynamic";
13 | import EleFormDataEditor from "vue-ele-form-data-editor";
14 |
15 | // 拖拽
16 | import vueDraggable from "vuedraggable/src/vuedraggable";
17 |
18 | // 代码编辑器
19 | import { PrismEditor } from "vue-prism-editor";
20 | import "vue-prism-editor/dist/prismeditor.min.css";
21 | import "prismjs/themes/prism-tomorrow.css";
22 |
23 | Vue.use(PerfectScrollbar);
24 | Vue.component("dynamic", EleFormDynamic);
25 | Vue.component("PrismEditor", PrismEditor);
26 | Vue.component("vue-draggable", vueDraggable);
27 | Vue.component("data-editor", EleFormDataEditor);
28 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report(报告问题)
3 | about: Create a report to help us improve
4 | ---
5 |
6 |
11 |
12 | ## Bug report(问题描述)
13 |
14 | #### Steps to reproduce(问题复现步骤)
15 |
16 |
21 |
22 | #### Screenshot or Gif(截图或动态图)
23 |
24 | #### Link to minimal reproduction(最小可在线还原 demo)
25 |
26 |
29 |
30 | #### Other relevant information(格外信息)
31 |
32 | - Vue version:
33 | - f-render version:
34 | - ElementUI version:
35 | - vue-ele-form version:
36 |
--------------------------------------------------------------------------------
/src/fixtures/extends/json-editor.js:
--------------------------------------------------------------------------------
1 | export default {
2 | type: "data-editor",
3 | label: "JSON编辑器",
4 | config: {
5 | url: "https://github.com/dream2023/vue-ele-form-upload-file",
6 | attrs: {
7 | config: {
8 | height: {
9 | type: "input",
10 | label: "高度"
11 | },
12 | plus: {
13 | type: "switch",
14 | label: "是否显示全屏按钮"
15 | },
16 | options: {
17 | type: "data-editor",
18 | label: "配置",
19 | attrs: {
20 | types: ["object"]
21 | }
22 | }
23 | },
24 | data: {}
25 | },
26 | common: {
27 | config: {
28 | default: {
29 | type: "data-editor",
30 | label: "默认值",
31 | attrs: {
32 | types: ["object", "array"]
33 | }
34 | }
35 | }
36 | }
37 | }
38 | };
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/question.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Question(提问)
3 | about: Asking questions about use
4 | ---
5 |
6 | ## Question(提问)
7 |
8 |
15 |
16 | #### Steps to reproduce(问题复现步骤)
17 |
18 |
23 |
24 | #### Screenshot or Gif(截图或动态图)
25 |
26 | #### Link to minimal reproduction(最小可在线还原 demo)
27 |
28 |
31 |
32 | #### Other relevant information(格外信息)
33 |
34 | - Vue version:
35 | - f-render version:
36 | - ElementUI version:
37 | - vue-ele-form version:
38 |
--------------------------------------------------------------------------------
/src/components/right/form-props.vue:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
20 |
35 |
--------------------------------------------------------------------------------
/src/components/main/index.vue:
--------------------------------------------------------------------------------
1 |
40 |
--------------------------------------------------------------------------------
/example/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
49 |
--------------------------------------------------------------------------------
/src/components/right/components/attrs-header.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 点击查看 {{ title }}
7 | 属性详细解释
8 |
9 |
10 |
16 |
17 |
18 |
19 |
20 |
34 |
35 |
49 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 二当家的
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.m
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: gitub pages
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 |
8 | jobs:
9 | build-deploy:
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - uses: actions/checkout@master
14 |
15 | - name: install
16 | run: yarn
17 |
18 | - name: build
19 | run: yarn build
20 |
21 | - name: deploy
22 | uses: peaceiris/actions-gh-pages@v2.5.0
23 | env:
24 | ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
25 | PUBLISH_BRANCH: gh-pages
26 | PUBLISH_DIR: ./dist
27 |
28 | - name: Sync to Gitee
29 | uses: wearerequired/git-mirror-action@master
30 | env:
31 | SSH_PRIVATE_KEY: ${{ secrets.GITEE_RSA_PRIVATE_KEY }}
32 | with:
33 | source-repo: "git@github.com:dream2023/f-render.git"
34 | destination-repo: "git@gitee.com:dream2023/f-render.git"
35 |
36 | - name: Build Gitee Pages
37 | uses: yanglbme/gitee-pages-action@master
38 | with:
39 | gitee-username: dream2023
40 | gitee-password: ${{ secrets.GITEE_PASSWORD }}
41 | gitee-repo: dream2023/f-render
42 |
--------------------------------------------------------------------------------
/src/fixtures/extends/dynamic.js:
--------------------------------------------------------------------------------
1 | export default {
2 | type: "dynamic",
3 | label: "动态组件",
4 | config: {
5 | url: "https://github.com/dream2023/vue-ele-form-dynamic",
6 | attrs: {
7 | config: {
8 | columns: {
9 | type: "data-editor",
10 | label: "列",
11 | required: true,
12 | tip: "可以是数组或者对象",
13 | attrs: {
14 | types: ["array", "object"]
15 | }
16 | },
17 | rules: {
18 | type: "data-editor",
19 | label: "校检规则",
20 | tip:
21 | "当columns为数组时, 则rules必须为对象类型, 指定校检字段, 当columns为对象时, 则rules为数组类型",
22 | attrs: {
23 | types: ["array", "object"],
24 | rows: 10
25 | }
26 | },
27 | delimiter: {
28 | type: "input",
29 | label: "分割符"
30 | }
31 | },
32 | data: {}
33 | },
34 | common: {
35 | config: {
36 | default: {
37 | type: "data-editor",
38 | label: "默认值",
39 | attrs: {
40 | types: ["array", "object"]
41 | }
42 | }
43 | },
44 | data: {
45 | default: []
46 | }
47 | }
48 | }
49 | };
50 |
--------------------------------------------------------------------------------
/example/main.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import App from "./App.vue";
3 | import FRender from "f-render";
4 | import ElementUI from "element-ui";
5 | import EleForm from "vue-ele-form";
6 | import EleDynamic from "vue-ele-form-dynamic";
7 | import "element-ui/lib/theme-chalk/index.css";
8 | import "normalize.css";
9 | import axios from "axios";
10 |
11 | axios.interceptors.response.use(response => {
12 | // 将响应结果返回
13 | return response.data;
14 | });
15 | Vue.prototype.$axios = axios;
16 | Vue.config.productionTip = false;
17 | Vue.use(ElementUI);
18 | Vue.use(EleForm, {
19 | upload: {
20 | action: "https://www.mocky.io/v2/5cc8019d300000980a055e76",
21 | responseFn(response) {
22 | // 因为是 mock 地址, 所以, 总是返回同一张图片的URL, 正常使用的时候不会
23 | return response.url;
24 | }
25 | },
26 | "upload-file": {
27 | responseFn(response, file) {
28 | return {
29 | name: file.name,
30 | url: URL.createObjectURL(file.raw),
31 | size: file.size
32 | };
33 | }
34 | },
35 | bmap: {
36 | ak: "9YLHZRPvUNLhi34Oh2ojqeGSpzCf1rVG"
37 | }
38 | });
39 | Vue.component("f-render", FRender);
40 | Vue.component("dynamic", EleDynamic);
41 |
42 | new Vue({
43 | render: h => h(App)
44 | }).$mount("#app");
45 |
--------------------------------------------------------------------------------
/src/form-skeleton.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
20 |
21 |
59 |
--------------------------------------------------------------------------------
/src/components/right/form-item-attrs.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
18 |
19 |
20 | 从左侧拖拽添加表单项并点选
21 |
22 |
23 |
24 |
25 |
47 |
--------------------------------------------------------------------------------
/src/components/main/components/preview-dialog.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
21 |
22 |
23 |
24 |
59 |
--------------------------------------------------------------------------------
/src/fixtures/extends/bmap.js:
--------------------------------------------------------------------------------
1 | export default {
2 | type: "bmap",
3 | label: "地图",
4 | config: {
5 | url: "https://github.com/dream2023/vue-ele-form-bmap",
6 | attrs: {
7 | config: {
8 | ak: {
9 | type: "input",
10 | label: "密钥",
11 | required: true
12 | },
13 | zoom: {
14 | type: "number",
15 | label: "缩放比",
16 | attrs: {
17 | min: 1
18 | }
19 | },
20 | isScrollWheelZoom: {
21 | type: "switch",
22 | label: "滚轮缩放大小"
23 | },
24 | mapHeight: {
25 | type: "number",
26 | label: "地图高度",
27 | attrs: {
28 | min: 0,
29 | step: 50
30 | }
31 | },
32 | isShowNavigation: {
33 | type: "switch",
34 | label: "是否显示缩略控件"
35 | },
36 | isShowGeolocation: {
37 | type: "switch",
38 | label: "是否显示自动定位控件"
39 | },
40 | placeholder: {
41 | type: "input",
42 | label: "搜索占位符"
43 | }
44 | },
45 | data: {
46 | ak: "9YLHZRPvUNLhi34Oh2ojqeGSpzCf1rVG"
47 | }
48 | },
49 | common: {
50 | config: {
51 | default: {
52 | type: "data-editor",
53 | label: "默认值",
54 | attrs: {
55 | types: ["string", "object"],
56 | rows: 4
57 | }
58 | }
59 | }
60 | }
61 | }
62 | };
63 |
--------------------------------------------------------------------------------
/src/utils.js:
--------------------------------------------------------------------------------
1 | import _ from "lodash";
2 | const cloneDeep = require("clone");
3 | /**
4 | * 对象转为数组
5 | * @param {object} obj
6 | * @example
7 | * objectToArr({a1: { name: "张", age: 10 }, a2: { name: "李", age: 20 }}, 'id')
8 | * // [{ name: "张", age: 10, id: 'a1' }, { name: "李", age: 20, id: 'a2' } ]
9 | */
10 | export function objectToArr(obj, keyField) {
11 | return Object.keys(obj).reduce((acc, key) => {
12 | acc.push(Object.assign({}, { [keyField]: key }, obj[key]));
13 | return acc;
14 | }, []);
15 | }
16 |
17 | /**
18 | * 数组转为对象
19 | * @param {array} arr
20 | * @example
21 | * arrToObject([{ name: "张", age: 10, id: 'a1' }, { name: "李", age: 20, id: 'a2' } ], 'id')
22 | * // {a1: { name: "张", age: 10 }, a2: { name: "李", age: 20 }}
23 | */
24 | export function arrToObject(arr, key) {
25 | return cloneDeep(arr).reduce((acc, cur) => {
26 | acc[cur[key]] = cur;
27 | delete cur[key];
28 |
29 | return acc;
30 | }, {});
31 | }
32 |
33 | // 改变 formDesc 的 Label
34 | export function changeFormDescLabel(formDesc = {}) {
35 | return _.mapValues(formDesc, (obj, key) => {
36 | // 将 label 改为 key:label,
37 | // 例如 max: { label: "最大值" } => max: { label: "max:最大值" }
38 | const label = `${key}: ${obj.label}`;
39 |
40 | // 因为 placeholder 会采用 label 做为默认值
41 | // 所以我们需要手动赋值保持 placeholder 不变
42 | if (!obj.attrs) {
43 | obj.attrs = {};
44 | }
45 | obj.attrs.placeholder = obj.label;
46 | return { ...obj, label };
47 | });
48 | }
49 |
50 | /**
51 | * 移除双引号
52 | * @param {string} str
53 | * @example
54 | * reomveQuotes({"name": "zhang"}) => {name: "zhang"}
55 | */
56 | export function reomveQuotes(str) {
57 | return str.replace(/"(\w+)":/g, "$1:");
58 | }
59 |
60 | /**
61 | * 移除无用的属性
62 | */
63 | export function removeEmptyProps(obj = {}) {
64 | return _.omitBy(obj, val => val === undefined || val === null || val === "");
65 | }
66 |
--------------------------------------------------------------------------------
/example/AppHeader.vue:
--------------------------------------------------------------------------------
1 |
2 |
29 |
30 |
31 |
54 |
55 |
77 |
--------------------------------------------------------------------------------
/src/fixtures/extends/gallery.js:
--------------------------------------------------------------------------------
1 | export default {
2 | type: "gallery",
3 | label: "图片及视频展示",
4 | config: {
5 | url: "https://github.com/dream2023/vue-ele-form-gallery",
6 | attrs: {
7 | config: {
8 | type: {
9 | type: "select",
10 | label: "类型",
11 | options: ["image", "video", "iframe"]
12 | },
13 | width: {
14 | type: "number",
15 | label: "缩略图宽度",
16 | attrs: {
17 | min: 0,
18 | step: 10
19 | }
20 | },
21 | height: {
22 | type: "number",
23 | label: "缩略图高度",
24 | attrs: {
25 | min: 0,
26 | step: 10
27 | }
28 | },
29 | lazy: {
30 | type: "switch",
31 | label: "缩略图是否懒加载"
32 | },
33 | thumbSuffix: {
34 | type: "input",
35 | label: "缩略图后缀"
36 | },
37 | thumbStyle: {
38 | type: "data-editor",
39 | label: "缩略图样式",
40 | attrs: {
41 | types: ["object"]
42 | }
43 | },
44 | carouselAttrs: {
45 | type: "data-editor",
46 | label: "轮播图属性",
47 | attrs: {
48 | types: ["object"]
49 | }
50 | }
51 | },
52 | data: {}
53 | },
54 | common: {
55 | config: {
56 | default: {
57 | type: "dynamic",
58 | label: "默认值",
59 | attrs: {
60 | columns: {
61 | type: "el-input",
62 | attrs: {
63 | placeholder: "图片链接"
64 | }
65 | }
66 | }
67 | }
68 | },
69 | data: {
70 | default: [
71 | "https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg",
72 | "https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg"
73 | ]
74 | }
75 | }
76 | }
77 | };
78 |
--------------------------------------------------------------------------------
/src/fixtures/extends/video-uploader.js:
--------------------------------------------------------------------------------
1 | export default {
2 | type: "video-uploader",
3 | label: "上传视频",
4 | config: {
5 | url: "https://github.com/dream2023/vue-ele-form-video-uploader",
6 | attrs: {
7 | config: {
8 | action: {
9 | type: "input",
10 | label: "上传地址",
11 | required: true
12 | },
13 | name: {
14 | type: "input",
15 | label: "上传的文件字段名",
16 | required: true
17 | },
18 | fileSize: {
19 | type: "input",
20 | label: "文件大小限制(MB)",
21 | attrs: {
22 | type: "number",
23 | min: 0
24 | }
25 | },
26 | width: {
27 | type: "number",
28 | label: "显示宽度",
29 | attrs: {
30 | step: 10,
31 | min: 0
32 | }
33 | },
34 | height: {
35 | type: "number",
36 | label: "显示高度(默认auto)",
37 | attrs: {
38 | step: 10,
39 | min: 0
40 | }
41 | },
42 | fileType: {
43 | type: "data-editor",
44 | label: "文件类型",
45 | attrs: {
46 | types: ["array"],
47 | rows: 4
48 | }
49 | },
50 | isShowTip: {
51 | type: "switch",
52 | label: "是否显示提示"
53 | },
54 | withCredentials: {
55 | type: "switch",
56 | label: "支持发送 cookie 凭证信息"
57 | },
58 | data: {
59 | type: "data-editor",
60 | label: "上传时附带的额外参数",
61 | attrs: {
62 | types: ["object"]
63 | }
64 | },
65 | headers: {
66 | type: "data-editor",
67 | label: "设置上传的请求头部",
68 | attrs: {
69 | types: ["object"]
70 | }
71 | }
72 | },
73 | data: {
74 | action: "https://www.mocky.io/v2/5cc8019d300000980a055e76"
75 | }
76 | }
77 | }
78 | };
79 |
--------------------------------------------------------------------------------
/src/fixtures/extends/quill-editor.js:
--------------------------------------------------------------------------------
1 | export default {
2 | type: "quill-editor",
3 | label: "富文本编辑器",
4 | config: {
5 | url: "https://github.com/dream2023/vue-ele-form-quill-editor",
6 | attrs: {
7 | config: {
8 | action: {
9 | type: "input",
10 | label: "上传地址",
11 | required: true
12 | },
13 | editorOptions: {
14 | type: "data-editor",
15 | label: "编辑器设置",
16 | tip: "请参考: https://github.com/davidroyer/vue2-editor",
17 | attrs: {
18 | types: ["object"]
19 | }
20 | },
21 | placeholder: {
22 | type: "input",
23 | label: "占位符"
24 | },
25 | fileSize: {
26 | type: "input",
27 | label: "文件大小限制(MB)",
28 | attrs: {
29 | type: "number",
30 | min: 0
31 | }
32 | },
33 | name: {
34 | type: "input",
35 | label: "上传的文件字段名",
36 | required: true
37 | },
38 | withCredentials: {
39 | type: "switch",
40 | label: "支持发送 cookie 凭证信息"
41 | },
42 | data: {
43 | type: "data-editor",
44 | label: "上传时附带的额外参数",
45 | attrs: {
46 | types: ["object"]
47 | }
48 | },
49 | headers: {
50 | type: "data-editor",
51 | label: "设置上传的请求头部",
52 | attrs: {
53 | types: ["object"]
54 | }
55 | },
56 | editorToolbar: {
57 | type: "data-editor",
58 | label: "自定义toolbar",
59 | attrs: {
60 | types: ["array"]
61 | }
62 | }
63 | },
64 | data: {
65 | action: "https://www.mocky.io/v2/5cc8019d300000980a055e76"
66 | }
67 | },
68 | common: {
69 | config: {
70 | default: {
71 | type: "textarea",
72 | label: "默认值"
73 | }
74 | }
75 | }
76 | }
77 | };
78 |
--------------------------------------------------------------------------------
/src/components/right/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
21 |
22 |
23 |
51 |
52 |
82 |
--------------------------------------------------------------------------------
/src/fixtures/extends/upload-file.js:
--------------------------------------------------------------------------------
1 | export default {
2 | type: "upload-file",
3 | label: "文件上传",
4 | config: {
5 | url: "https://github.com/dream2023/vue-ele-form-upload-file",
6 | attrs: {
7 | config: {
8 | action: {
9 | type: "input",
10 | label: "上传地址",
11 | required: true
12 | },
13 | name: {
14 | type: "input",
15 | label: "上传的文件字段名",
16 | required: true
17 | },
18 | placeholder: {
19 | type: "input",
20 | label: "上传按钮文本"
21 | },
22 | fileSize: {
23 | type: "input",
24 | label: "文件大小限制(MB)",
25 | attrs: {
26 | type: "number",
27 | min: 0
28 | }
29 | },
30 | fileType: {
31 | type: "data-editor",
32 | label: '文件类型, 例如["png", "jpg", "jpeg"]',
33 | attrs: {
34 | types: ["array"],
35 | rows: 4
36 | }
37 | },
38 | multiple: {
39 | type: "switch",
40 | label: "是否支持多选文件"
41 | },
42 | limit: {
43 | type: "input",
44 | label: "文件个数显示",
45 | vif: data => data.multiple,
46 | attrs: {
47 | type: "number",
48 | min: 0
49 | }
50 | },
51 | isCanDownload: {
52 | type: "switch",
53 | label: "是否显示下载"
54 | },
55 | isCanDelete: {
56 | type: "switch",
57 | label: "是否可删除"
58 | },
59 | isCanUploadSame: {
60 | type: "switch",
61 | label: "是否可上传相同文件"
62 | },
63 | isShowTip: {
64 | type: "switch",
65 | label: "是否显示提示"
66 | },
67 | withCredentials: {
68 | type: "switch",
69 | label: "支持发送 cookie 凭证信息"
70 | },
71 | data: {
72 | type: "data-editor",
73 | label: "上传时附带的额外参数",
74 | attrs: {
75 | types: ["object"]
76 | }
77 | },
78 | headers: {
79 | type: "data-editor",
80 | label: "设置上传的请求头部",
81 | attrs: {
82 | types: ["object"]
83 | }
84 | }
85 | },
86 | data: {
87 | action: "https://www.mocky.io/v2/5cc8019d300000980a055e76"
88 | }
89 | }
90 | }
91 | };
92 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "f-render",
3 | "version": "4.12.3",
4 | "private": false,
5 | "license": "MIT",
6 | "description": "f-render | 基于 ElementUI 的表单设计器",
7 | "scripts": {
8 | "serve": "vue-cli-service serve",
9 | "build": "vue-cli-service build",
10 | "toc": "doctoc README.md",
11 | "build:lib": "vue-cli-service build --target lib --name f-render ./src/index.js",
12 | "lint": "vue-cli-service lint --mode=production",
13 | "release": "standard-version",
14 | "pub": " npm run release && npm publish && git push --follow-tags origin master"
15 | },
16 | "main": "./dist/f-render.umd.min.js",
17 | "dependencies": {
18 | "clipboard-copy": "^3.1.0",
19 | "clone": "^2.1.2",
20 | "fuzzy": "^0.1.3",
21 | "indent-string": "^4.0.0",
22 | "lodash": "^4.17.20",
23 | "prismjs": "^1.21.0",
24 | "serialize-javascript": "^4.0.0",
25 | "vue-ele-form-data-editor": "^0.1.6",
26 | "vue-ele-form-dynamic": "^0.4.3",
27 | "vue-multipane": "^0.9.5",
28 | "vue-prism-editor": "^1.2.2",
29 | "vue2-perfect-scrollbar": "^1.5.0",
30 | "vuedraggable": "^2.24.0"
31 | },
32 | "devDependencies": {
33 | "@vue/cli-plugin-babel": "~4.5.0",
34 | "@vue/cli-plugin-eslint": "~4.5.0",
35 | "@vue/cli-service": "~4.5.0",
36 | "@vue/eslint-config-prettier": "^6.0.0",
37 | "axios": "^0.20.0",
38 | "babel-eslint": "^10.1.0",
39 | "babel-plugin-lodash": "^3.3.4",
40 | "core-js": "^3.6.5",
41 | "doctoc": "^1.4.0",
42 | "element-ui": "^2.13.2",
43 | "eslint": "^6.7.2",
44 | "eslint-plugin-prettier": "^3.1.3",
45 | "eslint-plugin-vue": "^6.2.2",
46 | "lint-staged": "^9.5.0",
47 | "lodash-webpack-plugin": "^0.11.5",
48 | "normalize.css": "^8.0.1",
49 | "prettier": "^1.19.1",
50 | "standard-version": "^9.0.0",
51 | "vue": "^2.6.11",
52 | "vue-ele-form": "^0.8.56",
53 | "vue-template-compiler": "^2.6.11"
54 | },
55 | "repository": {
56 | "type": "git",
57 | "url": "https://github.com/dream2023/f-render"
58 | },
59 | "keywords": [
60 | "vue-ele-form",
61 | "f-render",
62 | "form-schema",
63 | "vue-form",
64 | "form-designer",
65 | "form-design",
66 | "element-ui",
67 | "form-generator",
68 | "for-generate",
69 | "vue-form-generator",
70 | "form schema"
71 | ],
72 | "gitHooks": {
73 | "pre-commit": "lint-staged"
74 | },
75 | "lint-staged": {
76 | "*.{js,jsx,vue}": [
77 | "vue-cli-service lint --mode=production",
78 | "git add"
79 | ]
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/fixtures/extends/tree-select.js:
--------------------------------------------------------------------------------
1 | export default {
2 | type: "tree-select",
3 | label: "树形下拉选择器",
4 | config: {
5 | url: "https://github.com/dream2023/vue-ele-form-tree-select",
6 | attrs: {
7 | config: {
8 | placeholder: {
9 | type: "input",
10 | label: "占位符"
11 | },
12 | appendToBody: {
13 | type: "switch",
14 | label: "弹窗插入body"
15 | },
16 | multiple: {
17 | type: "switch",
18 | label: "是否开启多选模式"
19 | },
20 | searchable: {
21 | type: "switch",
22 | label: "是否开启搜索功能"
23 | },
24 | async: {
25 | type: "switch",
26 | label: "是否开启异步搜索"
27 | },
28 | autoFocus: {
29 | type: "switch",
30 | label: "是否自动聚焦"
31 | },
32 | clearable: {
33 | type: "switch",
34 | label: "是否显示清除图标"
35 | },
36 | limit: {
37 | type: "number",
38 | label: "多选数量显示",
39 | vif: data => data.multiple,
40 | attrs: {
41 | min: 1
42 | }
43 | },
44 | maxHeight: {
45 | type: "number",
46 | label: "弹出菜单高度",
47 | attrs: {
48 | min: 0,
49 | step: 10
50 | }
51 | },
52 | alwaysOpen: {
53 | type: "switch",
54 | label: "一直打开选项菜单"
55 | },
56 | flattenSearchResults: {
57 | type: "switch",
58 | label: "是否展平搜索结果",
59 | vif: data => data.async
60 | },
61 | autoLoadRootOptions: {
62 | type: "switch",
63 | label: "是否自定加载根节点选项"
64 | }
65 | }
66 | },
67 | common: {
68 | config: {
69 | default: {
70 | type: "tree-select",
71 | label: "默认值",
72 | prop: data => data.prop,
73 | optionsLinkageFields: data => data.optionsLinkageFields,
74 | options: data => data.options
75 | }
76 | },
77 | data: {
78 | isOptions: true,
79 | options: [
80 | {
81 | id: "a",
82 | label: "a",
83 | children: [
84 | {
85 | id: "aa",
86 | label: "aa"
87 | },
88 | {
89 | id: "ab",
90 | label: "ab"
91 | }
92 | ]
93 | },
94 | {
95 | id: "b",
96 | label: "b"
97 | },
98 | {
99 | id: "c",
100 | label: "c"
101 | }
102 | ]
103 | }
104 | }
105 | }
106 | };
107 |
--------------------------------------------------------------------------------
/src/components/left/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
13 |
14 |
22 |
28 | {{ item.type }}
29 | {{ item.label }}
30 |
31 |
32 |
33 |
34 |
35 |
36 |
76 |
77 |
113 |
--------------------------------------------------------------------------------
/src/components/main/components/code-dialog.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 | f-render方式
10 | vue-ele-form方式
11 |
12 |
19 |
20 | 复制代码
21 |
22 | 下载文件
31 | 关闭弹窗
32 |
33 |
34 |
35 |
36 |
112 |
--------------------------------------------------------------------------------
/src/fixtures/extends/image-uploader.js:
--------------------------------------------------------------------------------
1 | export default {
2 | type: "image-uploader",
3 | label: "上传图片",
4 | config: {
5 | url: "https://github.com/dream2023/vue-ele-form-image-uploader",
6 | attrs: {
7 | config: {
8 | action: {
9 | type: "input",
10 | label: "上传地址",
11 | required: true
12 | },
13 | name: {
14 | type: "input",
15 | label: "上传的文件字段名",
16 | required: true
17 | },
18 | corp: {
19 | type: "switch",
20 | label: "是否剪裁"
21 | },
22 | cropHeight: {
23 | type: "number",
24 | label: "裁剪高度",
25 | vif: data => data.corp,
26 | attrs: {
27 | min: 0
28 | }
29 | },
30 | cropWidth: {
31 | type: "number",
32 | label: "裁剪宽度",
33 | vif: data => data.corp,
34 | attrs: {
35 | min: 0
36 | }
37 | },
38 | multiple: {
39 | type: "switch",
40 | label: "是否支持多选文件"
41 | },
42 | limit: {
43 | type: "input",
44 | label: "文件个数显示",
45 | vif: data => data.multiple,
46 | attrs: {
47 | min: 0,
48 | type: "number"
49 | }
50 | },
51 | size: {
52 | type: "number",
53 | label: "图片显示大小",
54 | attrs: {
55 | min: 0,
56 | step: 10
57 | }
58 | },
59 | fileSize: {
60 | type: "number",
61 | label: "文件大小限制(MB)",
62 | attrs: {
63 | min: 0
64 | }
65 | },
66 | lazy: {
67 | type: "switch",
68 | label: "图片懒加载"
69 | },
70 | drag: {
71 | type: "switch",
72 | label: "是否启用拖拽上传"
73 | },
74 | withCredentials: {
75 | type: "switch",
76 | label: "支持发送 cookie 凭证信息"
77 | },
78 | isShowTip: {
79 | type: "switch",
80 | label: "是否显示提示"
81 | },
82 | title: {
83 | type: "input",
84 | label: "弹窗标题"
85 | },
86 | thumbSuffix: {
87 | type: "input",
88 | label: "略图后缀, 例如七牛云缩略图样式 (?imageView2/1/w/20/h/20)"
89 | },
90 | fileType: {
91 | type: "data-editor",
92 | label: '文件类型, 例如["png", "jpg", "jpeg"]',
93 | attrs: {
94 | types: ["array"]
95 | }
96 | },
97 | data: {
98 | type: "data-editor",
99 | label: "上传时附带的额外参数",
100 | attrs: {
101 | types: ["array", "object"]
102 | }
103 | },
104 | headers: {
105 | type: "data-editor",
106 | label: "设置上传的请求头部",
107 | attrs: {
108 | types: ["object"]
109 | }
110 | }
111 | },
112 | data: {
113 | action: "https://www.mocky.io/v2/5cc8019d300000980a055e76"
114 | }
115 | }
116 | }
117 | };
118 |
--------------------------------------------------------------------------------
/src/fixtures/extends/data-editor.js:
--------------------------------------------------------------------------------
1 | export default {
2 | type: "textarea",
3 | label: "多行输入框",
4 | sort: 2,
5 | config: {
6 | url: "https://element.eleme.cn/#/zh-CN/component/input#wen-ben-yu",
7 | attrs: {
8 | config: {
9 | autoSave: {
10 | type: "switch",
11 | label: "是否自动保存"
12 | },
13 | types: {
14 | type: "dynamic",
15 | label: "数据类型"
16 | },
17 | placeholder: {
18 | type: "input",
19 | label: "输入框占位文本",
20 | attrs: {
21 | clearable: true
22 | }
23 | },
24 | rows: {
25 | type: "number",
26 | label: "输入框行",
27 | attrs: {
28 | min: 1
29 | }
30 | },
31 | autosizeType: {
32 | type: "radio",
33 | label: "自适应内容高度值类型",
34 | default: "switch",
35 | options: [
36 | { text: "自适应", value: "switch" },
37 | { text: "最大最小值", value: "data-editor" }
38 | ]
39 | },
40 | autosize: {
41 | type: data => data.autosizeType,
42 | default: data => {
43 | if (data.autosizeType === "switch") {
44 | return false;
45 | } else {
46 | return { minRows: 2, maxRows: 6 };
47 | }
48 | },
49 | label: "自适应内容高度配置",
50 | attrs(data) {
51 | if (data.autosizeType === "data-editor") {
52 | return {
53 | types: ["object"],
54 | rows: 4
55 | };
56 | }
57 | },
58 | rules: [
59 | {
60 | trigger: "blur",
61 | validator: function(rule, value, callback) {
62 | if (typeof value === "object") {
63 | if (!value.minRows || !value.maxRows) {
64 | callback("对象必须包含 minRows 和 maxRows");
65 | }
66 | } else if (typeof value !== "boolean") {
67 | callback("数据类型不正确");
68 | }
69 | }
70 | }
71 | ]
72 | },
73 | resize: {
74 | type: "select",
75 | label: "控制是否能被用户缩放",
76 | options: ["both", "horizontal", "vertical"],
77 | attrs: {
78 | clearable: true
79 | }
80 | },
81 | showWordLimit: {
82 | type: "switch",
83 | label: "是否显示输入字数统计",
84 | vif: data => data.minlength || data.maxlength
85 | },
86 | clearable: {
87 | type: "switch",
88 | label: "是否可清空"
89 | },
90 | autofocus: {
91 | type: "switch",
92 | label: "原生属性,自动获取焦点"
93 | },
94 | tabindex: {
95 | type: "input",
96 | label: "输入框的tabindex",
97 | attrs: {
98 | clearable: true
99 | }
100 | },
101 | validateEvent: {
102 | type: "switch",
103 | label: "输入时是否触发表单的校验"
104 | }
105 | },
106 | data: {}
107 | }
108 | }
109 | };
110 |
--------------------------------------------------------------------------------
/src/components/right/form-item-common.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
23 |
24 |
25 | 新增校检规则
28 |
29 |
35 |
36 |
37 |
38 |
39 |
40 | 从左侧拖拽添加表单项并点选
41 |
42 |
43 |
44 |
45 |
116 |
--------------------------------------------------------------------------------
/src/fixtures/extends/markdown-editor.js:
--------------------------------------------------------------------------------
1 | export default {
2 | type: "markdown-editor",
3 | label: "markdown编辑器",
4 | config: {
5 | url: "https://github.com/dream2023/vue-ele-form-markdown-editor",
6 | attrs: {
7 | config: {
8 | fontSize: {
9 | type: "input",
10 | label: "编辑区域文字大小"
11 | },
12 | scrollStyle: {
13 | type: "switch",
14 | label: "开启滚动条样式(暂时仅支持chrome)"
15 | },
16 | boxShadow: {
17 | type: "switch",
18 | label: "开启边框阴影"
19 | },
20 | boxShadowStyle: {
21 | type: "input",
22 | label: "边框阴影样式"
23 | },
24 | transition: {
25 | type: "switch",
26 | label: "是否开启过渡动画"
27 | },
28 | toolbarsBackground: {
29 | type: "color",
30 | label: "工具栏背景颜色"
31 | },
32 | previewBackground: {
33 | type: "color",
34 | label: "预览框背景颜色"
35 | },
36 | subfield: {
37 | type: "switch",
38 | label: "true: 双栏(编辑预览同屏), false: 单栏(编辑预览分屏)"
39 | },
40 | defaultOpen: {
41 | type: "radio",
42 | label: "默认展示区域",
43 | options: ["edit", "preview"]
44 | },
45 | placeholder: {
46 | type: "input",
47 | label: "输入框为空时默认提示文本"
48 | },
49 | editable: {
50 | type: "switch",
51 | label: "是否允许编辑"
52 | },
53 | toolbarsFlag: {
54 | type: "switch",
55 | label: "工具栏是否显示"
56 | },
57 | navigation: {
58 | type: "switch",
59 | label: "默认展示目录"
60 | },
61 | shortCut: {
62 | type: "switch",
63 | label: "是否启用快捷键"
64 | },
65 | autofocus: {
66 | type: "switch",
67 | label: "自动聚焦到文本框"
68 | },
69 | ishljs: {
70 | type: "switch",
71 | label: "代码高亮"
72 | },
73 | toolbars: {
74 | type: "data-editor",
75 | label: "工具栏",
76 | attrs: {
77 | types: ["object"],
78 | rows: 10
79 | }
80 | },
81 | action: {
82 | type: "input",
83 | label: "上传地址",
84 | required: true
85 | },
86 | fileSize: {
87 | type: "input",
88 | label: "文件大小限制(MB)",
89 | attrs: {
90 | type: "number",
91 | min: 0
92 | }
93 | },
94 | name: {
95 | type: "input",
96 | label: "上传的文件字段名",
97 | required: true
98 | },
99 | withCredentials: {
100 | type: "switch",
101 | label: "支持发送 cookie 凭证信息"
102 | },
103 | data: {
104 | type: "data-editor",
105 | label: "上传时附带的额外参数",
106 | attrs: {
107 | types: ["object"]
108 | }
109 | },
110 | headers: {
111 | type: "data-editor",
112 | label: "设置上传的请求头部",
113 | attrs: {
114 | types: ["object"]
115 | }
116 | }
117 | },
118 | data: {
119 | action: "https://www.mocky.io/v2/5cc8019d300000980a055e76"
120 | }
121 | },
122 | common: {
123 | config: {
124 | default: {
125 | type: "textarea",
126 | label: "默认值",
127 | default: ""
128 | }
129 | }
130 | }
131 | }
132 | };
133 |
--------------------------------------------------------------------------------
/src/fixtures/form-item-common.js:
--------------------------------------------------------------------------------
1 | export default {
2 | config: {
3 | field: {
4 | type: "input",
5 | label: "字段名",
6 | tip: "字段名不可重复",
7 | rules: {
8 | type: "string"
9 | }
10 | },
11 | label: {
12 | type: "input",
13 | label: "标签"
14 | },
15 | layout: {
16 | type: "slider",
17 | label: "宽度",
18 | attrs: {
19 | min: 1,
20 | max: 24,
21 | formatTooltip(val) {
22 | return `${val} / 24`;
23 | }
24 | }
25 | },
26 | default: {
27 | type: "input",
28 | label: "默认值"
29 | },
30 | required: {
31 | type: "yesno",
32 | label: "校检",
33 | title: "是否必填"
34 | },
35 | rules: {
36 | type: "data-editor",
37 | label: "校检规则",
38 | title: "新增校检规则",
39 | default: [],
40 | attrs: {
41 | types: ["array", "object"],
42 | rows: 10
43 | },
44 | tip:
45 | '校检规则文档, 请点击查看'
46 | },
47 | options: {
48 | type: "data-editor",
49 | label: "选项",
50 | attrs: {
51 | types: ["string", "array", "function", "promise", "asyncfunction"],
52 | rows: 10
53 | },
54 | vif: data => data.isOptions,
55 | tip:
56 | 'options支持`API接口`、`数组`、`函数`、`Promise`等, 具体看文档'
57 | },
58 | prop: {
59 | type: "data-editor",
60 | label: "options 配置",
61 | vif: data => data.isOptions,
62 | attrs: {
63 | types: ["object"],
64 | rows: 4
65 | }
66 | },
67 | optionsLinkageFields: {
68 | type: "dynamic",
69 | vif: data => data.isOptions,
70 | label: "options 关联属性"
71 | },
72 | vif: {
73 | type: "data-editor",
74 | label: "联动显示/隐藏",
75 | attrs: {
76 | types: ["function", "boolean"]
77 | },
78 | tip:
79 | '支持`布尔值`和`函数`,具体请查看:文档'
80 | },
81 | disabled: {
82 | type: "data-editor",
83 | label: "联动启用/禁用",
84 | attrs: {
85 | types: ["function", "boolean", "string"]
86 | },
87 | tip:
88 | '支持`布尔值`和`函数`,具体请查看:文档'
89 | },
90 | tip: {
91 | type: "input",
92 | label: "表单项提示"
93 | },
94 | isShowLabel: {
95 | label: "否显示标签",
96 | type: "radio-button",
97 | tip: "与全局isShowLabel作用相同",
98 | options: [
99 | { text: "显示", value: undefined },
100 | { text: "隐藏", value: false }
101 | ]
102 | },
103 | labelWidth: {
104 | label: "标签宽度",
105 | type: "input",
106 | tip: "需要以`px`作为单位, 例如`100px`, 默认为全局设置的labelWidth值"
107 | },
108 | break: {
109 | label: "强制折行",
110 | type: "radio-button",
111 | options: [
112 | { text: "正常", value: undefined },
113 | { text: "折行", value: true }
114 | ]
115 | },
116 | displayFormatter: {
117 | label: "显示处理函数",
118 | type: "data-editor",
119 | attrs: {
120 | types: ["function"]
121 | }
122 | },
123 | valueFormatter: {
124 | label: "最终值处理函数",
125 | type: "data-editor",
126 | attrs: {
127 | types: ["function"]
128 | }
129 | }
130 | },
131 | // 覆盖值
132 | data: {}
133 | };
134 |
--------------------------------------------------------------------------------
/src/components/main/components/data-dialog.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
15 |
21 |
22 | 更改数据
23 | 复制数据
24 | 下载数据
33 | 关闭弹窗
34 |
35 |
36 |
37 |
38 |
125 |
--------------------------------------------------------------------------------
/src/fixtures/extends/table-editor.js:
--------------------------------------------------------------------------------
1 | export default {
2 | type: "table-editor",
3 | label: "表格内容编辑组件",
4 | config: {
5 | url: "https://github.com/dream2023/vue-ele-form-table-editor",
6 | attrs: {
7 | config: {
8 | columns: {
9 | type: "data-editor",
10 | label: "table 列",
11 | required: true,
12 | attrs: {
13 | types: ["array", "object"]
14 | },
15 | rows: 12
16 | },
17 | isShowDelete: {
18 | type: "switch",
19 | label: "是否显示删除"
20 | },
21 | isShowAdd: {
22 | type: "switch",
23 | label: "是否显示新增按钮"
24 | },
25 | addBtnText: {
26 | type: "input",
27 | label: "新增按钮文本"
28 | },
29 | newColumnValue: {
30 | type: "data-editor",
31 | label: "新增列的值",
32 | attrs: {
33 | types: ["object"]
34 | }
35 | },
36 | rules: {
37 | type: "data-editor",
38 | label: "校检规则",
39 | attrs: {
40 | types: ["object", "array"],
41 | rows: 10
42 | }
43 | },
44 | extraBtns: {
45 | type: "data-editor",
46 | label: "右侧其它按钮",
47 | attrs: {
48 | types: ["array"]
49 | }
50 | },
51 | deleteBtnAttr: {
52 | type: "data-editor",
53 | label: "删除按钮属性",
54 | attrs: {
55 | types: ["object"]
56 | }
57 | },
58 | tableAttrs: {
59 | type: "data-editor",
60 | label: "表格属性",
61 | attrs: {
62 | types: ["object"]
63 | }
64 | }
65 | },
66 | data: {
67 | columns: [
68 | {
69 | // el-table-column 的属性
70 | type: "index",
71 | width: 50
72 | },
73 | {
74 | // el-table-column 的属性
75 | prop: "grade",
76 | label: "年级"
77 | },
78 | {
79 | prop: "name",
80 | label: "姓名",
81 | content: {
82 | type: "el-input",
83 | attrs: {
84 | placeholder: "学员姓名"
85 | }
86 | }
87 | },
88 | {
89 | label: "缴费",
90 | width: 200,
91 | content: [
92 | "已缴纳: ",
93 | {
94 | type: "el-input",
95 | valueKey: "tuition",
96 | style: {
97 | width: "100px",
98 | marginRight: "10px"
99 | }
100 | }
101 | ]
102 | },
103 | {
104 | prop: "dream",
105 | label: "梦想",
106 | content: {
107 | type: "el-select",
108 | options: [
109 | { text: "科学家", value: "scientist" },
110 | { text: "警察", value: "policeman" },
111 | "程序员"
112 | ]
113 | }
114 | }
115 | ],
116 | newColumnValue: {
117 | grade: "三年级二班"
118 | }
119 | }
120 | },
121 | common: {
122 | config: {
123 | default: {
124 | type: "data-editor",
125 | label: "默认值",
126 | attrs: {
127 | types: ["array"]
128 | }
129 | }
130 | },
131 | data: {
132 | default: [
133 | {
134 | grade: "三年级二班",
135 | name: "小张",
136 | sex: 1,
137 | tuition: 2000,
138 | unPay: 100,
139 | dream: ""
140 | }
141 | ]
142 | }
143 | }
144 | }
145 | };
146 |
--------------------------------------------------------------------------------
/src/components/main/main-header.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{ operationBtns[key].label }}
15 |
16 |
17 |
18 | 保存数据
21 |
22 |
23 |
24 |
25 |
26 |
33 |
34 |
35 |
36 |
37 |
118 |
119 |
145 |
--------------------------------------------------------------------------------
/src/fixtures/form-props.js:
--------------------------------------------------------------------------------
1 | export default {
2 | config: {
3 | inline: {
4 | type: "radio-button",
5 | label: "inline模式 / layout模式",
6 | options: [
7 | { text: "layout模式", value: undefined },
8 | { text: "inline模式", value: true }
9 | ]
10 | },
11 | isResponsive: {
12 | type: "radio-button",
13 | label: "是否响应式",
14 | vif: data => !data.inline,
15 | options: [
16 | { text: "是", value: undefined },
17 | { text: "否", value: false }
18 | ]
19 | },
20 | labelPosition: {
21 | type: "radio-button",
22 | label: "标签位置",
23 | options(data) {
24 | const options = ["left", "right", "top"];
25 | if (data.isResponsive !== false && !data.inline) {
26 | options.unshift({ text: "响应式", value: undefined });
27 | }
28 | return options;
29 | }
30 | },
31 | span: {
32 | type: "select",
33 | label: "表单宽度",
34 | vif: data => !data.inline,
35 | options() {
36 | const options = Array.from({ length: 24 }, (v, i) => {
37 | return { text: `${24 - i} / 24`, value: 24 - i };
38 | });
39 | options.unshift({ text: "响应式", value: undefined });
40 | return options;
41 | },
42 | style: {
43 | width: "100%"
44 | }
45 | },
46 | rules: {
47 | type: "data-editor",
48 | label: "校检规则",
49 | attrs: {
50 | types: ["object"]
51 | },
52 | tip:
53 | '校检规则文档, 请点击查看'
54 | },
55 | isDialog: {
56 | type: "radio-button",
57 | label: "是否为弹窗",
58 | options: [
59 | { text: "非弹窗", value: undefined },
60 | { text: "弹窗", value: true }
61 | ]
62 | },
63 | isShowLabel: {
64 | type: "radio-button",
65 | label: "是否显示标签",
66 | options: [
67 | { text: "显示", value: undefined },
68 | { text: "不显示", value: false }
69 | ]
70 | },
71 | labelWidth: {
72 | type: "input",
73 | label: "标签宽度",
74 | attrs: {
75 | type: "number",
76 | min: 0,
77 | step: 10
78 | },
79 | tip: "默认值为 `auto`"
80 | },
81 | disabled: {
82 | type: "radio-button",
83 | label: "全局禁用表单",
84 | options: [
85 | { text: "正常", value: undefined },
86 | { text: "禁用", value: true }
87 | ]
88 | },
89 | readonly: {
90 | type: "radio-button",
91 | label: "全局只读表单",
92 | options: [
93 | { text: "正常", value: undefined },
94 | { text: "只读", value: true }
95 | ]
96 | },
97 | isShowErrorNotify: {
98 | type: "radio-button",
99 | label: "是否在校检错误后显示右上角提示",
100 | options: [
101 | { text: "显示", value: undefined },
102 | { text: "不显示", value: false }
103 | ]
104 | },
105 | isShowSubmitBtn: {
106 | type: "radio-button",
107 | label: "提交按钮",
108 | options: [
109 | { text: "显示", value: undefined },
110 | { text: "隐藏", value: false }
111 | ]
112 | },
113 | isShowBackBtn: {
114 | type: "radio-button",
115 | label: "返回按钮",
116 | options: [
117 | { text: "显示", value: undefined },
118 | { text: "隐藏", value: false }
119 | ]
120 | },
121 | formBtnSize: {
122 | type: "radio-button",
123 | label: "表单按钮大小",
124 | options: [{ text: "默认", value: undefined }, "medium", "small", "mini"]
125 | },
126 | isShowResetBtn: {
127 | type: "radio-button",
128 | label: "重置按钮",
129 | options: [
130 | { text: "显示", value: true },
131 | { text: "隐藏", value: undefined }
132 | ]
133 | },
134 | isShowCancelBtn: {
135 | type: "radio-button",
136 | label: "取消按钮",
137 | options: [
138 | { text: "显示", value: true },
139 | { text: "隐藏", value: undefined }
140 | ]
141 | },
142 | submitBtnText: {
143 | type: "input",
144 | label: "提交按钮文字"
145 | },
146 | backBtnText: {
147 | type: "input",
148 | label: "返回按钮文字"
149 | },
150 | cancelBtnText: {
151 | type: "input",
152 | label: "取消按钮文字"
153 | },
154 | resetBtnText: {
155 | type: "input",
156 | label: "返回按钮文字"
157 | },
158 | formAttrs: {
159 | type: "data-editor",
160 | label: "el-form属性",
161 | attrs: {
162 | types: ["object"]
163 | }
164 | }
165 | },
166 | data: {}
167 | };
168 |
--------------------------------------------------------------------------------
/src/components/main/main-content.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
23 |
24 |
28 | 从左侧拖拽来添加表单项
29 |
30 |
31 |
32 |
43 |
53 |
62 |
67 |
68 |
69 |
70 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
142 |
143 |
204 |
--------------------------------------------------------------------------------
/src/components/main/components/batch-dialog.vue:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
193 |
--------------------------------------------------------------------------------
/src/components/right/components/form-item-rules.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
15 |
16 |
17 |
196 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4 |
5 | ### [4.12.2](https://github.com/dream2023/f-render/compare/v4.12.1...v4.12.2) (2020-12-22)
6 |
7 |
8 | ### Bug Fixes
9 |
10 | * **#66:** attrs 属性未隔离 & 火狐浏览器拖拽打开新页面 ([7d733e9](https://github.com/dream2023/f-render/commit/7d733e94131d8ae6a9384b6b25cf8a1c0009136f)), closes [#66](https://github.com/dream2023/f-render/issues/66)
11 |
12 | ### [4.12.1](https://github.com/dream2023/f-render/compare/v4.12.0...v4.12.1) (2020-11-17)
13 |
14 | ## [4.12.0](https://github.com/dream2023/f-render/compare/v4.10.2...v4.12.0) (2020-11-01)
15 |
16 |
17 | ### Features
18 |
19 | * 增加插槽 & 右侧属性面板配置 ([106fa49](https://github.com/dream2023/f-render/commit/106fa49f965366bd53dc90f3d8541ca0089c0b98))
20 |
21 | ## [4.11.0](https://github.com/dream2023/f-render/compare/v4.10.2...v4.11.0) (2020-11-01)
22 |
23 |
24 | ### Features
25 |
26 | * 增加插槽 & 右侧属性面板配置 ([106fa49](https://github.com/dream2023/f-render/commit/106fa49f965366bd53dc90f3d8541ca0089c0b98))
27 |
28 | ### [4.10.2](https://github.com/dream2023/f-render/compare/v4.10.1...v4.10.2) (2020-10-23)
29 |
30 |
31 | ### Bug Fixes
32 |
33 | * 修复 BUG ([fe50821](https://github.com/dream2023/f-render/commit/fe50821918dfd1106ee23feccae3f88a102d771b))
34 | * 修复 switch 相关 BUG ([dfd0a7e](https://github.com/dream2023/f-render/commit/dfd0a7ecc349322983e8a5507641d547829d1618))
35 |
36 | ### [4.10.1](https://github.com/dream2023/f-render/compare/v4.9.0...v4.10.1) (2020-10-16)
37 |
38 | ## [4.10.0](https://github.com/dream2023/f-render/compare/v4.8.0...v4.10.0) (2020-10-14)
39 |
40 | ### Features
41 |
42 | - 兼容 ie11 ([4a140df](https://github.com/dream2023/f-render/commit/4a140dfe7a9a6460170c8905b308b2a613b1ade6))
43 |
44 | ## [4.8.0](https://github.com/dream2023/f-render/compare/v4.7.2...v4.8.0) (2020-09-14)
45 |
46 | ### Features
47 |
48 | - 修复级联组件默认值 BUG ([c950d55](https://github.com/dream2023/f-render/commit/c950d55cca9b6fb12e2568b71c1bcece51711652))
49 |
50 | ### [4.7.2](https://github.com/dream2023/f-render/compare/v4.7.1...v4.7.2) (2020-09-10)
51 |
52 | ### Bug Fixes
53 |
54 | - **#49:** 增加强制换行属性 ([fbbb9a5](https://github.com/dream2023/f-render/commit/fbbb9a5423ebd6d067e42f4e4de66e949e468065)), closes [#49](https://github.com/dream2023/f-render/issues/49)
55 | - form-props 和 form-item-common 增加 default ([b16c006](https://github.com/dream2023/f-render/commit/b16c006b45c176cce4fbe060a1159d5968c40118))
56 | - layout 会缩小 ([302bb06](https://github.com/dream2023/f-render/commit/302bb06549b8df2f2e12add2a45b43610e4fced3))
57 |
58 | ### [4.7.1](https://github.com/dream2023/f-render/compare/v4.7.0...v4.7.1) (2020-09-05)
59 |
60 | ### Bug Fixes
61 |
62 | - **#62:** 校检更新问题 ([1e7a3cc](https://github.com/dream2023/f-render/commit/1e7a3cc474d288244935f2ab76bfdfbdff7b1a35)), closes [#62](https://github.com/dream2023/f-render/issues/62)
63 |
64 | ## [4.7.0](https://github.com/dream2023/f-render/compare/v4.6.1...v4.7.0) (2020-09-02)
65 |
66 | ### Features
67 |
68 | - 增加 remoteMethod ([f19e705](https://github.com/dream2023/f-render/commit/f19e70583badf51f98a0871063c8c785257069f2))
69 |
70 | ### Bug Fixes
71 |
72 | - 修复 BUG & 升级依赖 ([3134a5c](https://github.com/dream2023/f-render/commit/3134a5cc0608abe4b838dc94067564b79701e872))
73 |
74 | ### [4.6.2](https://github.com/dream2023/f-render/compare/v4.6.1...v4.6.2) (2020-09-01)
75 |
76 | ### Bug Fixes
77 |
78 | - 修复 BUG & 升级依赖 ([3134a5c](https://github.com/dream2023/f-render/commit/3134a5cc0608abe4b838dc94067564b79701e872))
79 |
80 | ### [4.6.1](https://github.com/dream2023/f-render/compare/v4.6.0...v4.6.1) (2020-08-28)
81 |
82 | ### Bug Fixes
83 |
84 | - 修复 options BUG ([0079791](https://github.com/dream2023/f-render/commit/00797910c57c669d6e2163d7317894e01fb28850))
85 |
86 | ## [4.6.0](https://github.com/dream2023/f-render/compare/v4.5.0...v4.6.0) (2020-08-28)
87 |
88 | ### Features
89 |
90 | - 增加点击添加功能 ([f8c53d9](https://github.com/dream2023/f-render/commit/f8c53d9396e22dea7611cf3d13398bcbc4fac897))
91 | - 增加 order 属性, 避免回显时不一致 ([d81c4f4](https://github.com/dream2023/f-render/commit/d81c4f43050112bfd47f458b8fb160993a94b4b2))
92 |
93 | ### Bug Fixes
94 |
95 | - 处理 options 相关问题 ([ffef651](https://github.com/dream2023/f-render/commit/ffef651e571037b501ce801be9c47598037e1801))
96 |
97 | ## [4.5.0](https://github.com/dream2023/f-render/compare/v4.4.0...v4.5.0) (2020-08-26)
98 |
99 | ### Features
100 |
101 | - 优化体积 ([9618c00](https://github.com/dream2023/f-render/commit/9618c0017eb5bfe7a0526d07a0ae7b5c4660960e))
102 |
103 | ### Bug Fixes
104 |
105 | - 修复 data-editor types 的拼写错误 ([743dc16](https://github.com/dream2023/f-render/commit/743dc16c45786104d7e5ac52c0771ae75e320bc3))
106 | - 升级依赖 & 抽离全局组件 ([333e175](https://github.com/dream2023/f-render/commit/333e175908ddf1c5339aca15dabc615d224cf247))
107 | - 增加配置 ([6d337f5](https://github.com/dream2023/f-render/commit/6d337f5494dc8281a59678aec01248e2785081e1))
108 |
109 | ## [4.4.0](https://github.com/dream2023/f-render/compare/v4.3.2...v4.4.0) (2020-08-25)
110 |
111 | ### Features
112 |
113 | - 切换属性 Tab 时,滚动到顶部 ([00450a5](https://github.com/dream2023/f-render/commit/00450a59302134e0d3fa258434d501c1153ee8e3))
114 |
115 | ### [4.3.2](https://github.com/dream2023/f-render/compare/v4.3.1...v4.3.2) (2020-08-24)
116 |
117 | ### [4.3.1](https://github.com/dream2023/f-render/compare/v4.3.0...v4.3.1) (2020-08-24)
118 |
119 | ## [4.3.0](https://github.com/dream2023/f-render/compare/v3.1.0...v4.3.0) (2020-08-24)
120 |
121 | ### Features
122 |
123 | - 增加 Dockerfile ([240c669](https://github.com/dream2023/f-render/commit/240c66998418bd0068e8c78e1b0b945245a4e37c))
124 | - 增加 time-picker 配置 ([1f043ee](https://github.com/dream2023/f-render/commit/1f043eec6d86709cedcbed33132abd4e08239051))
125 | - 正则表达式校检不正确 ([31ca5c2](https://github.com/dream2023/f-render/commit/31ca5c282d57692a5c89b90cef0a46d4666b9d2d))
126 |
127 | ### Bug Fixes
128 |
129 | - 修复若干问题 ([#58](https://github.com/dream2023/f-render/issues/58)) ([60c6815](https://github.com/dream2023/f-render/commit/60c681569d842ff0027e0db75df9688441b2d7aa)), closes [#57](https://github.com/dream2023/f-render/issues/57) [#56](https://github.com/dream2023/f-render/issues/56) [#55](https://github.com/dream2023/f-render/issues/55)
130 | - 修复若干 BUG ([b8eea65](https://github.com/dream2023/f-render/commit/b8eea650a0f4b6a6335b392fe2d314d61f814e2b))
131 | - 修复 BUG & 增加联动属性 ([27377b4](https://github.com/dream2023/f-render/commit/27377b47a483c4c4d83fe12ea15fcf153d09858e))
132 | - 依赖报错 ([8eca6b5](https://github.com/dream2023/f-render/commit/8eca6b50fad64d99ed61e312ba72ce3268e9382d))
133 | - 预览清空原数据 ([db60207](https://github.com/dream2023/f-render/commit/db602073f5fc93c67b6d31b13a39aa48888c76e9))
134 | - labelWidth 计算不正确 ([7b35ce1](https://github.com/dream2023/f-render/commit/7b35ce1e67a2b908d2d3a4b4d3dc3a436e69a97e))
135 |
136 | ## [4.2.0](https://github.com/dream2023/f-render/compare/v3.1.0...v4.2.0) (2020-08-24)
137 |
138 | ### Features
139 |
140 | - 增加 Dockerfile ([240c669](https://github.com/dream2023/f-render/commit/240c66998418bd0068e8c78e1b0b945245a4e37c))
141 | - 增加 time-picker 配置 ([1f043ee](https://github.com/dream2023/f-render/commit/1f043eec6d86709cedcbed33132abd4e08239051))
142 | - 正则表达式校检不正确 ([31ca5c2](https://github.com/dream2023/f-render/commit/31ca5c282d57692a5c89b90cef0a46d4666b9d2d))
143 |
144 | ### Bug Fixes
145 |
146 | - 修复若干问题 ([#58](https://github.com/dream2023/f-render/issues/58)) ([60c6815](https://github.com/dream2023/f-render/commit/60c681569d842ff0027e0db75df9688441b2d7aa)), closes [#57](https://github.com/dream2023/f-render/issues/57) [#56](https://github.com/dream2023/f-render/issues/56) [#55](https://github.com/dream2023/f-render/issues/55)
147 | - 修复 BUG & 增加联动属性 ([27377b4](https://github.com/dream2023/f-render/commit/27377b47a483c4c4d83fe12ea15fcf153d09858e))
148 | - 依赖报错 ([8eca6b5](https://github.com/dream2023/f-render/commit/8eca6b50fad64d99ed61e312ba72ce3268e9382d))
149 | - 预览清空原数据 ([db60207](https://github.com/dream2023/f-render/commit/db602073f5fc93c67b6d31b13a39aa48888c76e9))
150 | - labelWidth 计算不正确 ([7b35ce1](https://github.com/dream2023/f-render/commit/7b35ce1e67a2b908d2d3a4b4d3dc3a436e69a97e))
151 |
--------------------------------------------------------------------------------
/src/f-render.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
37 |
38 |
39 |
40 |
41 |
319 |
320 |
389 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # f-render | 基于 ElementUI 的表单设计器
2 |
3 | [](https://github.com/dream2023/f-render)
4 | 
5 | 
6 | [](https://app.netlify.com/sites/f-render/deploys)
7 | 
8 | [](https://github.com/dream2023/f-render/stargazers)
9 |
10 |
11 |
12 |
13 |
14 | - [交流群](#%E4%BA%A4%E6%B5%81%E7%BE%A4)
15 | - [介绍](#%E4%BB%8B%E7%BB%8D)
16 | - [注意](#%E6%B3%A8%E6%84%8F)
17 | - [特性](#%E7%89%B9%E6%80%A7)
18 | - [Demo](#demo)
19 | - [教程](#%E6%95%99%E7%A8%8B)
20 | - [1 分钟快速接入](#1-%E5%88%86%E9%92%9F%E5%BF%AB%E9%80%9F%E6%8E%A5%E5%85%A5)
21 | - [第 1 步:安装](#%E7%AC%AC-1-%E6%AD%A5%E5%AE%89%E8%A3%85)
22 | - [第 2 步:注册](#%E7%AC%AC-2-%E6%AD%A5%E6%B3%A8%E5%86%8C)
23 | - [第 3 步:使用](#%E7%AC%AC-3-%E6%AD%A5%E4%BD%BF%E7%94%A8)
24 | - [用户模式](#%E7%94%A8%E6%88%B7%E6%A8%A1%E5%BC%8F)
25 | - [基于 f-render 的配置](#%E5%9F%BA%E4%BA%8E-f-render-%E7%9A%84%E9%85%8D%E7%BD%AE)
26 | - [基于 vue-ele-form 的配置](#%E5%9F%BA%E4%BA%8E-vue-ele-form-%E7%9A%84%E9%85%8D%E7%BD%AE)
27 | - [定制化](#%E5%AE%9A%E5%88%B6%E5%8C%96)
28 | - [新增官方扩展组件(以富文本扩展为例)](#%E6%96%B0%E5%A2%9E%E5%AE%98%E6%96%B9%E6%89%A9%E5%B1%95%E7%BB%84%E4%BB%B6%E4%BB%A5%E5%AF%8C%E6%96%87%E6%9C%AC%E6%89%A9%E5%B1%95%E4%B8%BA%E4%BE%8B)
29 | - [安装组件](#%E5%AE%89%E8%A3%85%E7%BB%84%E4%BB%B6)
30 | - [注册组件](#%E6%B3%A8%E5%86%8C%E7%BB%84%E4%BB%B6)
31 | - [配置属性](#%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7)
32 | - [新增自定义组件](#%E6%96%B0%E5%A2%9E%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BB%84%E4%BB%B6)
33 | - [创建组件并全局注册](#%E5%88%9B%E5%BB%BA%E7%BB%84%E4%BB%B6%E5%B9%B6%E5%85%A8%E5%B1%80%E6%B3%A8%E5%86%8C)
34 | - [书写配置](#%E4%B9%A6%E5%86%99%E9%85%8D%E7%BD%AE)
35 | - [合并配置并传入](#%E5%90%88%E5%B9%B6%E9%85%8D%E7%BD%AE%E5%B9%B6%E4%BC%A0%E5%85%A5)
36 | - [定制化原组件配置 & 表单配置](#%E5%AE%9A%E5%88%B6%E5%8C%96%E5%8E%9F%E7%BB%84%E4%BB%B6%E9%85%8D%E7%BD%AE--%E8%A1%A8%E5%8D%95%E9%85%8D%E7%BD%AE)
37 | - [定制化右侧 Tabs](#%E5%AE%9A%E5%88%B6%E5%8C%96%E5%8F%B3%E4%BE%A7-tabs)
38 | - [样式定制化](#%E6%A0%B7%E5%BC%8F%E5%AE%9A%E5%88%B6%E5%8C%96)
39 | - [二次开发](#%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91)
40 | - [f-render 问答集锦](#f-render-%E9%97%AE%E7%AD%94%E9%9B%86%E9%94%A6)
41 | - [Props 说明](#props-%E8%AF%B4%E6%98%8E)
42 | - [插槽](#%E6%8F%92%E6%A7%BD)
43 | - [生态](#%E7%94%9F%E6%80%81)
44 | - [特别感谢赞助者](#%E7%89%B9%E5%88%AB%E6%84%9F%E8%B0%A2%E8%B5%9E%E5%8A%A9%E8%80%85)
45 | - [Contributors ✨](#contributors-)
46 |
47 |
48 |
49 | ## 介绍
50 |
51 | f-render 是基于 [vue-ele-form](https://github.com/dream2023/vue-ele-form) 开发的可视化表单设计工具, 适用于 各种流程引擎和动态表单项目,大大节省你的开发时间;
52 |
53 | [](https://dream2023.gitee.io/f-render/)
54 |
55 | ## 注意
56 |
57 | 注意,此设计器不是独立存在的,是依托于 [vue-ele-form](https://github.com/dream2023/vue-ele-form),在使用前请务必阅读 [vue-ele-form 的文档](https://www.yuque.com/chaojie-vjiel/vbwzgu/xl46cd)。
58 |
59 | ## 特性
60 |
61 | - 组件方式:以组件方式接入,1 分钟轻松接入;
62 | - 体积小:Gzip 压缩后 `100k` 左右;
63 | - 易扩展:可以在`不更改源码`的情况下增删改属性、组件;
64 |
65 | ## Demo
66 |
67 | [https://dream2023.gitee.io/f-render/](https://dream2023.gitee.io/f-render/)
68 |
69 | ## 教程
70 |
71 | 虽然 f-render 可以做到在不更改源码的情况下实现大量的定制化,但是依然有不少人希望能够根据公司的需求进行二次开发。
72 |
73 | 所以我推出了一个从 0 实现整个项目的 [教程](https://www.lanqiao.cn/courses/2848),如果感兴趣 f-render 的实现过程和思考,可以点击 [从 0 实现可视化表单组件](https://www.lanqiao.cn/courses/2848) 进行学习。
74 |
75 | ## 1 分钟快速接入
76 |
77 | #### 第 1 步:安装
78 |
79 | ```bash
80 | yarn add element-ui # npm install element-ui -S
81 | yarn add vue-ele-form # npm install vue-ele-form -S
82 | yarn add f-render # npm install f-render -S
83 | ```
84 |
85 | #### 第 2 步:注册
86 |
87 | ```js
88 | // vue-ele-form 的注册可参考:https://www.yuque.com/chaojie-vjiel/vbwzgu/xl46cd
89 | import EleForm from "vue-ele-form";
90 | import FRender from "f-render";
91 | import ElementUI from "element-ui";
92 | import "element-ui/lib/theme-chalk/index.css";
93 |
94 | Vue.use(ElementUI);
95 | Vue.use(EleForm);
96 | Vue.component("f-render", FRender);
97 | ```
98 |
99 | #### 第 3 步:使用
100 |
101 | ```html
102 |
103 |
109 |
110 |
111 |
136 | ```
137 |
138 | ## 用户模式
139 |
140 | 我们把动态表单分为两个阶段:
141 |
142 | - 首先是设计阶段:通过拖拽设计表单;
143 | - 然后是用户阶段:将设计好的表单以纯表单的形式让用户填写。
144 |
145 | 我们别分称这两个阶段的表单为设计模式和用户模式。设计模式的表单配置我们已经讲了,下面看用户模式下的表单配置:
146 |
147 | #### 基于 f-render 的配置
148 |
149 | 通过属性 `pure`, 可以直接做为表单使用,其数据提交方式同 `vue-ele-form` 一样,具体可查看[文档](https://www.yuque.com/chaojie-vjiel/vbwzgu/zbu9mn)。
150 |
151 | ```html
152 |
153 |
160 |
161 |
162 |
190 | ```
191 |
192 | #### 基于 vue-ele-form 的配置
193 |
194 | 如果你的可视化设计和表单使用,不再一个系统,可以直接使用 `vue-ele-form`,不必安装 `f-render`,具体如下:
195 |
196 | ```html
197 |
198 |
205 |
206 |
207 |
238 | ```
239 |
240 | ## 定制化
241 |
242 | ### 新增官方扩展组件(以富文本扩展为例)
243 |
244 | #### 安装组件
245 |
246 | ```bash
247 | yarn add vue-ele-form-quill-editor
248 | ```
249 |
250 | #### 注册组件
251 |
252 | ```js
253 | Vue.component("quill-editor", EleFormQuillEditor);
254 | ```
255 |
256 | #### 配置属性
257 |
258 | ```html
259 |
260 |
261 |
262 |
263 |
264 |
282 | ```
283 |
284 | ### 新增自定义组件
285 |
286 | #### 创建组件并全局注册
287 |
288 | 需要根据 vue-ele-form 文档[创建自定义组件](https://www.yuque.com/chaojie-vjiel/vbwzgu/ugumna),并注册。
289 |
290 | #### 书写配置
291 |
292 | 你可以参考[源码中的配置]('./src/fixtures/comps.js'),一下是范例和属性说明:
293 |
294 | ```js
295 | // custom-url.js
296 | export default {
297 | // 假如这个组件叫 url(必填)
298 | type: "custom-url",
299 | // 默认标签名(必填)
300 | label: "URL",
301 | // 用于排序,值越小,越靠前
302 | sort: 1,
303 | // 属性配置
304 | config: {
305 | // 属性配置说明地址(可省略)
306 | url: "https://www.xxx.com",
307 | // 组件属性配置(不知道啥是组件属性,可以看一下界面右侧)
308 | attrs: {
309 | // config 配置 参考 FormDesc:
310 | // https://www.yuque.com/chaojie-vjiel/vbwzgu/iw5dzf#KOPkD
311 | config: {
312 | // max 为属性名
313 | max: {
314 | type: "number",
315 | label: "最大输入长度"
316 | },
317 | name: {
318 | type: "input",
319 | label: "原生 name",
320 | // 必填
321 | required: true
322 | }
323 | // ....
324 | },
325 | // 默认值,如果在配置文件里设置了,则每个组件都会携带
326 | data: {
327 | name: "url"
328 | }
329 | },
330 | // 表单项配置,是 FormDesc 中非 attrs 的其它配置,
331 | // 具体可看:https://www.yuque.com/chaojie-vjiel/vbwzgu/iw5dzf#hl4pm
332 | common: {
333 | config: {
334 | // 默认值
335 | default: {
336 | type: "input",
337 | label: "默认值"
338 | }
339 | },
340 | data: {}
341 | }
342 | }
343 | };
344 | ```
345 |
346 | #### 合并配置并传入
347 |
348 | ```html
349 |
350 |
351 |
352 |
353 |
354 |
365 | ```
366 |
367 | ### 定制化原组件配置 & 表单配置
368 |
369 | - 组件配置目录:`f-render/src/fixtures/comps.js`
370 | - 表单配置目录:`f-render/src/fixtures/form-props.js`
371 | - 表单项通用属性配置:`f-render/src/fixtures/form-item-common.js`
372 | - 扩展组件目录:`f-render/src/fixtures/extends/[扩展组件名].js`
373 |
374 | 如果你想修改组件属性或者表单的属性,减少或者增加组件,可以将上述文件`拷贝到自己的项目`目录,参考上述配置说明,进行更改,并传入即可:
375 |
376 | ```html
377 |
378 |
379 |
380 |
385 | ```
386 |
387 | 具体而言,如果想让每个 `input` 组件都携带 `clearable: true` 的属性,我们可以这样操作:
388 |
389 | ```html
390 |
391 |
392 |
393 |
394 |
395 |
396 |
411 | ```
412 |
413 | ### 定制化右侧 Tabs
414 |
415 | 我们可以通过 `isShowRight` 属性来控制右侧面板是否显示,通过 `rightTabs` 来定制具体显示的面板名称,具体如下:
416 |
417 | ```html
418 |
419 |
420 |
421 |
422 |
423 |
437 | ```
438 |
439 | ### 样式定制化
440 |
441 | 直接进行样式覆盖即可,注意不要加 `scoped`,否则覆盖不成功
442 |
443 | ## 二次开发
444 |
445 | 如果仅通过`属性`和`样式`定制化已无法满足的你和你产品经理的要求,那就需要进行定制化开发,我个人觉得代码整体还是非常简单的,你可以 `clone` 代码或者下载后(建议用[gitee](https://gitee.com/dream2023/f-render)),进行相应的更改,更改后有两种处理方式:
446 |
447 | - 直接放到项目目录里,并将安装 `dependencies` 的依赖复制到项目,进行开发即可;
448 | - 直接开发,然后发布到公司[私服](https://www.npmjs.com/package/verdaccio),如果是开源,则可以发到 GitHub 或者 gitee,然后安装自己的即可
449 |
450 | 具体的细节,开头提的[教程](https://www.lanqiao.cn/courses/2848)里会有详细的过程,希望大家可以支持一下。
451 |
452 | ## f-render 问答集锦
453 |
454 | - [1、f-render 不能做什么?](https://www.yuque.com/chaojie-vjiel/vbwzgu/adz8q8#0nlfc)
455 | - [2、怎么实现 options URL 配置?](https://www.yuque.com/chaojie-vjiel/vbwzgu/adz8q8#gvS8c)
456 |
457 | ## Props 说明
458 |
459 | ```js
460 | props: {
461 | // 表单内容
462 | config: {
463 | type: [Object, String],
464 | required: true
465 | },
466 | // 设计器整体高度
467 | height: {
468 | type: [String, Number],
469 | default: "400px"
470 | },
471 | // 保存格式
472 | saveFormat: {
473 | type: String,
474 | default: "string",
475 | validator(val) {
476 | return ["object", "string"].includes(val);
477 | }
478 | },
479 | // 是否纯净(用于显示表单)
480 | pure: Boolean,
481 | // 表单配置
482 | formProps: {
483 | type: Object,
484 | default: () => formProps
485 | },
486 | // 表单项配置
487 | formItemCommon: {
488 | type: Object,
489 | default: () => formItemCommonDefault
490 | },
491 | // 组件列表
492 | comps: {
493 | type: Array,
494 | default: () => comps
495 | },
496 | // 操作配置
497 | operations: {
498 | type: Array,
499 | default: () => ["preview", "data", "code", "batch", "clear", "save"]
500 | },
501 | // 是否显示右侧
502 | isShowRight: {
503 | type: Boolean,
504 | default: true
505 | },
506 | // 右侧属性面板 Tabs
507 | rightTabs: {
508 | type: Array,
509 | default: () => [
510 | { label: "表单项属性配置", name: "form-item-common" },
511 | { label: "组件属性配置", name: "form-item-attrs" },
512 | { label: "表单配置", name: "form-props" }
513 | ]
514 | },
515 | // 是否在加载
516 | loading: Boolean,
517 |
518 | // 表单相关(pure 为 true 时), 同 vue-ele-form
519 | // https://www.yuque.com/chaojie-vjiel/vbwzgu/dyw8a7
520 | requestFn: Function,
521 | isLoading: Boolean,
522 | formError: Object,
523 | // ....
524 | },
525 | ```
526 |
527 | ## 插槽
528 |
529 | - left:左侧组件列表
530 | - main: 中间区域
531 | - main-header: 头部操作区
532 | - main-content: 表单设计区
533 | - right: 右侧属性配置区
534 |
535 | 举例:
536 |
537 | ```html
538 |
539 |
540 |
541 |
542 |
543 |
left
544 |
{{frender.comps}}
545 |
546 |
547 |
548 |
550 | ```
551 |
552 | 其中 `frender` 数据是 `f-render` 组件数据的集合,具体都有哪些数据,可以参考[源码](https://gitee.com/dream2023/f-render/blob/master/src/f-render.vue),其它插槽均有此参数。
553 |
554 | ## 生态
555 |
556 | | Project | Status | Description |
557 | | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------ |
558 | | [vue-ele-form](https://github.com/dream2023/vue-ele-form) | [](https://github.com/dream2023/vue-ele-form) | 接基于 ElementUI 的数据驱动表单 |
559 | | [f-render](https://github.com/dream2023/f-render) | [](https://github.com/dream2023/f-render) | 专为 vue-ele-form 开发的可视化表单设计工具 |
560 | | [vue-ele-form-json-editor](https://github.com/dream2023/vue-ele-form-json-editor) | [](https://github.com/dream2023/vue-ele-form-json-editor) | JSON 编辑器(vue-ele-form 扩展) |
561 | | [vue-ele-form-upload-file](https://github.com/dream2023/vue-ele-form-upload-file) | [](https://github.com/dream2023/vue-ele-form-upload-file) | upload 文件上传组件(vue-ele-form 扩展) |
562 | | [vue-ele-form-image-uploader](https://github.com/dream2023/vue-ele-form-image-uploader) | [](https://github.com/dream2023/vue-ele-form-image-uploader) | 上传图片增强组件(vue-ele-form 扩展) |
563 | | [vue-ele-form-tree-select](https://github.com/dream2023/vue-ele-form-tree-select) | [](https://github.com/dream2023/vue-ele-form-tree-select) | 树形选择框组件(vue-ele-form 扩展) |
564 | | [vue-ele-form-table-editor](https://github.com/dream2023/vue-ele-form-table-editor) | [](https://github.com/dream2023/vue-ele-form-table-editor) | 表格编辑器(vue-ele-form 扩展) |
565 | | [vue-ele-form-dynamic](https://github.com/dream2023/vue-ele-form-dynamic) | [](https://github.com/dream2023/vue-ele-form-dynamic) | 动态表单(vue-ele-form 扩展) |
566 | | [vue-ele-form-video-uploader](https://github.com/dream2023/vue-ele-form-video-uploader) | [](https://github.com/dream2023/vue-ele-form-video-uploader) | 上传视频增强组件(vue-ele-form 扩展) |
567 | | [vue-ele-form-quill-editor](https://github.com/dream2023/vue-ele-form-quill-editor) | [](https://github.com/dream2023/vue-ele-form-quill-editor) | 富文本编辑器(vue-ele-form 扩展) |
568 | | [vue-ele-form-markdown-editor](https://github.com/dream2023/vue-ele-form-markdown-editor) | [](https://github.com/dream2023/vue-ele-form-markdown-editor) | markdown 编辑器(vue-ele-form 扩展) |
569 | | [vue-ele-form-bmap](https://github.com/dream2023/vue-ele-form-bmap) | [](https://github.com/dream2023/vue-ele-form-bmap) | 百度地图组件(vue-ele-form 扩展) |
570 | | [vue-ele-form-codemirror](https://github.com/dream2023/vue-ele-form-codemirror) | [](https://github.com/dream2023/vue-ele-form-codemirror) | 代码编辑器(vue-ele-form-gallery 扩展) |
571 | | [vue-ele-form-gallery](https://github.com/dream2023/vue-ele-form-gallery) | [](https://github.com/dream2023/vue-ele-form-gallery) | 图片/视频展示组件(vue-ele-form 扩展) |
572 | | [vue-ele-form-data-editor](https://github.com/dream2023/vue-ele-form-data-editor) | [](https://github.com/dream2023/vue-ele-form-data-editor) | 轻量级数据编辑器(vue-ele-form 扩展) |
573 |
574 | 特别感谢赞助者
575 |
576 |
618 |
619 |
620 | > 如果您觉得对您有所帮助, 可以请作者喝一杯咖啡, 让开源走的更远, 点击进入[码云赞赏](https://gitee.com/dream2023/f-render)一下, 并加入下面交流群, 将链接发送给我
621 |
622 | ## Contributors ✨
623 |
624 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
625 |
626 |
627 |
628 |
629 |
636 |
637 |
638 |
639 |
640 |
641 |
642 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
643 |
--------------------------------------------------------------------------------