嵌套表单效验,动态表单效验,动态增删表单

动态表单效验

效果图

在这里插入图片描述

代码

<template>
  <div class="question">
    <div class="save"><el-button type="primary" size="mini" @click="saveQuestions">保 存</el-button></div>
    <div class="question-item" v-for="(question, qusIndex) in questionList" :key="question.questionId">
      <el-form size="mini" :model="question" :rules="rules" ref="ruleForm" label-width="30px">
        <el-form-item prop="titleName" :label="question.sort + '.'">
          <el-input v-model="question.titleName" placeholder="请输入标题" maxlength="200"></el-input>
        </el-form-item>
        <div class="options" v-for="(option, optIndex) in question.optionList" :key="option.optionId">
          <el-form size="mini" :model="option" :rules="rules" ref="optionForm" :label="option.sort + '.'">
            <el-form-item prop="optionName">
              <el-radio-group v-model="question.optionValue">
                <el-radio :label="option.optionName">
                  <el-input size="mini" v-model="option.optionName" :placeholder="'请输入' + option.optionName" maxlength="50"></el-input>
                  <i class="el-icon-delete" @click="removeOption(question, optIndex)"></i>
                  <i v-if="optIndex + 1 == question.optionList.length" class="el-icon-circle-plus-outline" @click="addOptions(qusIndex, optIndex)"></i>
                </el-radio>
              </el-radio-group>
            </el-form-item>
          </el-form>
        </div>
      </el-form>
      <div class="btn-group">
        <el-button plain icon="el-icon-top" v-if="qusIndex != 0" @click="moveQuestion('top', qusIndex)">上移</el-button>
        <el-button plain icon="el-icon-bottom" v-if="qusIndex != questionList.length - 1" @click="moveQuestion('botoom', qusIndex)">下移</el-button>
        <el-button size="mini" type="primary" plain icon="el-icon-delete" @click="removeQuestion(qusIndex)">删除</el-button>
      </div>
    </div>
    <div class="addbox" @click="addQuestion"><i class="el-icon-plus avatar-uploader-icon"></i></div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      questionList: [
        {
          questionId: 1,
          sort: 1,
          titleName: "标题1",
          optionValue: "",
          optionList: [
            {
              optionId: 1,
              optionName: "选项1",
              sort: 1,
            },
            {
              optionId: 2,
              optionName: "选项2",
              sort: 2,
            },
          ],
        },
        {
          questionId: 2,
          sort: 2,
          titleName: "标题2",
          optionValue: "",
          optionList: [
            {
              optionId: 1,
              optionName: "选项1",
              sort: 1,
            },
            {
              optionId: 2,
              optionName: "选项2",
              sort: 2,
            },
          ],
        },
      ],

      rules: {
        titleName: [{ required: true, message: "请输入标题", trigger: "blur" }],
        optionName: [{ required: true, message: "请输入选项", trigger: "blur" }],
      },
    };
  },
  methods: {
    // 新增选项
    addOptions(qusIndex, optIndex) {
      console.log(qusIndex, optIndex);
      this.questionList[qusIndex].optionList.push({
        optionName: "选项" + (optIndex + 2),
        sort: optIndex + 2,
      });
    },
    // 移除选项
    removeOption(question, optIndex) {
      question.optionList.splice(optIndex, 1);
    },
    // 移除题目
    removeQuestion(qusIndex) {
      this.questionList.splice(qusIndex, 1);
    },
    // 新增题目
    addQuestion() {
      this.questionList.push({
        sort: this.questionList.length + 1,
        titleName: "标题" + (this.questionList.length + 1),
        optionValue: "",
        optionList: [
          {
            optionId: 1,
            optionName: "选项1",
            sort: 1,
          },
          {
            optionId: 2,
            optionName: "选项2",
            sort: 2,
          },
        ],
      });
    },
    // 移动
    moveQuestion(position, itemIndex) {
      if (position == "top") {
        let sort1 = this.questionList[itemIndex - 1].sort;
        this.questionList[itemIndex - 1].sort = this.questionList[itemIndex].sort;
        this.questionList[itemIndex].sort = sort1;
        this.changeSort(); // 排序
      } else {
        let sort1 = this.questionList[itemIndex].sort;
        this.questionList[itemIndex].sort = this.questionList[itemIndex + 1].sort;
        this.questionList[itemIndex + 1].sort = sort1;
        this.changeSort(); // 排序
      }
    },
    // 按序号排序
    changeSort() {
      this.questionList.sort(function (a, b) {
        return a.sort - b.sort;
      });
    },
    // 使用Promise.all效验所有表单
    saveQuestions() {
      let ruleFormArr = this.$refs["ruleForm"];
      let optionFormArr = this.$refs["optionForm"];
      Promise.all([...ruleFormArr, ...optionFormArr].map(this.getFormPromise)).then((res) => {
        const validateResult = res.every((item) => !!item);
        if (validateResult) {
          console.log("表单都校验通过");
        } else {
          console.log("表单未校验通过");
        }
      });
    },
    // 单个表单验证
    getFormPromise(form) {
      return new Promise(function (resolve, reject) {
        form.validate((res) => {
          resolve(res);
        });
      });
    },
  },
};
</script>

<style lang="less" scoped>
.question {
  width: 500px;
  margin: 0 auto;
  background: #fff;
  padding: 30px;

  .question-item {
    padding: 10px;
    border-bottom: 1px solid #cacdd1;
    &:hover {
      background-color: #fafafa;
    }
  }
  .options {
    display: flex;
    align-items: center;
    margin-left: 20px;
    width: 300px;
  }

  .addbox {
    width: 250px;
    height: 50px;
    line-height: 50px;
    margin: 10px;
    border: 1px dashed #8c939d;
    text-align: center;
  }
  .btn-group,
  .save {
    text-align: right;
  }
  ::v-deep {
    .options {
      .el-form-item__content {
        display: flex;
        align-items: center;
        i {
          margin-left: 10px;
        }
      }
      .el-form-item,
      .el-radio,
      .el-radio__label {
        display: flex;
        justify-content: flex-start;
        align-items: center;
      }
    }
  }
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值