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

动态表单效验

效果图

在这里插入图片描述

代码

<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>

猜你喜欢

转载自blog.csdn.net/qq_37831545/article/details/129039232