vue3 + element-plus 实现动态表单

1. 做一个这样的需求

点击新增,新增一行表单,点击保存,保存该条数据,点击取消删除该条数据

想法是循环form表单,把表单独有的的组电压表都放到一个数组里,包括disabled,ref,通过点击每一行的按钮传参index,取到disabled数组和ref数组中下角标为index的值

可以做多条保存,但没做

动态表单演示

2. 代码实现

<template>
  <div class="app-container">
    <el-dialog
      :modelValue="dialogVisible"
      :title="`${title}投资与营收`"
      width="60%"
      :before-close="handleClose"
    >
      <!-- 月度投资区域 -->
      <div class="month-content">
        <div class="month">
          <div class="title">月度投资</div>
          <el-button
            type="primary"
            plain
            @click="handleMonthAdd"
          >新增</el-button>
        </div>

        <div class="content">
          <div
            v-for="( item, index ) in monthForm.monthArr"
            :key="item.key"
          >
            <el-form
              :ref="el => getMonthRef(el, index)"
              :model="monthForm"
              class="month-item"
            >
              <el-form-item
                label="月份"
                :prop="'monthArr.' + index + '.month'"
                :rules="rules.month"
              >
                <el-date-picker
                  :clearable="false"
                  :disabled="monthDisabled[index]"
                  v-model="item.month"
                  value-format="YYYY-MM"
                  type="month"
                  placeholder="请选择月份"
                  style="width: 100%"
                  :validate-event="false"
                />
              </el-form-item>
              <el-form-item
                label="金额"
                :prop="'monthArr.' + index + '.money'"
                :rules="rules.money"
                style="margin-left: 10px; margin-right: 10px;"
              >
                <el-input
                  :disabled="monthDisabled[index]"
                  v-model="item.money"
                  placeholder="请输入金额"
                >
                  <template #suffix>
                    <span>元</span>
                  </template>
                </el-input>
              </el-form-item>
              <el-button
                v-if="!isMonthSubmit[index]"
                type="primary"
                plain
                @click="handleMonthSubmit(index)"
              >保存</el-button>
              <el-button
                v-if="!isMonthSubmit[index]"
                plain
                @click="handleMonthDel(index)"
              >取消</el-button>
              <el-button
                v-if="isMonthSubmit[index]"
                type="danger"
                plain
                @click="handleMonthDelData(item.projectInvestmentId, index)"
              >删除</el-button>
            </el-form>
          </div>
        </div>
      </div>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="handleClose">取消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup name="projectManagement-create">
import { ElMessage } from 'element-plus';
import {
  createInvest,
  deleteInvest,
  getDetailInvest,
} from '@/api/projectManagement';
import { onMounted } from 'vue';
const props = defineProps({
  title: {
    type: String,
    default: '',
  },
  dialogVisible: {
    type: Boolean,
    default: false,
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  monthCurrentObj: {
    type: Object,
    default: {},
  },
  projectId: {
    type: Number,
    default: null,
  },
});

const emit = defineEmits(['handleClose']);

// 校验月份是否重复
const checkMonth = (rule, value, callback) => {
  let data = [];
  monthForm.value.monthArr.forEach((item, index) => {
    if (index !== checkMonthIndex.value) {
      data.push(item.month.slice(0, 7));
    }
  });
  console.log(data, 'datadatadata');

  data.forEach(item => {
    if (item === value) {
      callback(new Error('投资时间已存在'));
    }
  });
  callback();
};

const rules = {
  month: [
    { required: true, message: '月份不能为空', trigger: 'change' },
    { validator: checkMonth, trigger: 'change' },
  ],
  money: [
    { required: true, message: '金额不能为空', trigger: 'change' },
    {
      pattern: /(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^[0-9]\.[0-9]([0-9])?$)/,
      message: '金额应大于零且最多保留小数点后两位',
      trigger: 'change',
    },
  ],
};

// 月度投资变量
const monthForm = ref({
  monthArr: [],
});
const monthNum = ref(0);
const isMonthSubmit = ref([]);
const monthDisabled = ref([]);
const checkMonthIndex = ref();
const monthRefList = ref([]);

// 获取 monthRef
const getMonthRef = (el, index) => {
  if (el) {
    monthRefList.value[index] = el;
  }
};

// 监听月度投资 “新增” 按钮
const handleMonthAdd = () => {
  monthForm.value.monthArr.push({
    month: '',
    money: '',
    key: 'momth' + monthNum.value++,
  });
  isMonthSubmit.value.push(false);
  monthDisabled.value.push(false);
};

// 监听月度投资 “保存” 按钮
const handleMonthSubmit = index => {
  checkMonthIndex.value = index;
  // 月度投资
  monthRefList.value[index].validate(valid => {
    if (valid) {
      let form = {
        projectId: props.projectId,
        investmentTime: monthForm.value.monthArr[index].month,
        investmentAmount: monthForm.value.monthArr[index].money,
      };
      createInvest(form).then(res => {
        ElMessage.success(res.msg);
        if (res.code === 200) {
          getDetailInvest({
            projectId: props.projectId,
            orderByColumn: 'investmentTime',
            isAsc: 'asc',
          }).then(res => {
            if (res.code === 200) {
              let data = [];
              monthForm.value.monthArr.forEach((item, i) => {
                if ('projectInvestmentId' in item === false && i !== index) {
                  data.push(item);
                }
              });
              monthForm.value.monthArr = [];
              isMonthSubmit.value = [];
              monthDisabled.value = [];
              res.rows.forEach(item => {
                monthForm.value.monthArr.push({
                  projectInvestmentId: item.projectInvestmentId,
                  month: item.investmentTime,
                  money: item.investmentAmount,
                });
                isMonthSubmit.value.push(true);
                monthDisabled.value.push(true);
              });
              monthForm.value.monthArr = monthForm.value.monthArr.concat(data);
            } else {
              ElMessage.error(res.msg);
            }
          });
        } else {
          ElMessage.error(res.msg);
        }
      });
    }
  });
};

// 监听月度投资 “取消” 按钮
const handleMonthDel = index => {
  monthForm.value.monthArr.splice(index, 1);
  monthNum.value = monthNum.value - 1;
  isMonthSubmit.value.splice(index, 1);
  monthDisabled.value.splice(index, 1);
};

// 监听月度投资 “删除” 按钮
const handleMonthDelData = (id, index) => {
  deleteInvest(id).then(res => {
    if (res.code === 200) {
      isMonthSubmit.value.splice(index, 1);
      monthDisabled.value.splice(index, 1);
      monthForm.value.monthArr.splice(index, 1);
      ElMessage.success(res.msg);
    } else {
      ElMessage.error(res.msg);
    }
  });
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值