vue动态表单DynamicForm
效果:
预期:像这样的表单结构,如果在form中一行一行写每个文本域,有点麻烦,封装成一个组件,同类型支持新增和删除
①DynamicForm.vue
<template> <div class="dynamic-form"> <div class="title"> <p>{{template.title}}p> <van-icon name="add-o" @click="handleAdd" /> div> <div class="content" v-for="(item,index) in MyList" :key="index"> <p class="icon" @click="handleDelete(index)"> <img src="@/assets/public/delete.svg"> p> <van-field v-for="(ele,i) in template.labels" :key="i" v-model="item[ele.field]" rows="3" autosize :label="ele.name" placeholder="请输入" type="textarea" maxlength="200" show-word-limit clearable required :rules="[{required:true,message:'必填项,不能为空'}]" /> div> div> template> <script> export default { model: { prop: 'data', event: 'change' }, computed: { MyList: { get: vm => vm.data, set(data) { this.$emit('change', data) } } }, props: { template: { type: Object, required: true }, data: { type: Array, require: true } }, methods: { handleAdd() { this.MyList.push({}) }, handleDelete(index) { if (this.MyList.length === 1) return this.$toast('必须保留一项') this.MyList.splice(index, 1) } } } script>
②拜访计划中使用
// 引入 import DynamicForm from '@/components/DynamicForm' // data page2Data: [ { title: '拜访计划', variable: 'requirements', labels: [ { name: '初步预测需求点', field: 'requirement' }, { name: '判断理由', field: 'reason' } ], data: [{}] }, { title: '提问设计(我方提问)', variable: 'questions', labels: [{ name: '问题', field: 'question' }], data: [{}] }, { title: '杜宾清单(客户会提的问题或者顾虑)', variable: 'duBins', labels: [ { name: '问题', field: 'question' }, { name: '解决方案', field: 'solution' } ], data: [{}] }, { title: '信任等级', variable: 'trustLevels', labels: [ { name: '提升计划', field: 'improvementPlan' }, { name: '原因', field: 'reason' } ], data: [{}] }, { title: '物料准备', variable: 'materials', labels: [ { name: '具体物料', field: 'material' }, { name: '选择原因', field: 'reason' } ], data: [{}] } ]
DOM:
<van-form @submit="handleSubmit" validate-trigger='onSubmit'> <DynamicForm v-for="(item,index) in page2Data" :key="index" v-model="item.data" :template='item' /> <div class="page2-footer"> <van-button native-type="submit" :loading='submitLoading'>提交van-button> div> van-form>
得到的数据结构:
const arr = [ { title: '拜访计划', variable: 'requirements', labels: [ { name: '初步预测需求点', field: 'requirement' }, { name: '判断理由', field: 'reason' } ], data: [{ requirement: '2', reason: '2' }] }, { title: '提问设计(我方提问)', variable: 'questions', labels: [{ name: '问题', field: 'question' }], data: [{ question: '1' }] }, { title: '杜宾清单(客户会提的问题或者顾虑)', variable: 'duBins', labels: [ { name: '问题', field: 'question' }, { name: '解决方案', field: 'solution' } ], data: [{ question: '1', solution: '1' }] }, { title: '信任等级', variable: 'trustLevels', labels: [ { name: '提升计划', field: 'improvementPlan' }, { name: '原因', field: 'reason' } ], data: [{ improvementPlan: '6', reason: '6' }] }, { title: '物料准备', variable: 'materials', labels: [ { name: '具体物料', field: 'material' }, { name: '选择原因', field: 'reason' } ], data: [{ material: '16', reason: '6' }] } ]
③拜访反馈中使用
// 引入 import DynamicForm from '@/components/DynamicForm' // data page2Data: [ { title: '需求调研结果汇总', variable: 'requirementList', labels: [ { name: '客户实际需求', field: 'requirement' }, { name: '判断理由', field: 'reason' } ], data: [{}] }, { title: '客户实际提出的顾虑/问题', variable: 'questionList', labels: [{ name: '顾虑/问题', field: 'concern' }], data: [{}] } ]
DOM:
<van-form @submit="handleSubmit" validate-trigger='onSubmit'> <DynamicForm v-for="(item,index) in page2Data" :key="index" v-model="item.data" :template='item' /> <div class="page2-footer"> <van-button native-type="submit" :loading='submitLoading'>提交van-button> div> van-form>
得到的数据结构:
const arr = [ { title: '需求调研结果汇总', variable: 'requirementList', labels: [ { name: '客户实际需求', field: 'requirement' }, { name: '判断理由', field: 'reason' } ], data: [ { requirement: '1', reason: '2' }, { requirement: '11', reason: '22' } ] }, { title: '客户实际提出的顾虑/问题', variable: 'questionList', labels: [{ name: '顾虑/问题', field: 'concern' }], data: [{ concern: '1' }] } ]