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' }]
        }
      ]