f-render is a visual form design tool developed based on vue-ele-form. It is suitable for various process engines and dynamic form projects, greatly saving your development time;
Note that this designer does not exist independently, but relies on vue-ele-form. Please be sure to read the documentation of vue-ele-form before using it.
100k
after Gzip compression;不更改源码
; https://dream2023.gitee.io/f-render/
Although f-render can achieve a large amount of customization without changing the source code, many people still hope to carry out secondary development according to the company's needs.
So I launched a tutorial to implement the entire project from scratch. If you are interested in the implementation process and thinking of f-render, you can click Implement Visual Form Component from Zero to learn.
yarn add element-ui # npm install element-ui -S
yarn add vue-ele-form # npm install vue-ele-form -S
yarn add f-render # npm install f-render -S
// vue-ele-form 的注册可参考:https://www.yuque.com/chaojie-vjiel/vbwzgu/xl46cd
import EleForm from "vue-ele-form" ;
import FRender from "f-render" ;
import ElementUI from "element-ui" ;
import "element-ui/lib/theme-chalk/index.css" ;
Vue . use ( ElementUI ) ;
Vue . use ( EleForm ) ;
Vue . component ( "f-render" , FRender ) ;
< template >
< f-render
@save =" handleSave "
:loading =" loading "
height =" calc(100vh - 60px) "
:config =" formConfig "
/>
</ template >
< script >
export default {
data ( ) {
return {
loading : false ,
formConfig : { }
} ;
} ,
methods : {
handleSave ( res ) {
// 这里是保存到 localStorage,你可以保存到服务器
localStorage . setItem ( "form-config" , res ) ;
this . $message . success ( "保存成功啦~" ) ;
}
} ,
mounted ( ) {
// 模拟异步加载
this . loading = true ;
setTimeout ( ( ) => {
this . loading = false ;
this . formConfig = localStorage . getItem ( "form-config" ) || "" ;
} , 1000 ) ;
}
} ;
</ script >
We divide dynamic forms into two stages:
We call these two stages of forms design mode and user mode respectively. We have already talked about the form configuration in design mode. Let’s look at the form configuration in user mode:
Through the attribute pure
, it can be used directly as a form. The data submission method is the same as vue-ele-form
. Please check the documentation for details.
< template >
< f-render
v-model =" formData "
:request-fn =" handleSubmit "
@request-success =" handleSuccess "
:config =" formConfig "
pure
/>
</ template >
< script >
export default {
data ( ) {
return {
formData : { } ,
formConfig : ""
} ;
} ,
methods : {
handleSubmit ( data ) {
// eslint-disable-next-line no-console
console . log ( data ) ;
return Promise . resolve ( ) ;
} ,
handleSuccess ( ) {
this . $message . success ( "创建成功" ) ;
}
} ,
mounted ( ) {
// 模拟异步加载
this . loading = true ;
setTimeout ( ( ) => {
this . loading = false ;
this . formConfig = localStorage . getItem ( "form-config" ) || "" ;
} , 1000 ) ;
}
} ;
</ script >
If your visual design and form use are no longer the same system, you can use vue-ele-form
directly without installing f-render
. The details are as follows:
< template >
< ele-form
v-model =" formData "
:request-fn =" handleSubmit "
@request-success =" handleSuccess "
v-if =" formConfig "
v-bind =" formConfig "
/>
</ template >
< script >
export default {
data ( ) {
return {
formData : { } ,
formConfig : null
} ;
} ,
methods : {
handleSubmit ( data ) {
// eslint-disable-next-line no-console
console . log ( data ) ;
return Promise . resolve ( ) ;
} ,
handleSuccess ( ) {
this . $message . success ( "创建成功" ) ;
}
} ,
mounted ( ) {
// 模拟异步加载
setTimeout ( ( ) => {
try {
// 这里必须对字符串进行反序列化
this . formConfig = eval ( `( ${ localStorage . getItem ( "form-config" ) } )` ) ;
} catch {
this . $message . error ( "数据解析失败" ) ;
}
} , 1000 ) ;
}
} ;
</ script >
yarn add vue-ele-form-quill-editor
Vue . component ( "quill-editor" , EleFormQuillEditor ) ;
< template >
<!-- 省略其它属性 -->
< f-render :comps =" comps " />
</ template >
< script >
// 默认配置
import comps from "f-render/src/fixtures/comps" ;
// 富文本配置
import quillEditor from "f-render/src/fixtures/extends/quill-editor" ;
// 可以更改显示组件位置,默认为 10
// 这里更改为 2,显示更靠前
quillEditor . sort = 2 ;
export default {
data ( ) {
return {
// 拼接上即可
comps : comps . concat ( quillEditor )
} ;
}
} ;
</ script >
You need to create a custom component according to the vue-ele-form document and register it.
You can refer to the configuration in the source code. Here are examples and attribute descriptions:
// custom-url.js
export default {
// 假如这个组件叫 url(必填)
type : "custom-url" ,
// 默认标签名(必填)
label : "URL" ,
// 用于排序,值越小,越靠前
sort : 1 ,
// 属性配置
config : {
// 属性配置说明地址(可省略)
url : "https://www.xxx.com" ,
// 组件属性配置(不知道啥是组件属性,可以看一下界面右侧)
attrs : {
// config 配置 参考 FormDesc:
// https://www.yuque.com/chaojie-vjiel/vbwzgu/iw5dzf#KOPkD
config : {
// max 为属性名
max : {
type : "number" ,
label : "最大输入长度"
} ,
name : {
type : "input" ,
label : "原生 name" ,
// 必填
required : true
}
// ....
} ,
// 默认值,如果在配置文件里设置了,则每个组件都会携带
data : {
name : "url"
}
} ,
// 表单项配置,是 FormDesc 中非 attrs 的其它配置,
// 具体可看:https://www.yuque.com/chaojie-vjiel/vbwzgu/iw5dzf#hl4pm
common : {
config : {
// 默认值
default : {
type : "input" ,
label : "默认值"
}
} ,
data : { }
}
}
} ;
< template >
<!-- 省略其它属性 -->
< f-render :comps =" comps " />
</ template >
< script >
import comps from "f-render/src/fixtures/comps" ;
import customUrl from "some/path/custom-url" ;
export default {
data ( ) {
return {
comps : comps . concat ( customUrl )
} ;
}
} ;
</ script >
f-render/src/fixtures/comps.js
f-render/src/fixtures/form-props.js
f-render/src/fixtures/form-item-common.js
f-render/src/fixtures/extends/[扩展组件名].js
If you want to modify component properties or form properties, reduce or add components, you can拷贝到自己的项目
directory, refer to the above configuration instructions, make changes, and pass them in:
<!-- formProps 是表单属性 -->
<!-- comps 是组件列表和属性 -->
<!-- formItemCommon 是表单项通用属性配置 -->
< f-render
:form-props =" formProps "
:comps =" comps "
:form-item-common =" formItemCommon "
/>
Specifically, if we want each input
component to carry clearable: true
attribute, we can do this:
< template >
<!-- 其它属性省略 -->
<!-- 将更改后的 comps 传递过去即可 -->
< f-render :comps =" comps " />
</ template >
< script >
import comps from "f-render/src/fixtures/comps" ;
// 查找 input 组件,当然你也可以看源码,直接查看索引
const inputIndex = comps . findIndex ( item => item . type === "input" ) ;
// 更改 config.attrs.data 值即可
comps [ inputIndex ] . config . attrs . data = { clearable : true } ;
export default {
data ( ) {
return {
comps
} ;
}
} ;
</ script >
We can control whether the right panel is displayed through isShowRight
attribute, and customize the specific displayed panel name through rightTabs
, as follows:
< template >
<!-- 定制化右侧 tabs -->
< f-render :right-tabs =" tabs " />
</ template >
< script >
export default {
data ( ) {
return {
tabs : [
{ label : "表单项属性配置" , name : "form-item-common" } ,
{ label : "组件属性配置" , name : "form-item-attrs" }
// 注释下面的内容,就可以不显示
// { label: "表单配置", name: "form-props" }
]
} ;
}
} ;
</ script >
Just overwrite the style directly. Be careful not to add scoped
, otherwise the override will not be successful.
If the requirements of you and your product manager cannot be met through属性
and样式
customization alone, then customized development is required. Personally, I think the overall code is very simple. You can clone
the code or download it (it is recommended to use gitee) , make corresponding changes. There are two ways to process the changes:
dependencies
to the project for development;For specific details, there will be a detailed process in the tutorial mentioned at the beginning. I hope you can support it.
props : {
// 表单内容
config : {
type : [ Object , String ] ,
required : true
} ,
// 设计器整体高度
height : {
type : [ String , Number ] ,
default : "400px"
} ,
// 保存格式
saveFormat : {
type : String ,
default : "string" ,
validator ( val ) {
return [ "object" , "string" ] . includes ( val ) ;
}
} ,
// 是否纯净(用于显示表单)
pure : Boolean ,
// 表单配置
formProps : {
type : Object ,
default : ( ) => formProps
} ,
// 表单项配置
formItemCommon : {
type : Object ,
default : ( ) => formItemCommonDefault
} ,
// 组件列表
comps : {
type : Array ,
default : ( ) => comps
} ,
// 操作配置
operations : {
type : Array ,
default : ( ) => [ "preview" , "data" , "code" , "batch" , "clear" , "save" ]
} ,
// 是否显示右侧
isShowRight : {
type : Boolean ,
default : true
} ,
// 右侧属性面板 Tabs
rightTabs : {
type : Array ,
default : ( ) => [
{ label : "表单项属性配置" , name : "form-item-common" } ,
{ label : "组件属性配置" , name : "form-item-attrs" } ,
{ label : "表单配置" , name : "form-props" }
]
} ,
// 是否在加载
loading : Boolean ,
// 表单相关(pure 为 true 时), 同 vue-ele-form
// https://www.yuque.com/chaojie-vjiel/vbwzgu/dyw8a7
requestFn : Function ,
isLoading : Boolean ,
formError : Object ,
// ....
} ,
Example:
< template >
< f-render >
<!-- 左侧插槽 -->
< template v-slot:left =" {frender} " >
< div >
< div > left </ div >
< div > {{frender.comps}} </ div >
</ div >
</ template >
</ f-render >
< template > </ template
> </ template >
The frender
data is a collection of f-render
component data. For specific data, please refer to the source code. Other slots have this parameter.
Project | Status | Description |
---|---|---|
vue-ele-form | Connect to data-driven forms based on ElementUI | |
f-render | Visual form design tool specially developed for vue-ele-form | |
vue-ele-form-json-editor | JSON editor (vue-ele-form extension) | |
vue-ele-form-upload-file | upload file upload component (vue-ele-form extension) | |
vue-ele-form-image-uploader | Upload image enhancement component (vue-ele-form extension) | |
vue-ele-form-tree-select | Tree selection box component (vue-ele-form extension) | |
vue-ele-form-table-editor | Form editor (vue-ele-form extension) | |
vue-ele-form-dynamic | Dynamic form (vue-ele-form extension) | |
vue-ele-form-video-uploader | Upload video enhancement component (vue-ele-form extension) | |
vue-ele-form-quill-editor | Rich text editor (vue-ele-form extension) | |
vue-ele-form-markdown-editor | markdown editor (vue-ele-form extension) | |
vue-ele-form-bmap | Baidu map component (vue-ele-form extension) | |
vue-ele-form-codemirror | Code editor (vue-ele-form-gallery extension) | |
vue-ele-form-gallery | Image/video display component (vue-ele-form extension) | |
vue-ele-form-data-editor | Lightweight data editor (vue-ele-form extension) |
Excellent customer service | Shengjie Yuanchuang | damonnie | xzusoft | seeenter | high pitched |
If you think it is helpful to you, you can buy the author a cup of coffee to make open source go further. Click to enter the code cloud to appreciate it, join the communication group below, and send me the link.
Thanks goes to these wonderful people (emoji key):
Zhang Chaojie ? | Wisen | IWANABETHATGUY |
This project follows the all-contributors specification. Contributions of any kind welcome!