话不多,先上一段视频,看看是不是你们需要的效果
elementui动态生成表单校验
附上代码
html
<template>
<div class="home">
<div class="home-box">
<!-- <menuHtml></menuHtml> -->
<div class="home-div">
<div style="margin-top: 20px;display:flex;justify-content: space-between;">
<div>
<span class="blueBlock"> </span>
<span class="title">问卷编辑</span>
</div>
<div>
<span style="color:#F56C6C;">问卷编辑完成,千万不要忘记点击保存哦<i class="el-icon-thumb"
style="transform: rotate(90deg);"></i></span>
<el-button type="primary" plain size="mini" icon="el-icon-s-claim"
@click="save('form')">保存</el-button>
</div>
</div>
<el-form abel-position='top' :model="form" ref="form">
<div class="content">
<div class="content-top">
<el-form-item prop="title" :rules="{required: true, message: ' ', trigger: 'blur' }">
<el-input size="small" v-model="form.title" placeholder="请输入问卷标题">
<el-button slot="append" @click="addQuestion()" icon="el-icon-circle-plus-outline">
添加问题
</el-button>
</el-input>
</el-form-item>
</div>
<div class="content-box">
<div class="content-center" v-for="(question,index) in form.questionList">
<el-form-item>
<el-radio v-model="question.type" :label="1">单选</el-radio>
<el-radio v-model="question.type" :label="2">多选</el-radio>
<el-radio v-model="question.type" :label="3">开放式问题</el-radio>
</el-form-item>
<el-form-item class="question" :prop="'questionList.'+index+'.name'"
:rules="{required: true, message: '', trigger: 'blur' }">
<el-input placeholder="请输入问题" size="small" v-model="question.name">
<template slot="prepend">Q{{index+1}}.</template>
</el-input>
<div @click="delQuestion(index)">
<i class="el-icon-delete-solid"></i>
<span>删除</span>
</div>
</el-form-item>
<el-form-item v-if="question.type==3" :prop="'questionList.'+index+'.answer2'"
:rules="{required: true, message: ' ', trigger: 'blur' }">
<el-input type="textarea" :rows="4" placeholder="请输入答案" v-model="question.answer2"
resize="none"></el-input>
</el-form-item>
<el-form-item v-else>
<div class="answer" v-for="(answer,index1) in question.answerList">
<el-form-item :prop="'questionList.'+index+'.answerList.'+index1+'.name'" :rules="{required: true, message: ' ', trigger: 'blur' }">
<el-input size="small" placeholder="请输入答案" v-model="answer.name">
<template slot="prepend">{{chars[index1]}}.</template>
</el-input>
</el-form-item>
<div class="answer-right">
<el-button @click="delAnswer(index,index1,question)" size="mini"
icon="el-icon-minus" circle type="danger" plain></el-button>
<el-button v-if="question.answerList.length==index1+1"
@click="addAnswer(index,index1)" size="mini" icon="el-icon-plus" circle
type="primary" plain></el-button>
</div>
</div>
</el-form-item>
<el-form-item label="正确答案" v-if="question.type==1"
:prop="'questionList.'+index+'.answer'" :rules="{required: true, message: ' ', trigger: 'blur' }">
<el-select size="mini" v-model="question.answer" placeholder="请选择答案">
<el-option v-for="(item,index2) in question.answerList" :key="index2"
:label="chars[index2]" :value="index2">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="正确答案" v-if="question.type==2"
:prop="'questionList.'+index+'.answer1'" :rules="{required: true, message: ' ', trigger: 'blur' }">
<el-select size="mini" multiple v-model="question.answer1" placeholder="请选择答案">
<el-option v-for="(item,index2) in question.answerList" :key="index2"
:label="chars[index2]" :value="index2">
</el-option>
</el-select>
</el-form-item>
</div>
</div>
</div>
</el-form>
</div>
</div>
</div>
</template>
<script>
// import menuHtml from '../../../view/leaf-content/menuHtml.vue'
export default {
name: 'addWjByTeacher',
components: {
// menuHtml,
},
props: [],
data() {
return {
chars: ['A', 'B', 'C', 'D'],
form: {
title: '',
// questionList: [],
questionList: [{
type: 1, //1.单选,2:多选,3开放式问题
questionTitle: '',
answerList: [{}],
answer: '', //单选答案
answer1: [], //多选答案
answer2: '', //开放式问题答案
}, {
type: 2, //1.单选,2:多选,3开放式问题
questionTitle: '',
answerList: [{}],
answer: '',
answer1: [],
answer2: '',
}, {
type: 3, //1.单选,2:多选,3开放式问题
questionTitle: '',
answerList: [{}],
answer: '',
answer1: [],
answer2: '',
}],
}
}
},
methods: {
addQuestion() { //添加问题
this.form.questionList.push({
type: 1, //1.单选,2:多选,3开放式问题
questionTitle: '',
answerList: [{}],
answer: '',
});
},
delQuestion(index) { //删除问题
this.form.questionList.splice(index, 1);
},
addAnswer(questionIndex, answerIndex) { //添加答案
console.log(answerIndex);
if (answerIndex < 3) {
this.form.questionList[questionIndex].answerList.push({});
}
},
delAnswer(questionIndex, answerIndex, question) { //删除答案
if (answerIndex >= 1) {
this.form.questionList[questionIndex].answerList.splice(answerIndex, 1);
}
//判断单选还是多选,要一同清空掉答案
if (question.type == 1) {
// this.form.questionList[questionIndex].answerList
question.answer = "";
} else if (question.type == 2) {
question.answer1 = "";
}
},
save(formName) { //保存问题
this.$refs[formName].validate((valid) => {
if (valid) {
alert('submit!');
} else {
console.log('error submit!!');
return false;
}
});
},
},
mounted() {
},
destroyed() {
},
created() {
}
}
</script>
<style scoped>
@import '../../../../assets/css/screenBase.css';
.home {
margin-top: 100px;
}
.home-box {
margin: 0 auto;
display: flex;
align-items: flex-start;
width: 1000px;
justify-content: center
}
.home-div {
width: 1000px;
height: 650px;
background-color: #fff;
border-radius: 10px;
/* padding-top: 20px; */
padding-right: 40px;
padding-left: 40px;
/* padding-bottom: 20px; */
}
.blueBlock {
height: 8px;
width: 2px;
background-color: #226cd3;
margin-right: 10px;
}
.title {
font-weight: 600;
font-size: 24px;
}
.content {
display: flex;
flex-direction: column;
align-items: flex-start;
width: 900px;
}
.el-form-item {
margin-bottom: 0px;
}
.content-top {
margin-top: 20px;
display: flex;
}
.content-top /deep/ input {
width: 800px;
}
.content-center {
width: 880px;
background-color: #e9f5f136;
border-radius: 10px;
margin-top: 5px;
padding: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
}
.content-box {
/* margin-top: 20px; */
padding: 5px;
height: 500px;
overflow: hidden;
overflow-y: auto;
}
/deep/.el-form--label-top .el-form-item__label {
padding: 0px;
}
.btn {
margin-top: 40px;
text-align: center;
}
.question {}
.question /deep/.el-form-item__content {
display: flex;
align-items: flex-start;
justify-content: flex-start;
}
/* .answer /deep/.el-form-item__content {
display: flex;
align-items: flex-start;
justify-content: flex-start;
width: 750px;
} */
.question /deep/ input {
width: 550px;
}
.question div {
width: 100px;
text-align: center;
}
.question i {
color: #F56C6C;
margin-right: 5px;
}
.answer /deep/ .el-input-group--prepend {
width: 500px;
}
.answer /deep/ .el-input__inner {
width: 500px;
}
.answer-right {
width: 100px;
display: flex;
align-items: flex-start;
/* text-align: center; */
}
.answer-right span {
width: 25px;
height: 25px;
line-height: 25px;
text-align: center;
display: inline-block;
background: #FFFFFF;
border-radius: 8px;
border: 1px solid #CCD3E7;
}
.answer-right i {
color: #000;
font-weight: 600;
}
.answer {
display: flex;
align-items: center;
}
</style>
最主要的地方,因为我是双层的循环遍历,先看第一层的注意地方
最最最最最最最主要的地方,这是第二层的地方