Bootstrap

Vue+antd做一个批量新增的动态表单(增加/删除表单)

<template>
	<div class="addDevice">

		<div class="deviceContent">
			<a-page-header
				class="titleHeader"
				:title="$t('AddEquip')"
				:sub-title="$t('AddEquip1')"
			/>

			<div class="device">

				<a-form-model v-for="(form, index) in deviceForm" :key="index" :rules="rules" :model="form" :ref="'form'+index" class="deviceForm" :label-col="{ span: 3 }" :wrapper-col="{ span: 6 }">

					<a-button type="primary" class="deleteBtn" @click="deleteDevice(index)">{{ $t('deletes') }}</a-button>

					<a-form-model-item :label="$t('EquipmentType')" prop="device_id" class="setSelect">
						<a-select v-model="form.device_id" placeholder="请选择设备类型">
							<a-select-option v-for="(item, index) in deviceTypeList" :key="index" :value="item.device_id">{{ item.device_name }}</a-select-option>
						</a-select>
					</a-form-model-item>

					<a-form-model-item :label="$t('DeviceName')" prop="name">
						<a-input v-model="form.name" :placeholder="$t('PleaseEnterName')"/>
					</a-form-model-item>

					<a-form-model-item :label="$t('EnglishEquipment')" prop="name_en">
						<a-input v-model="form.name_en" :placeholder="$t('PleaseEnglishName')"/>
					</a-form-model-item>

					<a-form-model-item :label="$t('DonglePoint')" prop="use_dongle_divide">
						<a-radio-group v-model="form.use_dongle_divide" v-decorator="['radio-group']">
							<a-radio value="1">{{ $t('yes') }}</a-radio>
							<a-radio value="0">{{ $t('no') }}</a-radio>
						</a-radio-group>
					</a-form-model-item>

					<a-form-model-item :label="$t('ThirdParty')" prop="is_third">
						<a-radio-group v-model="form.is_third" v-decorator="['radio-group']">
							<a-radio value="1">{{ $t('yes') }}</a-radio>
							<a-radio value="0">{{ $t('no') }}</a-radio>
						</a-radio-group>
					</a-form-model-item>

					<a-form-model-item :label="$t('remarks')">
						<a-textarea v-model="form.remark" :rows="4" :placeholder="$t('PleaseComments')"></a-textarea>
					</a-form-model-item>

				</a-form-model>
				<div class="btn">
					<a-button type="primary" :loading="loading" @click="applyCheck">{{ $t('apply') }}</a-button>
					<a-button type="primary" @click="addDevice" style="margin-left: 30px;">{{ $t('AddEquipment') }}</a-button>
				</div>
			</div>

		</div>

	</div>
</template>

<script>
  import { addMachines, getMachinesSimpleList } from '@/api/device'
  export default {
    name: "addDevice",
    i18n: require('../i18n'),
    data() {
      return {
        key: '',
        loading: false,
        resultValidateList: [],
				deviceTypeList: [],
        deviceForm: [
          {
            name: '',
            name_en: '',
            device_id: undefined,
            use_dongle_divide: '',
            is_third: '',
            remark: ''
          }
        ],
        rules: {
          name: [
            { required: true, message: '请填写设备中文名!', trigger: 'blur' }
          ],
          name_en: [
            { required: true, message: '请填写设备英文名!', trigger: 'blur' }
          ],
          device_id: [
            { required: true, message: '请选择设备类型!', trigger: 'change' }
          ],
          use_dongle_divide: [
            { required: true, message: '加密狗是否扣点!', trigger: 'change' }
					],
          is_third: [
            { required: true, message: '是否第三方设备!', trigger: 'change' }
					]
				}
      }
    },
    methods: {

      // 创建设备
      addMachines() {

				const _this = this
        this.loading = true
        const deviceArray = JSON.parse(JSON.stringify(this.deviceForm))

        deviceArray.forEach((item) => {
          item.device_id = Number(item.device_id)
          item.use_dongle_divide = Number(item.use_dongle_divide)
          item.is_third = Number(item.is_third)
				})

				const params = {
          operator_id: Number(this.$route.query.id),
          apply_id: 0,
          machines: deviceArray
				}

        addMachines(params, this.key).then(response => {
          this.loading = false
          const { code, msg } = response.data
          if (code === 1) {
            this.$message.success(msg, 3)

            setTimeout(function() {
              _this.$closePage(_this.$route.path, '/store/list')
            }, 500)
          }
        }).catch(() => {
          this.loading = false
        })
      },

      // 删除设备
      deleteDevice(index) {
        this.deviceForm.splice(index, 1)
			},

      // 提交表单
      applyCheck() {

        this.resultValidateList = []

        for(let i = 0; i < this.deviceForm.length; i++){
          this.checkValidate('form' + i)
        }

        Promise.all(this.resultValidateList).then(() => {
          // 提交数据
					this.addMachines()
        })
      },

      // 表单验证
      checkValidate(name) {

        const that = this
        const result = new Promise((resolve, reject) => {
          that.$refs[name][0].validate(valid => {
            if (valid) {
              resolve(true)
            } else {
              reject(false)
						}
          })
        })
        this.resultValidateList.push(result)
			},

			// 增加设备
      addDevice() {
        if (this.deviceForm.length < 10 ) {
          const arr = {
            name: '',
            name_en: '',
            device_id: undefined,
            use_dongle_divide: '',
            is_third: '',
            remark: ''
          }
          this.deviceForm.push(arr)
				} else {
          this.$message.warn('最多一次新增10个设备', 3)
				}
			},

      // 获取设备类型
      getMachinesSimpleList() {
        const params = {
          page: 0,
          limit: 0,
          status: 1
        }
        getMachinesSimpleList(params, this.key).then(response => {
          const { data } = response.data
          this.deviceTypeList = data.list
        })
      },
    },
    created() {
      // 路由key
      this.key = this.$route.meta.key

      // 获取设备类型
      this.getMachinesSimpleList()
    },
  }
</script>

<style lang="less" scoped>
	.addDevice{
		background: #fff;
		padding: 30px;
		min-height: 750px;

		.deviceContent{

			.titleHeader{
				padding-bottom: 40px;
			}

			.device{

				.deviceForm{
					position: relative;
					border-bottom: 1px solid #e4e3e3;
					padding-bottom: 25px;
					margin-bottom: 40px;

					.deleteBtn{
						position: absolute;
						top: 0;
						right: 47%;
						cursor: pointer;
						z-index: 9;
					}
				}
			}

			.btn{
				margin-left: 160px;
			}

			.more{
				cursor: pointer;
				padding-left: 21%;
				text-align: left;
				margin-bottom: 30px;
				color: rgba(0, 0, 0, 0.85);
			}
		}

	}
</style>

;