效果图
代码
<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;
});
},
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>