持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第11天,点击查看活动详情
开发项目实战篇,试题库出题,将试题根据题型需要的字段封装成组件,传入不同的题型,展示不同的题型,客观题的共通点就是-都有选项,选项可以增、删、改,最多20个,最少2个。话不多说,直接上代码吧
客观题-单选题、多选题、判断题
编辑器用的tinymce
题目由题干,选项,答案,题目解析,添加选项按钮,删除选项按钮,移动选项按钮组成
实现一个公共的客观题的组件,按需引入,组件如下:
<div class="selectModule">
<div class="moduleStem">
<p>题目:</p>
<tinymce :placeholder="'输入题目描述'" ref="editor" v-model="data.context" :size="{ height: textHeight }"
:disabled="disabled" :maxlength="500"></tinymce>
</div>
<ul :class="['optionList',disabled ? 'isDisabled' : '']">
<li
:class="['optionItem',data.isDisabled ? 'isDisabled' : '']"
v-for="(item,index) in data.options"
:key="item.value"
>
<!--单选题-->
<template v-if="data.type == 1">
<el-radio
v-model="data.answeNum"
:label="item.number"
>{{item.number}}
</el-radio>
<tinymce placeholder="输入选项内容描述" ref="editor" v-model="item.content" :size="{ height: optionHeight }"
:disabled="disabled" :maxlength="500"></tinymce>
</template>
<!--多选题-->
<template v-if="data.type == 2">
<el-checkbox
v-model="data.answeNum"
:label="item.number"
>{{item.number}}
</el-checkbox>
<tinymce placeholder="输入选项内容描述 " ref="editor" v-model="item.content" :size="{ height: optionHeight }"
:disabled="disabled" :maxlength="500"></tinymce>
</template>
<!--判断题-->
<template v-if="data.type == 3">
<el-radio
v-model="data.answeNum"
:label="item.number"
>{{item.number | optionsName}}
</el-radio>
</template>
<div v-if="data.type !== 3">
<div class="deleteItem hoverClass" title="上移动" @click="topOption(index)" v-if="index !== 0"><i class="el-icon-top"></i></div>
<div class="deleteItem hoverClass" title="下移动" @click="bottomOption(index)" v-if="index !== data.options.length - 1"><i class="el-icon-bottom"></i></div>
<div class="deleteItem hoverClass" title="删除" @click="deleteOptionsFn(index)" v-if="data.options.length > 2"><i class="el-icon-close"></i></div>
</div>
</li>
<div v-if="!disabled && data.type !== 3" class="addOptions hoverClass" @click="addOptionsFn">
<i class="el-icon el-icon-plus"></i> 添加选项
</div>
</ul>
<div class="moduleStem">
<p>解析:</p>
<tinymce :placeholder="'输入题目解析'" ref="editor" v-model="data.parse" :size="{ height: textHeight }"
:disabled="disabled" :maxlength="2000"></tinymce>
</div>
</div>
增删改查的js代码
// 增加选项
addOptionsFn() {
let length = this.data.options.length;
if (length == 20) {
this.$message({
type: "error",
message: "至多有二十项!"
});
return;
}
let optionData = {
content: "",
number: this.sortOptionsFn(length),
value: length
};
this.data.options.push(optionData);
},
// 删除选项
deleteOptionsFn(index) {
let remainData = this.data.options;
if (remainData.length === 2) {
this.$message({
type: "error",
message: "至少有两项!"
});
return;
}
if (this.data.answeNum.constructor == Array){
if (this.data.answeNum.indexOf(index) > -1){
this.data.answeNum.splice(this.data.answeNum.indexOf(index), 1);
}
} else {
if (this.data.answeNum === index){
this.data.answeNum = 0;
}
}
remainData.splice(index, 1); // 删除选项
remainData.forEach((element, index) => {
element.number = this.sortOptionsFn(index);
element.value = index;
});
},
// 上移动
topOption(index) {
let remainData = this.data.options;
remainData[index] = remainData.splice(index - 1, 1, remainData[index])[0];
remainData.forEach((element, index) => {
element.number = this.sortOptionsFn(index);
element.value = index;
});
},
// 下移动
bottomOption(index) {
let remainData = this.data.options;
remainData[index] = remainData.splice(index + 1, 1, remainData[index])[0];
remainData.forEach((element, index) => {
element.number = this.sortOptionsFn(index);
element.value = index;
});
},
// 删除之后选项排序
sortOptionsFn(index) {
let options = new Map([
[0, "A"], [1, "B"], [2, "C"], [3, "D"], [4, "E"],
[5, "F"], [6, "G"], [7, "H"], [8, "I"], [9, "J"],
[10, "K"], [11, "L"], [12, "M"], [13, "N"], [14, "O"],
[15, "P"], [16, "Q"], [17, "R"], [18, "S"], [19, "T"]
]);
return options.get(index);
}