由于最近在一个项目中需要实现创建试卷与预览试卷的功能,所以就自己动手写了一个,效果还不错,目前项目已经交付使用,今天就先和大家分享一下创建试卷。
创建试卷
先放一下效果图
首先是试卷的相关设置
考试对象是通过接口返回的数据
<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 " >卡片名称</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 " > <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>
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]