Vue动态增添表单并赋予增删上下移动等操作

开发需求:前端设计一个表单,依据题目类型,判断是否需要添加内容,若需添加,则可以动态增删、上下移动调整顺序等

开发难点:需根据实际逻辑(如:第一项内容不可删除、上移等),注意按钮的禁用

开发效果:

image.png image.png image.png image.png

具体实现:

<template>
  <div>
    <!--新增题目-->
    <el-dialog
      title="新增题目"
      :visible.sync="dialogAddNewQuestion"
      customClass="dialogWidth"
      center
    >
      <el-form
        ref="addNewForm"
        :model="addNewForm"
        :rules="addNewQuestionFormRules"
        label-width="80px"
        :label-position="addNewForm.labelPosition"
      >
        <el-form-item label="题目序号" prop="sort">
          <el-input v-model.number="addNewForm.sort"></el-input>
        </el-form-item>
        <el-form-item label="题目名称" prop="name">
          <el-input v-model="addNewForm.name"></el-input>
        </el-form-item>
        <el-form-item label="题目类型" prop="type">
          <el-select v-model="addNewForm.type" placeholder="请选择题目类型">
            <el-option
              v-for="item in addNewForm.option"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            >
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="题目分数" prop="score">
          <el-input v-model.number="addNewForm.score"></el-input>
        </el-form-item>
        <el-form-item label="题目备注" prop="remark">
          <el-input type="textarea" v-model="addNewForm.remark"></el-input>
        </el-form-item>
        <el-divider></el-divider>
        <!--若是单选或多选添加新选项功能-->
        <div v-show="addNewForm.type != '问答' && addNewForm.type != '填空'" v-for="(item, index) in addNewForm.options" :key="index">
          <el-row :gutter="10">
          <el-col :span="4">
            <el-form-item label-width="120px" :label="'选项内容' + (index + 1)" :prop="`options.${index}.sort`" :rules="[{ required: true, message: '请输入选项的序号', trigger: 'blur' }, { type: 'number', message: '序号必须为数字值' }]" style="width: 250px">
              <el-input v-model.number="item.sort" placeholder="请输入选项排序"></el-input>
             </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item  :prop="`options.${index}.name`" :rules="[{ required: true, message: '请输入选项的内容', trigger: 'blur' }]" style="width: 350px">
              <el-input v-model="item.name" placeholder="请输入选项内容"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item  :prop="`options.${index}.score`" :rules="[{ required: true, message: '请输入选项的分数', trigger: 'blur' }, { type: 'number', message: '分数必须为数字值' }]" style="width: 300px">
              <el-input v-model.number="item.score" placeholder="请输入选项分数"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-button
            type="danger"
            :disabled="index == 0"
            @click="deleteItem(item, index)"
            >删除</el-button
          >
          <el-button
            icon="el-icon-top"
            :disabled="index == 0"
            @click="upItem(index)"
            circle
          ></el-button>
          <el-button
            icon="el-icon-bottom"
            :disabled="
              index == addNewForm.options.length - 1
            "
            @click="downItem(index)"
            circle
          ></el-button>
          </el-col>
          </el-row>
          <el-button
            icon="el-icon-plus"
            v-if="
              index + 1 == addNewForm.options.length
            "
            @click="addItem()"
          ></el-button>
        </div>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button
          style="position: absolute; right: 100px; bottom: 10px"
          @click="dialogAddNewQuestion = false"
          >关闭</el-button
        >
        <el-button
          type="primary"
          style="position: absolute; right: 10px; bottom: 10px"
          @click="submitNewQuestion"
          >新增</el-button
        >
      </div>
    </el-dialog>

    
  </div>
</template>
  
<script>
import {
  createQuestion,
} from "@/api/questionnaire";
export default {
  data() {
    return {
      // 弹窗
      dialogAddNewQuestion: false,
      // 新增题目表格
      addNewForm: {
        labelPosition: "left",
        // 上一页问卷的id
        questionnaireId: this.$route.query.questionnaireId, 
        sort: null,
        name: "",
        score: null,
        // 默认
        type: "填空",
        option: [
          { value: "填空", label: "填空" },
          { value: "单选", label: "单选" },
          { value: "多选", label: "多选" },
          { value: "问答", label: "问答" },
        ],
        remark: "",
        // 新增题目的新增选项表格
        options: [
          {
            name: "",
            score: null,
            sort: null,
          }
        ]
      },
      // 新增题目表格校验
      addNewQuestionFormRules: {
        sort: [
          { required: true, message: "请输入题目的序号", trigger: "blur" },
          { type: "number", message: "序号必须为数字值" },
        ],
        name: [
          { required: true, message: "请输入题目的名称", trigger: "blur" },
        ],
        score: [
          { required: true, message: "请输入题目的分数", trigger: "blur" },
          { type: "number", message: "分数必须为数字值" },
        ],
        type: [
          { required: true, message: "请选择题目的类型", trigger: "blur" },
        ]
      },
    };
  },
  methods: {
    // 新增问卷
    addNewQuestion() {
      this.dialogAddNewQuestion = true;
    },
    // 提交新增题目
    submitNewQuestion() {
      this.$refs["addNewForm"].validate((valid) => {
        if (valid) {
          createQuestion(this.addNewForm).then(() => {
            this.dialogAddNewQuestion = false;
            this.fetchQuestionRecord();
            this.$notify({
              title: "成功",
              message: "新增题目成功",
              type: "success",
              duration: 2000,
            });
          });
        }
      });
    },
    // 新增添加选项内容
    addItem() {
      this.addNewForm.options.push({
        name: "",
        score: null,
        sort: null,
      });
    },
    // 新增删除选项内容
    deleteItem(item, index) {
      this.addNewForm.options.splice(index, 1);
      this.$message({
        message: "删除成功哟~",
        type: "success",
      });
    },
    // 新增上移动选项操作
    upItem(index) {
      let arr = this.addNewForm.options;
      arr.splice(index - 1, 1, ...arr.splice(index, 1, arr[index - 1]));
    },
    // 新增下移选项操作
    downItem(index) {
      let arr = this.addNewForm.options;
      arr.splice(index, 1, ...arr.splice(index + 1, 1, arr[index]));
    },
  },
};
</script>
  
  <style>
.dialogWidth {
  width: 85%;
}
</style>
posted @ 2022-12-08 15:52  我在吃大西瓜呢  阅读(147)  评论(0编辑  收藏  举报