vue如何生成动态表单?

碰到个问题,麻烦大家看看有啥好的思路不。
有个需求,需要根据后端数据动态生成表单,有各种各样类型,文本框,单选多选,下拉表单……
后端会传递过来表单类型,表单name,表单所需数据。

用vue去写,根据不同的type去生成不同类型的输入框,但是这样动态的数据,我们无法直接写到vue的data里,无法很好的提交用户输入的数据。

目前的思路是和后端商量好,前端尽量覆盖全部的字段。后端返回哪些字段需要显示和部分类型需要的数据。

阅读 27.5k
8 个回答

我在项目中也遇到了这个问题,思路和你差不多,就是针对各个表单写好通用的组件,然后根据typev-if来渲染对应的表单,数据,事件什么的都可以动态的传进去

// template
<div v-for="(item, index) in formData">
    <input v-if="item.type === 'input'" v-model='item.val'>
    <radio v-if="item.type === 'radio'" @click='item.process'></radio>
    <checkbox v-if="item.type === 'checkbox'" @click='item.process'></checkbox>
    ...
</div>
<input type="button" @click="submit"></input>
<script>
export.dafault = {
    data () {
        return {
            formData: [{
                type: 'input',
                val: ''
            },{
                type: 'radio',
                data: {...},
                process: this.click1,
                val: ''    
            }, {
                type: 'checkbox'
                data: {...}
                process: this.click2,
                val: ''
            }]
        }
    },
    methods: {
        click1 () {
            console.log(1)
        },
        click2 () {
            ...
        },
        submit () {
            // 在这里可以拿到用户输入的值,通过v-model赋的值
            // 我在这里就直接取值了,这里的麻烦之处就在于可能需要遍历formData来取到对应的值
            // 可以使用数组的find方法 
            console.log(this.formData[0].val)
        }
    }
}

</script>
新手上路,请多包涵

写一个form组件 用来渲染表单、form接收一个数组 例如

<xx-form :params="params ">

params = {
    ...其它必要参数,
    fields: [
        {
            type:"text",
            name:"后端字段名",
            isEdit:true,
            isQuery:true,
            isList:true,
            isAdd:true
        },
        {
            type:"select",
            name:"字段名",
            options:{
                list:[
                    {
                        label: '红方',
                        value: 0
                     },
                     {
                        label: '蓝方',
                        value: 1
                     }
                ]
            }
        }
    ]
 }

其实大概就是这个个感觉 根据isAdd类似的参数 来决定是不是可编辑 可查询 复杂一点的就是例如这个select date select可能要根据数据字典来操作,那你就要考虑处理一下ajax

组件内部无非就是根据type来 v-if渲染不同的组件 组件越多 v-if也就越多

<template v-for="item in params.fields>

<template v-if="item.type === "text">
    <input type="text" v-model="formdata[item.name]"></input>
</template>
 <template v-if="item.type === "select">
   <select  v-model="formdata[item.name]">
       <options v-for="xxx in item.options.list" :value="xxx.value">{{xxx.label}}</options>
   </select>
</template>

</template>

然后将form组件的fomrdata暴漏出去,并提供一个设置的方法
思路大体就是这样 无非你需要自己考虑的更多一点 比如 ajax的处理、表单验证、处理更多的可渲染项 例如富文本编辑器、日期

可以使用form-create动态生成表单,form-create 是一个可以通过 JSON 生成具有动态渲染、数据收集、验证和提交功能的表单动态生成组件。并且支持生成任何 Vue 组件。结合内置17种常用表单组件和自定义组件,再复杂的表单都可以轻松搞定。github地址

目前以支持如下 UI

ElementUI 版本

npm i @form-create/element-ui

Iview 版本 2.x|3.x

npm i @form-create/iview

Iview 版本 4.x

npm i @form-create/iview4

Ant-design-vue 版本 1.5.3+

npm i @form-create/ant-design-vue

新手上路,请多包涵

请问有没有完整的demo呀 现在不知道如何下手

新手上路,请多包涵
新手上路,请多包涵

如果多个field之间有逻辑关系,怎么实现了,或者某个field有某个event的响应?如何实现

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题