由于最近在一个项目中需要实现创建试卷与预览试卷的功能,所以就自己动手写了一个,效果还不错,目前项目已经交付使用,今天就先和大家分享一下创建试卷。
创建试卷
先放一下效果图
首先是试卷的相关设置
考试对象是通过接口返回的数据
<span class=\"content-label\">选择考试对象</span> <el-form-item prop=\"roleList\"> <el-select v-model=\"form.roleList\" multiple filterable allow-create default-first-option placeholder=\"请选择考试对象\" > <el-option v-for=\"item in roles\" :key=\"item.value\" :label=\"item.label\" :value=\"item.value\" /> </el-select> </el-form-item>
需要定义的data数据
roles: [], //考试对象选择列表(接口返回)
form: {
title: \"\",
roleList: [], // 考试对象
deadline: \"\", // 截止时间
questions: []
},
获取考试对象列表
getRoles() {
crudRoles.getAll().then(res => {
res.map((obj) => {
const role = {
value: obj.id,
label: obj.name
}
this.roles.push(role)
})
})
},
截至时间使用的是element时间日期选择器
<span class=\"content-label\">截止时间</span> <el-form-item prop=\"deadline\"> <el-date-picker v-model=\"form.deadline\" type=\"datetime\" placeholder=\"选择日期时间\" value-format=\"yyyy-MM-dd HH:mm:ss\" /> </el-form-item>
然后是添加试题
试题类型的相关数据也是通过接口返回的
questionType: [],
获取试题类型
getQuestionType() {
crudExam.getQuestionType().then(res => {
this.questionType = res
})
},
<div class=\"question-type\">
<el-button
v-for=\"item in questionType\"
:key=\"item.typeId\"
style=\"border-color: #2A82E4; color: #2A82E4\"
@click=\"addQuestion(item.typeId)\"
>
<svg-icon :icon-class=\"item.icon\" />
{{ item.typeName }}
</el-button>
</div>
addQuestion(typeId) {
const question = {
id: this.questionId,
quesTypeId: typeId,
title: \"\",
score: 0,
answer: [],
content: []
}
this.form.questions.push(question)
this.questionId++
},
对于添加的试题模板则是单独创建了一个question.vue
这里由于其他布局方法一直不太理想,所以采用了栅格布局,效果还算可以
<template>
<el-card class=\"box-card\">
<div slot=\"header\" class=\"clearfix\" style=\"margin-bottom: -10px\">
<span
class=\"type-name\"
v-text=\"question.quesTypeId < 3 ?
question.quesTypeId === 1 ?
\"单选题\" : \"多选题\"
: question.quesTypeId < 5 ?
question.quesTypeId === 3 ?
\"填空题\" : \"简答题\"
: \"判断题\"\"
>卡片名称</span>
<el-input v-model=\"question.score\" style=\"width: 55px\" />
<span>分</span>
<el-button style=\"float: right; border: none; font-size: 20px\" icon=\"el-icon-close\" @click=\"removeQuestion\" />
</div>
<el-form-item>
<el-input
v-model=\"question.title\"
type=\"textarea\"
placeholder=\"请输入题干内容...\"
/>
</el-form-item>
<!--单选、多选-->
<el-form-item v-if=\"question.quesTypeId === 1 || question.quesTypeId === 2\" style=\"margin-bottom: 0px\">
<el-checkbox-group
v-model=\"question.answer\"
:min=\"0\"
:max=\"question.quesTypeId === 1 ? 1 : 4\"
>
<el-row
v-for=\"(item, index) in [\"A\", \"B\", \"C\", \"D\"]\"
:key=\"item\"
>
<el-col :span=\"1\">
<el-checkbox-button
v-model=\"question.answer\"
:label=\"question.content[index]\"
border
>
{{ item }}
</el-checkbox-button>
</el-col>
<el-col :span=\"23\">
<el-input
v-model=\"question.content[index]\"
placeholder=\"请输入选项...\"
@input=\"contentChange(question)\"
/>
</el-col>
</el-row>
</el-checkbox-group>
</el-form-item>
<!--简答、填空-->
<el-form-item v-if=\"question.quesTypeId === 3 || question.quesTypeId === 4\" style=\"margin-bottom: 0px\">
<el-input
v-model=\"question.answer[0]\"
type=\"textarea\"
placeholder=\"请输入参考答案\"
/>
</el-form-item>
<!--判断-->
<el-form-item v-if=\"question.quesTypeId === 5\" style=\"margin-bottom: 0px\">
<el-checkbox-group
v-model=\"question.answer\"
:min=\"0\"
:max=\"1\"
>
<el-checkbox v-model=\"question.answer\" label=\"对\" border />
<el-checkbox v-model=\"question.answer\" label=\"错\" border />
</el-checkbox-group>
</el-form-item>
</el-card>
</template>
<script>
export default {
props: {
question: {
type: Object,
required: true
}
},
methods: {
removeQuestion() {
this.$emit(\"removeQuestion\", this.question.id)
},
contentChange(question) {
question.answer.splice(0)
}
}
}
</script>
<style scoped>
.type-name {
color: #505050;
margin-right: 20px;
}
</style>
然后是删除试题
<question v-for=\"item in form.questions\" :key=\"item.id\" :question=\"item\" class=\"question-content\" @removeQuestion=\"removeQuestion\" />
removeQuestion(id) {
for (let i = 0; i < this.form.questions.length; i++) {
if (this.form.questions[i].id === id) {
this.form.questions.splice(i, 1)
}
}
},
最后提交方法中进行数据验证
这个在之前一篇博客中简单介绍过,感兴趣的朋友可以自行前去了解
Vue关于Element对表单的校验
最最后把create.vue的源码分享给大家方便大家进行参考,如有更好的建议也请大家不吝赐教
<template>
<div class=\"app-container\">
<div>
<el-form
ref=\"form\"
:model=\"form\"
:rules=\"rules\"
class=\"form\"
>
<h4 class=\"card-label\">设置任务</h4>
<div class=\"card-panel\">
<div class=\"settings-wrap\" style=\"width: 18%\">
<span class=\"content-label\">选择考试对象</span>
<el-form-item prop=\"roleList\">
<el-select
v-model=\"form.roleList\"
multiple
filterable
allow-create
default-first-option
placeholder=\"请选择考试对象\"
>
<el-option
v-for=\"item in roles\"
:key=\"item.value\"
:label=\"item.label\"
:value=\"item.value\"
/>
</el-select>
</el-form-item>
</div>
<div class=\"settings-wrap\" style=\"width: 18%\">
<span class=\"content-label\">截止时间</span>
<el-form-item prop=\"deadline\">
<el-date-picker
v-model=\"form.deadline\"
type=\"datetime\"
placeholder=\"选择日期时间\"
value-format=\"yyyy-MM-dd HH:mm:ss\"
/>
</el-form-item>
</div>
</div>
<h4 class=\"card-label\">试卷标题</h4>
<div class=\"card-panel\">
<div class=\"settings-wrap\" style=\"width: 40%\">
<el-form-item prop=\"title\">
<el-input
v-model=\"form.title\"
type=\"text\"
placeholder=\"请输入试卷标题(1-20个字)\"
maxlength=\"20\"
show-word-limit
/>
</el-form-item>
</div>
</div>
<question
v-for=\"item in form.questions\"
:key=\"item.id\"
:question=\"item\"
class=\"question-content\"
@removeQuestion=\"removeQuestion\"
/>
<div class=\"question-type\">
<el-button
v-for=\"item in questionType\"
:key=\"item.typeId\"
style=\"border-color: #2A82E4; color: #2A82E4\"
@click=\"addQuestion(item.typeId)\"
>
<svg-icon :icon-class=\"item.icon\" />
{{ item.typeName }}
</el-button>
</div>
<el-button
type=\"primary\"
class=\"submit\"
:loading=\"loading\"
style=\"margin-top: 20px\"
@click=\"submit\"
>
提交试卷
</el-button>
</el-form>
</div>
</div>
</template>
<script>
import crudRoles from \"@/api/system/role\"
import crudExam from \"@/api/exam/exam\"
import question from \"@/views/exam/module/question\"
import crudList from \"@/api/exam/list\"
export default {
name: \"Create\",
components: {
question
},
data() {
return {
roles: [],
dialogVisible: false,
loading: false,
questionId: 0,
form: {
title: \"\",
roleList: [], // 考试对象
deadline: \"\", // 截止时间
questions: []
},
questionType: [],
rules: {
roleList: [{
required: true,
message: \"请选择考试对象\",
trigger: \"blur\"
}],
deadline: [{
required: true,
message: \"请选择截止时间\",
trigger: \"blur\"
}],
title: [{
required: true,
message: \"请输入试卷标题(1-20个字)\",
trigger: \"blur\"
}]
}
}
},
created() {
this.getRoles()
this.getQuestionType()
},
methods: {
getRoles() {
crudRoles.getAll().then(res => {
res.map((obj) => {
const role = {
value: obj.id,
label: obj.name
}
this.roles.push(role)
})
})
},
getQuestionType() {
crudExam.getQuestionType().then(res => {
this.questionType = res
})
},
addQuestion(typeId) {
const question = {
id: this.questionId,
quesTypeId: typeId,
title: \"\",
score: 0,
answer: [],
content: []
}
this.form.questions.push(question)
this.questionId++
},
removeQuestion(id) {
for (let i = 0; i < this.form.questions.length; i++) {
if (this.form.questions[i].id === id) {
this.form.questions.splice(i, 1)
}
}
},
submit() {
if (this.form.questions.length === 0) {
this.$notify({
title: \"警告\",
message: \"请添加试题\",
type: \"warning\"
})
return
}
const form = JSON.parse(JSON.stringify(this.form))
let isSubmit = true
let message = \"\"
this.loading = true
this.$refs[\"form\"].validate(res => {
if (!res) {
this.loading = false
return
}
for (let i = 0; i < form.questions.length; i++) {
const question = form.questions[i]
if (question.title === \"\") {
isSubmit = false
message = \"请设置题目题干\"
break
}
if ((question.quesTypeId === 1 || question.quesTypeId === 2) && question.content.length === 0) {
isSubmit = false
message = \"请设置选择题题答案\"
break
}
if ((question.quesTypeId === 1 || question.quesTypeId === 2 || question.quesTypeId === 5) && question.answer.length === 0) {
isSubmit = false
message = \"请设置客观题选项\"
break
}
}
if (!isSubmit) {
this.$notify({
title: \"警告\",
message: message,
type: \"warning\"
})
this.loading = false
return
}
form.questions.forEach(function(question) {
question.answer = JSON.stringify(question.answer)
question.content = JSON.stringify(question.content)
})
crudExam.add(form).then((res) => {
this.loading = false
const params = {
type: 2,
typeId: res,
url: this.$frontUrl + \"/answerOnline\"
}
crudList.remind(params).then(() => {
this.$message.success(\"提醒成功~\")
})
this.$router.push(\"/exam/index\")
}).catch(() => {
this.loading = false
})
})
}
}
}
</script>
<style rel=\"stylesheet/scss\" lang=\"scss\" scoped>
.card-label {
margin: 30px 0 15px;
}
.card-panel {
display: flex;
flex-direction: row;
padding: 17px 15px 0;
color: #666;
box-shadow: 0 0 3px 1px #e7e7e7;
border-color: #e7e7e7;
.settings-wrap {
margin-right: 4%;
}
}
.content-label {
display: block;
padding-bottom: 5px;
}
.question-type {
margin-top: 20px;
}
.question-content {
margin-top: 20px;
color: #666;
box-shadow: 0 0 4px 2px rgba(0, 0, 0, .05);
border-color: rgba(0, 0, 0, .05);
}
</style>
到此这篇关于基于vue与element实现创建试卷相关功能的文章就介绍到这了,更多相关vue与element创建试卷功能内容请搜索快网idc以前的文章或继续浏览下面的相关文章希望大家以后多多支持快网idc!
原文链接:https://blog.csdn.net/qq_43620423/article/details/110731009
相关文章
猜你喜欢
- 64M VPS建站:是否适合初学者操作和管理? 2025-06-10
- ASP.NET自助建站系统中的用户注册和登录功能定制方法 2025-06-10
- ASP.NET自助建站系统的域名绑定与解析教程 2025-06-10
- 个人服务器网站搭建:如何选择合适的服务器提供商? 2025-06-10
- ASP.NET自助建站系统中如何实现多语言支持? 2025-06-10





