天天看点

在线考试例子(vant+vue)

1.zxks.vue(考试列表)

<template>
  <div class="zxksClass">
    <!-- 导航栏 -->
    <comnavBar :Title="Title" :backType="'1'" @onClickLeft="onClickLeft"></comnavBar>
    <!-- 标签页 -->
    <div class="zxks_title">
      <div :class="currentActive==='dk'?'zxks_title_ok':'zxks_title_no'" @click="switchFun('dk')">待考</div>
      <div :class="currentActive==='yk'?'zxks_title_ok':'zxks_title_no'" @click="switchFun('yk')">已考</div>
    </div>
    <!-- 考试列表 -->
    <div class="zxks_scroll">
      <div class="zxks_div" v-if="currentActive==='dk'">
        <div
          class="zxks_list"
          v-for="(item,index) in examObj.dkList"
          :key="index"
          @click="ksxxFun(item)"
        >
          <div class="zxks_list_one">
            <div>{{item.title}}</div>
            <div>
              <span
                :class="item.state==='0'?'zxks_list0':(item.state==='1'?'zxks_list1':'zxks_list2')"
                v-text="item.state==='0'?'未开始':(item.state==='1'?'进行中':'已结束')"
              ></span>
            </div>
          </div>
          <div class="zxks_list_two">
            <span>
              {{item.dateStart}}
              <a style="margin-left:1vw">{{item.timeStart}}</a>
              ~
              <a style="margin-left:1vw">{{item.dateEnd}}</a>
              <a style="margin-left:1vw">{{item.timeEnd}}</a>
            </span>
          </div>
          <div class="zxks_list_three">
            <span>
              应考{{item.yk}}人/已考
              <a style="color:red">{{item.yjk}}</a>人
            </span>
          </div>
        </div>
      </div>
      <!-- 已考列表 -->
      <div class="zxks_div" v-if="currentActive==='yk'">
        <div
          class="zxks_list"
          v-for="(item,index) in examObj.ykList"
          :key="index"
          @click="ksxxFun(item)"
        >
          <div class="zxks_list_one">
            <div>{{item.title}}</div>
            <div>
              <span
                :class="item.state==='0'?'zxks_list0':(item.state==='1'?'zxks_list1':'zxks_list2')"
                v-text="item.state==='0'?'未开始':(item.state==='1'?'进行中':'已结束')"
              ></span>
            </div>
          </div>
          <div class="zxks_list_two">
            <span>{{item.dateStart}}{{item.timeStart}}~{{item.dateEnd}}{{item.timeEnd}}</span>
          </div>
          <div class="zxks_list_three">
            <span>
              应考{{item.yk}}人/已考
              <a style="color:red">{{item.yjk}}</a>人
            </span>
          </div>
        </div>
      </div>
    </div>

    <!-- 弹出层(考试信息) -->
    <van-popup v-model="showKS" :style="{ height: '90%',width:'95%' }">
      <zxksKsxx :currentInfo="currentInfo" @closeFun="closeFun"></zxksKsxx>
    </van-popup>
  </div>
</template>
 
<script>
// 导航栏
import comnavBar from '@/components/com_navBar'
// 考试信息的弹框
import zxksKsxx from '@/modules/zxks_ksxx'
export default {
  components: { comnavBar, zxksKsxx },
  data() {
    return {
      // 导航标题
      Title: '在线考试',
      // 当前选中的标签页 (默认:代考)
      currentActive: 'dk',
      // 考试数据
      examObj: {},
      // 点击展示正常考试的信息
      showKS: false,
      // 传给子组件的考当前试信息
      currentInfo: {}
    }
  },
  watch: {},
  created() {
    // 获取考试列表
    this.getData()
  },
  methods: {
    // 返回
    onClickLeft() {
      this.$router.push({ name: 'home' })
    },
    // 点击考试信息的遮罩层
    closeFun() {
      this.showKS = false
    },
    // 返回(考试信息)
    backFun() {
      this.showKS = false
    },
    // 查看考试信息
    ksxxFun(val) {
      this.showKS = true
      this.currentInfo = val
    },
    // 切换标签页
    switchFun(val) {
      this.currentActive = val
    },
    // 获取考试列表
    getData() {
      this.examObj.dkList = [
        {
          title: '000', //考试名称
          state: '0', //考试的状态   0:未开始   1:进行中   2:已结束
          dateStart: '2020-06-30', //开始日期
          dateEnd: '2020-06-31', //截止日期
          timeStart: '14:00', //开始时间点
          timeEnd: '15:30', //截止时间点
          kssm: '考试说明', //考试说明
          yk: 50, //应考人数
          yjk: 20, //已考人数
          mf: 100, //满分
          jgf: 60, //及格分
          zts: 20, //总题数
          kssc: 120 //考试时长
        },
        {
          title: '111',
          state: '1',
          dateStart: '2020-06-30',
          dateEnd: '2020-06-31',
          timeStart: '14:00',
          timeEnd: '15:30',
          yk: 50,
          yjk: 20,
          kssm: '考试说明',
          mf: 100, //满分
          jgf: 60, //及格分
          zts: 20, //总题数
          kssc: 120 //考试时长
        },
        {
          title: '222',
          state: '2',
          dateStart: '2020-06-30',
          dateEnd: '2020-06-31',
          timeStart: '14:00',
          timeEnd: '15:30',
          yk: 50,
          yjk: 20,
          kssm: '考试说明',
          mf: 100, //满分
          jgf: 60, //及格分
          zts: 20, //总题数
          kssc: 120 //考试时长
        }
      ]
      this.examObj.ykList = [
        {
          title: '2020年知识竞赛2020年知识竞赛',
          state: '1',
          dateStart: '2020-06-30',
          dateEnd: '2020-06-31',
          timeStart: '14:00',
          timeEnd: '15:30',
          yk: 50,
          yjk: 20,
          kssm: '考试说明',
          mf: 100, //满分
          jgf: 60, //及格分
          zts: 20, //总题数
          kssc: 120 //考试时长
        },
        {
          title: '2020年知识竞赛2020年知识竞赛',
          dateStart: '2020-06-30',
          dateEnd: '2020-06-31',
          timeStart: '14:00',
          timeEnd: '15:30',
          yk: 50,
          yjk: 20,
          kssm: '考试说明',
          mf: 100, //满分
          jgf: 60, //及格分
          zts: 20, //总题数
          kssc: 120 //考试时长
        }
      ]
    }
  }
}
</script>
 
<style scoped>
.zxks_scroll {
  height: 83vh;
  overflow-y: scroll;
}

.zxksClass {
  width: 100%;
  height: 100vh;
  background: #f3f4f6;
  /* padding-top: 15vw; */
  overflow-y: hidden;
}
.zxksClass /deep/ .van-popup {
  border-radius: 2vw;
}
.zxks_title {
  height: 10vw;
  line-height: 10vw;
  display: flex;
  padding-top: 15vw;
}
.zxks_title > div {
  width: 35vw;
  margin-left: 10vw;
  box-shadow: 0 0 1vw gainsboro;
}
.zxks_title_ok {
  background: #eb3132;
  color: #ffffff;
}
.zxks_title_no {
  background: #ffffff;
}
.zxks_div {
  background: #ffffff;
}
.zxks_list {
  width: 95vw;
  margin-left: 2.5vw;
  border-bottom: 1px solid #efefef;
  margin-top: 4vw;
}
.zxks_list_one {
  display: flex;
}
.zxks_list_one > div:nth-child(1) {
  width: 75vw;
  font-weight: 700;
  padding-top: 3vw;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: pre;
  text-align: left;
  padding-left: 2vw;
}
.zxks_list_one > div:nth-child(2) {
  width: 25vw;
  padding-top: 3vw;
}
.zxks_list_two {
  color: #848484;
  text-align: left;
  padding: 1vw 0;
  margin-top: 1vw;
  font-size: 3.5vw;
  padding-left: 2vw;
}
.zxks_list_three {
  color: #848484;
  text-align: left;
  margin-top: 1vw;
  font-size: 3.5vw;
  padding-bottom: 2vw;
  padding-left: 2vw;
}
.zxks_list0 {
  border: 1px solid #fbc235;
  color: #fbc235;
  padding: 0.5vw 1vw;
  font-size: 3vw;
  border-radius: 1vw;
}
.zxks_list1 {
  border: 1px solid #eb3637;
  color: #eb3637;

  padding: 0.5vw 1vw;
  font-size: 3vw;
  border-radius: 1vw;
}
.zxks_list2 {
  border: 1px solid #cfcfcf;
  padding: 0.5vw 1vw;
  color: #cfcfcf;
  font-size: 3vw;
  border-radius: 1vw;
}
</style>
           

2.zxks_dt.vue(答题)

<template>
  <div class="zxks_dt">
    <!-- 导航栏 -->
    <comnavBar :Title="Title" :backType="'1'" @onClickLeft="onClickLeft"></comnavBar>
    <!-- 答题的内容 -->
    <div class="zxks_dt_content">
      <div class="comRadio_top">
        <div>
          <span v-if="currentTest.type==='1'">单选题</span>
          <span v-if="currentTest.type==='2'">多选题</span>
          <span v-if="currentTest.type==='3'">填空题</span>
          <span v-if="currentTest.type==='4'">判断题</span>
          <span v-if="currentTest.type==='5'">简答题</span>
        </div>
        <div>
          <span style="color:#EB3837">剩余{{Time}}</span>
          <span style="margin:0 2vw;color:#CCCCCC">|</span>
          <span style="color:#EB3837">{{currentIndex+1}}</span>
          <span style="margin:0 1vw">/</span>
          {{$store.state.zxksList.length}}
        </div>
        <div>
          <img
            @click="testIndexListFun()"
            style="width:4vw"
            src="./../../assets/images/dsj.png"
            alt
          >
        </div>
      </div>
      <div>
        <!-- 单选题 -->
        <comRadio
          v-if="currentTest.type==='1'"
          :obj="currentTest.type==='1'?currentTest:''"
          :type="'0'"
        ></comRadio>
        <!-- 多选题 -->
        <comCheckbox
          :type="'0'"
          v-if="currentTest.type==='2'"
          :obj="currentTest.type==='2'?currentTest:''"
        ></comCheckbox>
        <!-- 填空题 -->
        <comBlank
          :type="'0'"
          v-if="currentTest.type==='3'"
          :obj="currentTest.type==='3'?currentTest:''"
        ></comBlank>
        <!-- 判断题 -->
        <comJudge
          :type="'0'"
          v-if="currentTest.type==='4'"
          :obj="currentTest.type==='4'?currentTest:''"
        ></comJudge>
        <!-- 简答题 -->
        <comshortAnswer
          :type="'0'"
          v-if="currentTest.type==='5'"
          :obj="currentTest.type==='5'?currentTest:''"
        ></comshortAnswer>
      </div>
      <div class="comRadio_tip">
        <div>
          <img @click="cktsFun()" src="./../../assets/icons/[email protected]" alt>
        </div>
        <div @click="cktsFun()">查看提示</div>
      </div>
      <div class="zxks_dt_btn">
        <div>
          <van-button type="danger" plain @click="getCurrentTest('-1')" v-if="currentIndex!==0">上一题</van-button>
        </div>
        <div>
          <van-button
            type="danger"
            v-if="currentIndex===$store.state.zxksList.length-1"
            @click="submitFun()"
          >提交</van-button>
          <van-button type="danger" plain v-else @click="getCurrentTest('1')">下一题</van-button>
        </div>
      </div>
    </div>
    <!-- 弹出层(查看提示) -->
    <van-popup v-model="showTip" position="bottom" :style="{ height: '50%',width:'100%' }">
      <comZxksTip @cancelMask="cancelMask" :tip="currentTest.tip" :title="'提示'" :type="'ts'"></comZxksTip>
    </van-popup>

    <!-- 弹出层(考试结束) -->
    <van-popup
      v-model="showEndTip"
      :close-on-click-overlay="false"
      :style="{ height: '35%',width:'70%' }"
    >
      <comKnow @cancelTestTip="cancelTestTip" :tip="'考试时间已到,将强制提交!!'"></comKnow>
    </van-popup>

    <!-- 弹出层(提交) -->
    <van-popup
      v-model="showIsSubmit"
      :close-on-click-overlay="false"
      :style="{ height: '35%',width:'70%' }"
    >
      <comOkCancel
        :tip="tipWord"
        @cancelTestSubmit="cancelTestSubmit"
        :tipLeft="tipLeft"
        :tipRight="tipRight"
      ></comOkCancel>
    </van-popup>

    <!-- 弹出层(选择试题) -->
    <van-popup v-model="showXZST" :style="{ height: '70%',width:'80%' }">
      <div class="xzstDiv">
        <div class="xzstTitle">选择试题</div>
        <div class="xzstContent">
          <div
            :class="(currentIndex+1)===item?'xzstContent_btn_ok':'xzstContent_btn_no'"
            v-for="item in $store.state.zxksList.length"
            :key="item"
            @click="updateTestIndexFun(item)"
          >{{item}}</div>
        </div>
      </div>
    </van-popup>

    <!-- 弹出层(试题答完的情况反馈) -->
    <van-popup v-model="showSTQKFK" position="right" :style="{ height: '100%',width:'100%' }">
      <zxksKsdtqk></zxksKsdtqk>
    </van-popup>
  </div>
</template>
 
<script>
// 导航栏
import comnavBar from '@/components/com_navBar'
// 查看提示弹框
import comZxksTip from '@/components/com_zxksTip'
// 考试结束弹框
import comKnow from '@/components/com_know'
// 考试结束弹框
import comOkCancel from '@/components/com_ok_cancel'
// 考试结束答题情况弹框
import zxksKsdtqk from '@/modules/zxks_ksdtqk'
// 单选题
import comRadio from '@/components/com_radio'
// 多选题
import comCheckbox from '@/components/com_checkbox'
// 填空题
import comBlank from '@/components/com_blank'
// 判断题
import comJudge from '@/components/com_judge'
// 简答题
import comshortAnswer from '@/components/com_shortAnswer'
export default {
  components: {
    comnavBar,
    comRadio,
    comCheckbox,
    comBlank,
    comJudge,
    comshortAnswer,
    comZxksTip,
    comKnow,
    comOkCancel,
    zxksKsdtqk
  },
  data() {
    return {
      // 提交的属于哪个类型   1:返回的弹框  2:提交的弹框
      currentType: '',
      // 是否提交
      showIsSubmit: false,
      // 提交的提示信息
      tipWord: '',
      // 左面按钮
      tipLeft: '',
      // 右面面按钮
      tipRight: '',
      // 当前考试的时长
      times: '',
      // 剩余时间
      Time: '',
      // 考试总时长
      totalTime: '',
      // 展示提示框
      showTip: false,
      // 导航的标题
      Title: '在线考试',
      // 试题列表
      testList: [],
      // 当前试题
      currentTest: {},
      // 当前试题的索引
      currentIndex: 0,
      // 提示考试结束
      showEndTip: false,
      // 选择试题列表
      showXZST: false,
      // 试题答完之后的情况反馈
      showSTQKFK: false
    }
  },
  watch: {},
  created() {
    // 获取试题
    this.getData()
    this.times = this.$route.query.time
    this.totalTime = this.times * 60
  },
  mounted() {
    this.times = this.times * 60
    this.timeDown()
    this.times--
    this.time = setInterval(() => {
      if (this.times === 0) {
        clearInterval(this.time)
        this.showEndTip = true
      }
      this.timeDown()
      this.times--
    }, 1000)
  },
  methods: {
    // 返回(强行退出当前考试)
    onClickLeft() {
      this.currentType = '1'
      this.showIsSubmit = true
      this.tipWord = '如退出当前考试,将自动提交您的试卷!!!'
      this.tipLeft = '退出'
      this.tipRight = '继续作答'
    },
    // 关闭提交框
    cancelTestSubmit(data) {
      // data   0:取消   1:确定
      // 点击返回的弹框
      if (this.currentType === '1') {
        if (data === '0') {
          this.$router.go(-1)
        } else {
          this.showIsSubmit = false
        }
      }
      // 点击提交的弹框
      if (this.currentType === '2') {
        if (data === '0') {
          this.showIsSubmit = false
        } else {
          this.showSTQKFK = true
        }
      }
    },
    // 提交
    submitFun() {
      this.currentType = '2'
      this.showIsSubmit = true
      this.tipWord = '是否提交您的试卷!!!'
      this.tipLeft = '暂不提交'
      this.tipRight = '确认提交'
    },
    // 切换试题索引
    updateTestIndexFun(val) {
      this.currentIndex = val - 1
      this.currentTest = this.$store.state.zxksList[this.currentIndex]
      this.showXZST = false
    },
    // 展示试题列表
    testIndexListFun() {
      this.showXZST = true
    },
    // 将时间转化格式
    timeDown() {
      let leftTime = this.times
      let m = this.formate(parseInt(leftTime / 60))
      let s = this.formate(parseInt(leftTime % 60))
      this.Time = `${m}分${s}秒` // 需要修改时间样式的话 ,比如需要什么30分钟倒计时,就只保留分和秒
    },
    formate(time) {
      if (time >= 10) {
        return time
      } else {
        return `0${time}`
      }
    },
    // 查看提示
    cktsFun() {
      this.showTip = true
    },
    // 取消查看提示的弹框
    cancelMask() {
      this.showTip = false
    },
    // 取消考试结束额弹框
    cancelTestTip() {
      this.showEndTip = false
      this.$router.go(-1)
    },
    // 获取试题
    getData() {
      this.testList = [
        // 单选题
        {
          num: '1', //题目序号
          score: '2', //题目分数
          id: '1',
          type: '1', //1:单选题  2:多选题  3:填空题   4:判断题  5:简答题
          title: '1+1=__', //题目
          tip: '单选题提示',
          tmList: [
            { id: '11', key: 'A', value: '0', state: false },
            { id: '12', key: 'B', value: '1', state: false },
            { id: '13', key: 'C', value: '2', state: false },
            { id: '14', key: 'D', value: '3', state: false }
          ],
          answer: '' //选择的答案
        },
        // 多选题
        {
          num: '2',
          score: '2',
          id: '2',
          type: '2',
          title: '你觉得你是__的人?', //题目
          tip: '多选题提示',
          tmList: [
            { id: '21', key: 'A', value: '活泼开朗', state: false },
            { id: '22', key: 'B', value: '美丽大方', state: false },
            { id: '23', key: 'C', value: '工作认真', state: false },
            { id: '24', key: 'D', value: '勤俭持家', state: false }
          ],
          answer: []
        },
        // 填空题
        {
          num: '3',
          score: '2',
          id: '3',
          type: '3',
          title: '1+1=__,1+2=__', //题目
          tip: '填空题提示',
          answer: ''
        },
        // 判断题
        {
          num: '4',
          score: '2',
          id: '4',
          type: '4', //1:单选题  2:多选题  3:判断题   4:填空题  5:简答题
          title: '1+1=0', //题目
          tip: '判断题提示',
          tmList: [
            { id: '41', key: '正确', value: '0', state: false },
            { id: '42', key: '错误', value: '1', state: false }
          ],
          answer: ''
        },
        // 简答题
        {
          num: '5',
          score: '2',
          id: '5',
          type: '5',
          title: '请描述自己', //题目
          tip: '简答题提示',
          answer: ''
        }
      ]
      this.$store.state.zxksList = this.testList
      this.currentTest = this.$store.state.zxksList[this.currentIndex]
    },
    // 点击切换试题
    getCurrentTest(val) {
      if (val === '1') {
        this.currentIndex++
        this.currentTest = this.$store.state.zxksList[this.currentIndex]
      } else {
        this.currentIndex--
        this.currentTest = this.$store.state.zxksList[this.currentIndex]
      }
    }
  }
}
</script>
 
<style scoped>
.zxks_dt {
  width: 100vw;
  height: 92vh;
  background: #f3f4f6;
  padding-top: 10vh;
}
.zxks_dt_content {
  width: 95vw;
  margin-left: 2.5vw;
  background: #ffffff;
  border-radius: 2vw;
}
.zxks_dt_btn {
  width: 95vw;
  height: 15vw;
  display: flex;
  padding-top: 5vw;
}
.zxks_dt_btn > div {
  width: 40vw;
  margin-left: 5vw;
}
.zxks_dt_btn > div /deep/ .van-button {
  width: 40vw;
  font-size: 4.5vw;
  height: 10vw;
  line-height: 10vw;
}

/* 标题 */
.comRadio_top {
  width: 100%;
  height: 10vw;
  border-bottom: 1px solid #f7f7f7;
  padding-top: 4vw;
  display: flex;
}
.comRadio /deep/ .van-popup {
  overflow-y: hidden;
}
.comRadio_top > div:nth-child(1) {
  width: 25%;
  height: 6vw;
  line-height: 6vw;
  text-align: left;
  margin-left: 3%;
  border-left: 1vw solid #ea3131;
  padding-left: 3vw;
  font-weight: bold;
  font-size: 4.5vw;
}
.comRadio_top > div:nth-child(2) {
  width: 50%;
  height: 6vw;
  line-height: 6vw;
  text-align: left;
  margin-left: 3%;
  padding-left: 3vw;
  text-align: right;
}
.comRadio_top > div:nth-child(3) {
  width: 6%;
  height: 6vw;
  line-height: 6vw;
  padding-top: 0.5vw;
  margin-left: 1vw;
}
/* 提示 */
.comRadio_tip {
  width: 95%;
  display: flex;
  margin-top: 5vw;
}
.comRadio_tip > div:nth-child(1) {
  width: 80%;
  text-align: right;
}
.comRadio_tip > div:nth-child(2) {
  width: 20%;
  text-align: center;
  color: #777777;
  font-size: 3.5vw;
}
.comRadio_tip img {
  width: 5vw;
  height: 5vw;
}

/* 选择试题 */
.xzstTitle {
  height: 6vh;
  line-height: 6vh;
  background: #ea3131;
  color: #ffffff;
}
.xzstContent {
  height: 64vh;
  display: flex;
  overflow-y: auto;
}
.xzstContent > div {
  width: 8vw;
  height: 8vw;
  line-height: 8vw;
  border-radius: 50%;
  margin: 2vw 1vw 1vw 2vw;
}
.xzstContent_btn_no {
  border: 1px solid #ea3131;
  color: #ea3131;
}
.xzstContent_btn_ok {
  border: 1px solid #ea3131;
  background: #ea3131;
  color: #ffffff;
}
</style>
           

3.zxks_ksxx.vue(考试信息——子组件)

<template>
  <div class="zxks_ksxx">
    <div class="zxks_ksxx_top" @click="closeFun">{{currentInfo.title}}</div>
    <!-- 考试信息 -->
    <div class="zxks_ksxx_mask" @click="closeFun">
      <div class="borderB">
        <div>
          <img src="./../assets/icons/[email protected]" alt>
        </div>
        <div class="marginT2">
          <div>试卷总分</div>
          <div class="fontW">{{currentInfo.mf}}分</div>
        </div>
      </div>
      <div class="borderB borderL">
        <div>
          <img src="./../assets/icons/[email protected]" alt>
        </div>
        <div class="marginT2">
          <div>及格分</div>
          <div class="fontW">{{currentInfo.jgf}}分</div>
        </div>
      </div>
      <div>
        <div>
          <img src="./../assets/icons/[email protected]" alt>
        </div>
        <div class="marginT2">
          <div>总题数</div>
          <div class="fontW">{{currentInfo.zts}}题</div>
        </div>
      </div>
      <div class="borderL">
        <div>
          <img src="./../assets/icons/[email protected]" alt>
        </div>
        <div class="marginT2">
          <div>考试时长</div>
          <div class="fontW">{{currentInfo.kssc}}分钟</div>
        </div>
      </div>
    </div>
    <!-- 考试时间 -->
    <div class="zxks_ksxx_time" @click="closeFun">
      <div>
        <img src="./../assets/icons/[email protected]" alt>
      </div>
      <div>
        <div>考试时间</div>
        <div>
          {{currentInfo.dateStart}}
          <span style="marginleft: 1vw">{{currentInfo.timeStart}}</span>
          ~
          {{currentInfo.dateEnd}}
          <span
            style="margin-left:1vw"
          >{{currentInfo.timeEnd}}</span>
        </div>
      </div>
    </div>
    <!-- 考试说明 -->
    <div class="zxks_ksxx_kssm" @click="closeFun">
      <div>
        <img src="./../assets/icons/[email protected]" alt>
      </div>
      <div>
        <div>考试说明</div>
        <div>{{currentInfo.kssm}}</div>
      </div>
    </div>
    <div class="zxks_ksxx_btn">
      <van-button type="danger" :disabled="true" v-if="currentInfo.state==='0'">未开始</van-button>
      <van-button type="danger" v-if="currentInfo.state==='1'" @click="datiFun()">开始答题</van-button>
      <van-button type="danger" :disabled="true" v-if="currentInfo.state==='2'">已结束</van-button>
    </div>
  </div>
</template>
 
<script>
//import * from '@/*/*'
export default {
  components: {},
  props: ['currentInfo'],
  data() {
    return {}
  },
  watch: {},
  created() {},
  methods: {
    // 关闭考试信息的弹框
    closeFun() {
      this.$emit('closeFun')
    },
    // 开始答题
    datiFun() {
      this.$router.push({
        name: 'zxksDT',
        query: { time: this.currentInfo.kssc }
      })
    }
  }
}
</script>
 
<style scoped>
.zxks_ksxx {
  position: relative;
}
.zxks_ksxx_top {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  font-size: 5vw;
  height: 20vh;
  color: #fefffe;
  line-height: 30vw;
  background-image: url('./../assets/icons/[email protected]');
  background-size: 100% 100%;
}
.zxks_ksxx_mask {
  width: 85vw;
  height: 26vh;
  position: absolute;
  top: 15vh;
  left: 5.5vw;
  background: #ffffff;
  box-shadow: 0 0 1vw rgb(211, 209, 209);
  border-radius: 2vw;
  display: flex;
  flex-wrap: wrap;
}
.zxks_ksxx_mask > div {
  width: 42vw;
  display: flex;
  flex-wrap: wrap;
  height: 13vh;
}
.zxks_ksxx_mask > div > div {
  width: 20vw;
  padding-top: 2.5vh;
}
.zxks_ksxx_mask img {
  width: 8vh;
  height: 8vh;
}
.marginT2 {
  margin-top: 1vh;
  text-align: left;
}
.fontW {
  font-weight: bold;
  margin-top: 1vh;
}
.borderL {
  border-left: 1px solid #efefef;
}
.borderR {
  border-right: 1px solid #efefef;
}
.borderT {
  border-top: 1px solid #efefef;
}
.borderB {
  border-bottom: 1px solid #efefef;
}
/* // 考试时间 */
.zxks_ksxx_time {
  width: 85vw;
  height: 7vh;
  position: absolute;
  top: 44vh;
  left: 5.5vw;
  background: #ffffff;
  display: flex;
  flex-wrap: wrap;
  padding-bottom: 1vh;
  border-bottom: 1px solid #efefef;
}
.zxks_ksxx_time img {
  width: 2vh;
  height: 2vh;
}
.zxks_ksxx_time > div:nth-child(1) {
  width: 7vw;
  height: 2vh;
}
.zxks_ksxx_time > div:nth-child(2) {
  width: 70vw;
  height: 3vh;
  text-align: left;
}
.zxks_ksxx_time > div > div:nth-child(1) {
  text-align: left;
  font-weight: bold;
}
.zxks_ksxx_time > div > div:nth-child(2) {
  text-align: left;
  margin-top: 0.5vh;
  color: #999999;
  font-size: 3.7vw;
}
/* 考试说明 */
.zxks_ksxx_kssm {
  width: 85vw;
  height: 21vh;
  line-height: 3.5vh;
  position: absolute;
  top: 55vh;
  left: 5.5vw;
  background: #ffffff;
  display: flex;
  flex-wrap: wrap;
  padding-bottom: 1vh;
}
.zxks_ksxx_kssm img {
  width: 3vw;
  height: 3vw;
}
.zxks_ksxx_kssm > div:nth-child(1) {
  width: 5vw;
  height: 5vw;
}
.zxks_ksxx_kssm > div:nth-child(2) {
  width: 79vw;
  height: 5vw;
  text-align: left;
}
.zxks_ksxx_kssm > div > div:nth-child(1) {
  text-align: left;
  font-weight: bold;
}
.zxks_ksxx_kssm > div > div:nth-child(2) {
  text-align: left;
  margin-top: 1vw;
  height: 16.5vh;
  color: #999999;
  font-size: 3.7vw;
  overflow-y: auto;
}
/* 按钮 */
.zxks_ksxx_btn {
  width: 85vw;
  position: absolute;
  top: 80vh;
  left: 5.5vw;
}
.zxks_ksxx_btn /deep/ .van-button--danger {
  color: #ffffff;
  border-radius: 10vw;
  width: 85vw;
  background: #eb3132;
  border: 1px solid #eb3132;
}
</style>
           

4.zxks_ksdtqk.vue(考试结束答题情况——子组件)

<template>
  <div class="zxksKsdtqk">
    <comnavBar :Title="'在线考试'" :backType="'1'" @onClickLeft="onClickLeft"></comnavBar>
    <!-- 主体内容 -->
    <div class="zxksKsdtqk_content">
      <div class="zxksKsdtqk_title">{{testInfo.title}}</div>
      <div class="zxksKsdtqk_mask">
        <div
          :class="testInfo.isPass==='1'?'zxksKsdtqk_img zxksKsdtqk_img_success':'zxksKsdtqk_img zxksKsdtqk_img_fail'"
        >
          <div
            :class="testInfo.isPass==='1'?'zxksKsdtqk_score_success':'zxksKsdtqk_score_fail'"
          >{{testInfo.score}}</div>
        </div>
        <div class="zxksKsdtqk_threeDiv">
          <div>
            <div>{{testInfo.dtys}}</div>
            <div>答题用时</div>
          </div>
          <div>
            <div>{{testInfo.hgf}}/{{testInfo.totalScore}}</div>
            <div>合格分/总分</div>
          </div>
          <div>
            <div>{{testInfo.jfpm}}</div>
            <div>积分排名</div>
          </div>
        </div>
      </div>
      <!-- 试题 -->
      <div class="zxksKsdtqk_test">
        <!-- 序号 -->
        <div
          :class="item.isFail==='0'?'zxksKsdtqk_test_success':'zxksKsdtqk_test_fail'"
          v-for="(item,index) in testInfo.testList"
          :key="index"
          @click="updateCurrentTestFun(index)"
        >{{index+1}}</div>
      </div>
      <!-- 试题 -->
      <div class="zxksKsdtqk_testContent">
        <!-- 题目 -->
        <div class="zxksKsdtqk_test_tm">{{currentTest.num}}.{{currentTest.title}}</div>
        <!-- 选项 -->
        <div class="zxksKsdtqk_test_xx">
          <!-- 单选题 -->
          <comRadio
            v-if="currentTest.type==='1'"
            :obj="currentTest.type==='1'?currentTest:''"
            :type="'1'"
          ></comRadio>
          <!-- 多选题 -->
          <comCheckbox
            :type="'1'"
            v-if="currentTest.type==='2'"
            :obj="currentTest.type==='2'?currentTest:''"
          ></comCheckbox>
          <!-- 填空题 -->
          <comBlank
            :type="'1'"
            v-if="currentTest.type==='3'"
            :obj="currentTest.type==='3'?currentTest:''"
          ></comBlank>
          <!-- 判断题 -->
          <comJudge
            :type="'1'"
            v-if="currentTest.type==='4'"
            :obj="currentTest.type==='4'?currentTest:''"
          ></comJudge>
          <!-- 简答题 -->
          <comshortAnswer
            :type="'1'"
            v-if="currentTest.type==='5'"
            :obj="currentTest.type==='5'?currentTest:''"
          ></comshortAnswer>
        </div>
      </div>
      <!-- 答案 -->
      <div class="zxksKsdtqk_testAnswer">
        <!-- 题目 -->
        <div class="zxksKsdtqk_answer">
          正确答案:
          <span style="color:#1EB91D;font-weight:bold">【{{currentTest.rightAnswer}}】</span>
        </div>
        <!-- 选项 -->
        <div class="zxksKsdtqk_jx">
          <div>解析</div>
          <span style="color:#6B6B6B;margin-left:3vw">{{currentTest.jx}}</span>
        </div>
      </div>
    </div>
  </div>
</template>
 
<script>
// 导航栏
import comnavBar from '@/components/com_navBar'
// 单选题
import comRadio from '@/components/com_radio'
// 多选题
import comCheckbox from '@/components/com_checkbox'
// 填空题
import comBlank from '@/components/com_blank'
// 判断题
import comJudge from '@/components/com_judge'
// 简答题
import comshortAnswer from '@/components/com_shortAnswer'
export default {
  components: {
    comRadio,
    comCheckbox,
    comBlank,
    comJudge,
    comshortAnswer,
    comnavBar
  },
  data() {
    return {
      // 考试情况
      testInfo: {},
      // 当前试题索引
      currentIndex: 0,
      // 当前试题
      currentTest: {}
    }
  },
  watch: {},
  created() {
    // 获取考试情况
    this.getData()
  },
  methods: {
    // 切换试题
    updateCurrentTestFun(val) {
      this.currentIndex = val
      this.currentTest = this.testInfo.testList[this.currentIndex]
    },
    // 获取考试情况
    getData() {
      this.testInfo = {
        title: '2020年知识竞赛', //考试名称
        totalScore: 100, //总分
        score: 89, //得分
        hgf: 60, //合格分
        isPass: '1', //0:未通过  1:通过
        dtys: '12分30秒', // 答题用时
        jfpm: '10/50', //积分排名
        testList: [
          // 单选题
          {
            num: '1', //题目序号
            score: '2', //题目分数
            id: '1', //题目id
            type: '1', //1:单选题  2:多选题  3:填空题   4:判断题  5:简答题
            title: '1+1=__', //题目
            tip: '单选题提示', //提示信息
            tmList: [
              { id: '11', key: 'A', value: '0', state: false },
              { id: '12', key: 'B', value: '1', state: false },
              { id: '13', key: 'C', value: '2', state: false },
              { id: '14', key: 'D', value: '3', state: false }
            ],
            answer: '11', //选择的答案
            isFail: '1', //该答案是否错误  0:正确 1:错误
            rightAnswer: 'C', //正确答案
            jx: '暂无解析' //解析
          },
          // 多选题
          {
            num: '2',
            score: '2',
            id: '2',
            type: '2',
            title: '你觉得你是__的人?', //题目
            tip: '多选题提示',
            tmList: [
              { id: '21', key: 'A', value: '活泼开朗', state: false },
              { id: '22', key: 'B', value: '美丽大方', state: false },
              { id: '23', key: 'C', value: '工作认真', state: false },
              { id: '24', key: 'D', value: '勤俭持家', state: false }
            ],
            answer: '21,22,23,24', //选择的答案
            isFail: '0', //该答案是否错误  0:正确 1:错误
            rightAnswer: 'ABCD', //正确答案
            jx: '暂无解析' //解析
          },
          // 填空题
          {
            num: '3',
            score: '2',
            id: '3',
            type: '3',
            title: '1+1=__,1+2=__', //题目
            tip: '填空题提示',
            answer: '2,3', //自己的答案
            isFail: '0', //该答案是否错误  0:正确 1:错误
            rightAnswer: '2,3', //正确答案
            jx: '暂无解析' //解析
          },
          // 判断题
          {
            num: '4',
            score: '2',
            id: '4',
            type: '4', //1:单选题  2:多选题  3:判断题   4:填空题  5:简答题
            title: '1+1=0', //题目
            tip: '判断题提示',
            tmList: [
              { id: '41', key: '正确', value: '0', state: false },
              { id: '42', key: '错误', value: '1', state: false }
            ],
            answer: '41', //自己的答案
            isFail: '0', //该答案是否错误  0:正确 1:错误
            rightAnswer: '正确', //正确答案
            jx: '暂无解析' //解析
          },
          // 简答题
          {
            num: '5',
            score: '2',
            id: '5',
            type: '5',
            title: '请描述自己', //题目
            tip: '简答题提示',
            answer: '我的描述', //自己的答案
            isFail: '0', //该答案是否错误  0:正确 1:错误
            rightAnswer: '我的描述', //正确答案
            jx: '暂无解析' //解析
          }
        ]
      }
      this.currentTest = this.testInfo.testList[this.currentIndex]
      console.log(this.testInfo.testList[this.currentIndex])
    },
    // 返回
    onClickLeft() {
      this.$router.push({ name: 'zxks' })
    }
  }
}
</script>
 
<style scoped>
.zxksKsdtqk_content {
  height: 100vh;
  overflow-y: auto;
}

.zxksKsdtqk_title {
  width: 100%;
  height: 50vw;
  background-image: url(/img/[email protected]);
  background-size: 100% 100%;
  line-height: 45vw;
  color: #ffffff;
  font-size: 5vw;
  text-align: center;
}

.zxksKsdtqk_mask {
  width: 90vw;
  background: #ffffff;
  border-radius: 2vw;
  margin-left: 5vw;
  box-shadow: 0 0 1vw gainsboro;
  margin-top: -20vw;
  padding-top: 1vw;
}
.zxksKsdtqk_img {
  margin-top: 5vw;
  width: 55vw;
  height: 38vw;
  margin-left: 17.5vw;
}
.zxksKsdtqk_img_success {
  background-image: url('./../assets/icons/[email protected]');
  background-size: 100% 100%;
}
.zxksKsdtqk_img_fail {
  background-image: url('./../assets/icons/[email protected]');
  background-size: 100% 100%;
}
.zxksKsdtqk_score_success {
  font-size: 10vw;
  font-weight: bold;
  color: #e54435;
  height: 20vw;
  line-height: 20vw;
}
.zxksKsdtqk_score_fail {
  font-size: 10vw;
  font-weight: bold;
  color: #878787;
  height: 20vw;
  line-height: 20vw;
}
.zxksKsdtqk_threeDiv {
  width: 100%;
  height: 20vw;
  background: #ffff;
  border-top: 1px solid #eeeeee;
  margin-top: 9vw;
  border-radius: 0 0 2vw 2vw;
  display: flex;
}
.zxksKsdtqk_threeDiv > div {
  width: 33%;
}
.zxksKsdtqk_threeDiv > div > div:nth-child(1) {
  font-weight: bold;
  height: 10vw;
  line-height: 15vw;
  font-size: 4.5vw;
}
.zxksKsdtqk_threeDiv > div > div:nth-child(2) {
  color: #696969;
  margin-top: 1vw;
}

.zxksKsdtqk_threeDiv > div:nth-child(1) {
  border-right: 1px solid #eeeeee;
}
.zxksKsdtqk_threeDiv > div:nth-child(2) {
  border-right: 1px solid #eeeeee;
}
.zxksKsdtqk_test {
  width: 95%;
  margin-left: 2.5vw;
  display: flex;
  flex-wrap: wrap;
  padding-bottom: 2vw;
  border-bottom: 1px solid #eeeeee;
  margin-top: 5vw;
}
.zxksKsdtqk_test > div {
  width: 8vw;
  height: 8vw;
  line-height: 8vw;
  border-radius: 50%;
  margin: 2vw;
}
.zxksKsdtqk_test_success {
  background: #d2f1d2;
  border: 1px solid #d2f1d2;
  color: #1fba1e;
}
.zxksKsdtqk_test_fail {
  background: #fcd5d6;
  border: 1px solid #fcd5d6;
  color: #eb3131;
}
.zxksKsdtqk_testContent {
  margin-top: 5vw;
  width: 95vw;
  width: 95%;
  margin-left: 2.5vw;
  padding-bottom: 3vw;
  border-bottom: 1px solid #eeeeee;
}
.zxksKsdtqk_test_tm {
  text-align: left;
  font-weight: bold;
  font-size: 4.5vw;
  line-height: 8vw;
  padding-left: 3vw;
}
.zxksKsdtqk_testAnswer {
  margin-top: 3vw;
  width: 95vw;
  margin-left: 2.5vw;
  text-align: left;
  margin-bottom: 20vw;
}
.zxksKsdtqk_jx > div {
  margin-top: 3vw;
}
.zxksKsdtqk_jx > div:nth-child(1) {
  width: 12vw;
  height: 5vw;
  background: #cccccc;
  color: #ffffff;
  display: inline-block;
  font-size: 3.5vw;
  text-align: center;
  border-radius: 2px;
}
</style>
           

5.com_navBar.vue(导航栏——子组件)

<template>
  <div class="com_navBar">
    <van-nav-bar :fixed="true" :title="Title" v-if="backType==='0'"/>
    <van-nav-bar
      v-if="backType==='1'"
      :title="Title"
      :fixed="true"
      left-arrow
      @click-left="onClickLeft"
    />
  </div>
</template>
 
<script>
//import * from '@/*/*'
export default {
  props: ['backType', 'Title'],
  data() {
    return {}
  },
  watch: {},
  created() {},
  methods: {
    // 返回
    onClickLeft() {
      this.$emit('onClickLeft')
    }
  }
}
</script>
 
<style scoped>
.com_navBar /deep/ .van-nav-bar {
  background-color: #eb3132;
  z-index: 1000;
}
.com_navBar /deep/ .van-nav-bar__title {
  color: #ffffff;
  font-size: 4vw;
}
.com_navBar /deep/ .van-nav-bar__text {
  color: #ffffff;
  font-size: 4vw;
}
.com_navBar /deep/ .van-icon-arrow-left::before {
  color: #ffffff;
  font-size: 4vw;
}

[class*='van-hairline']::after {
  border: 1px solid #eb3132;
}
</style>
           

6.com_radio.vue(单选题——子组件)

<template>
  <div class="comRadio">
    <!-- 在线答题 -->
    <div v-if="type==='0'" class="comRadio_div">
      <div class="comRadio_title">
        {{obj.num}}.
        <span style="margin-left:1vw">{{obj.title}}</span>
        <span class="comRadio_scoreClass">({{obj.score}}分)</span>
      </div>
      <div
        v-for="(item,index) in obj.tmList"
        :key="index"
        :class="item.state?'inputClassOk':'inputClass'"
        @click="changeFun(item,'0')"
      >
        {{item.key}}.
        <span style="margin-left:1vw">{{item.value}}</span>
      </div>
    </div>
    <!-- 考试结束预览试题 -->
    <div v-if="type==='1'" class="commentRadio">
      <div v-for="(item,index) in obj.tmList" :key="index" class="inputClass">
        <input
          :id="item.id"
          type="radio"
          :value="item.id"
          :disabled="true"
          :checked="item.id===radioVal?true:false"
          @change="changeFun(item,'1')"
        >
        <label :for="item.id"></label>
        <span>
          <label :for="item.id">{{item.key}}.{{item.value}}</label>
        </span>
      </div>
    </div>
  </div>
</template>
 
<script>
export default {
  components: {},
  props: ['obj', 'type'],
  data() {
    return {
      // 选中的答案
      radioVal: ''
    }
  },
  watch: {
    obj: {
      handler(val) {
        //拿到后台返回的正确选项显示,单选默认选中
        this.radioVal = val.answer
        //  this.$emit('getRadioVal', { tmId: this.questionId, radioValue: val })
      },
      deep: true,
      immediate: true
    }
  },
  created() {},
  methods: {
    // 选中试题
    changeFun(val, type) {
      if (type === '0') {
        val.state = !val.state
      }
      this.radioVal = val.id
    }
  }
}
</script>
 
<style scoped>
/* 标题 */
.comRadio_div .comRadio_title {
  margin-top: 3vw;
  width: 95%;
  font-weight: bold;
  text-align: left;
  margin-left: 5%;
  font-size: 4.5vw;
}
.comRadio_div .comRadio_scoreClass {
  color: #a0a0a0;
}
/* 处理单选样式 */
.comRadio_div .comRadio input {
  width: 4.5vw;
  height: 4.5vw;
}
.comRadio_div .inputClass {
  width: 90%;
  position: relative;
  height: 8vw;
  padding-top: 3vw;
  padding-left: 2vw;
  margin-left: 15px;
  border: 1px solid;
  text-align: left;
  margin-top: 3vw;
  background: #f6f7f9;
  border: 1px solid #e9e9e9;
  border-radius: 1vw;
}
.comRadio_div .inputClassOk {
  width: 90%;
  position: relative;
  height: 8vw;
  padding-top: 3vw;
  padding-left: 2vw;
  margin-left: 15px;
  border: 1px solid;
  text-align: left;
  margin-top: 3vw;
  background: #eb3132;
  border: 1px solid #eb3132;
  border-radius: 1vw;
  color: #ffffff;
}
.comRadio_div .inputClass input[type='radio'] {
  width: 20px;
  height: 20px;
  opacity: 0;
}

/* /另一种样式 (预览试题)*/
.commentRadio input {
  width: 4.5vw;
  height: 4.5vw;
}
.commentRadio .inputClass {
  position: relative;
  line-height: 6vw;
  margin-left: 15px;
  text-align: left;
}

.commentRadio .inputClass input[type='radio'] {
  width: 20px;
  height: 20px;
  opacity: 0;
}

.commentRadio .inputClass > label {
  position: absolute;
  left: -2px;
  top: 9px;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  border: 1px solid #999;
}

/*设置选中的input的样式*/
/* + 是兄弟选择器,获取选中后的label元素*/
.commentRadio .inputClass input:checked + label {
  background-color: #f24d4b;
  border: 1px solid #f24d4b;
}
.commentRadio .inputClass input:checked + label::after {
  position: absolute;
  content: '';
  width: 5px;
  height: 10px;
  top: 0;
  left: 4.1px;
  border: 2px solid #fff;
  border-top: none;
  border-left: none;
  transform: rotate(45deg);
}
</style>
           

7.com_checkbox.vue(多选题-子组件)

<template>
  <div class="comCheckbox">
    <div class="comCheckbox_div" v-if="type==='0'">
      <div class="comCheckbox_title">
        {{obj.num}}.
        <span style="margin-left:1vw">{{obj.title}}</span>
        <span class="comCheckbox_scoreClass">({{obj.score}}分)</span>
      </div>
      <div
        v-for="(item,index) in obj.tmList"
        :key="index"
        :class="item.state?'inputClassOk':'inputClass'"
        @click="changeFun(item)"
      >{{item.key}}.{{item.value}}</div>
    </div>
    <div class="commentRadio" v-if="type==='1'">
      <div v-for="(con,i) in obj.tmList" :key="i+'r'" class="inputClass">
        <input :id="con.id" type="checkbox" :value="con.id" v-model="checkboxList" :disabled="true">
        <label :for="con.id"></label>
        <span>
          <label :for="con.id">
            {{con.key}}.{{con.value}}
            <!-- <a style="color:red;font-size:4vw">({{con.score}}分)</a> -->
          </label>
        </span>
      </div>
    </div>
  </div>
</template>
 
<script>
export default {
  components: {},
  props: ['obj', 'type'],
  data() {
    return {
      // 选中的答案
      checkboxList: [],
      // 选项
      tmList: []
    }
  },
  watch: {
    obj: {
      handler(val) {
        if (!val.answer) {
          this.checkboxList = []
        } else {
          if (typeof val.answer === 'string') {
            this.checkboxList = this.strAndArr(val.answer)
          }
          if (typeof val.answer === 'object') {
            this.checkboxList = val.answer
          }
        }
      },
      deep: true,
      immediate: true
    }
  },
  created() {},
  methods: {
    // 字符串转数组
    strAndArr(str) {
      return str.split(',')
    },
    // 选中试题
    changeFun(val) {
      val.state = !val.state
    }
  }
}
</script>
 
<style scoped>
.comCheckbox_div .comCheckbox_title {
  margin-top: 3vw;
  width: 95%;
  font-weight: bold;
  text-align: left;
  margin-left: 3%;
  font-size: 4.5vw;
}
.comCheckbox_div .comCheckbox_scoreClass {
  color: #a0a0a0;
}
/* 处理单选样式 */
.comCheckbox_div .comCheckbox input {
  width: 4.5vw;
  height: 4.5vw;
}
.comCheckbox_div .inputClass {
  width: 90%;
  position: relative;
  height: 8vw;
  padding-top: 3vw;
  padding-left: 2vw;
  margin-left: 15px;
  border: 1px solid;
  text-align: left;
  margin-top: 3vw;
  background: #f6f7f9;
  border: 1px solid #e9e9e9;
  border-radius: 1vw;
}
.comCheckbox_div .inputClassOk {
  width: 90%;
  position: relative;
  height: 8vw;
  padding-top: 3vw;
  padding-left: 2vw;
  margin-left: 15px;
  border: 1px solid;
  text-align: left;
  margin-top: 3vw;
  background: #eb3132;
  border: 1px solid #eb3132;
  border-radius: 1vw;
  color: #ffffff;
}
.comCheckbox_div .inputClass input[type='radio'] {
  width: 20px;
  height: 20px;
  opacity: 0;
}

/* 另一方式 */
.commentRadio .commentRadio input {
  width: 4.5vw;
  height: 4.5vw;
  display: none;
}
.commentRadio .inputClass {
  position: relative;
  line-height: 10vw;
  margin-left: 15px;
  text-align: left;
}
.commentRadio .inputClass input[type='checkbox'] {
  width: 20px;
  height: 20px;
  opacity: 0;
}
.commentRadio .inputClass > label {
  position: absolute;
  left: 0;
  top: 9px;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  border: 1px solid #999;
}

/*设置选中的input的样式*/
/* + 是兄弟选择器,获取选中后的label元素*/
.commentRadio .inputClass input:checked + label {
  background-color: #f24d4b;
  border: 1px solid #f24d4b;
}

.commentRadio .inputClass input:checked + label::after {
  position: absolute;
  content: '';
  width: 5px;
  height: 10px;
  top: 0;
  left: 4.1px;
  border: 2px solid #fff;
  border-top: none;
  border-left: none;
  transform: rotate(45deg);
}
</style>
           

8.com_blank.vue(填空题——子组件)

<template>
  <div class="comBlank">
    <div class="comBlank_title" v-if="type==='0'">
      {{obj.num}}.
      <span style="margin-left:1vw">{{obj.title}}</span>
      <span class="comBlank_scoreClass">({{obj.score}}分)</span>
    </div>
    <div class="comBlank_text">
      <textarea
        :disabled="type==='1'?true:false"
        cols="25"
        rows="10"
        placeholder="请将答案用“ ,”隔开"
        v-model="obj.answer"
      ></textarea>
    </div>
  </div>
</template>
 
<script>
export default {
  components: {},
  props: ['obj', 'type'],
  data() {
    return {}
  },
  watch: {},
  created() {},
  methods: {}
}
</script>
 
<style scoped>
.comBlank_title {
  margin-top: 3vw;
  width: 95%;
  font-weight: bold;
  text-align: left;
  margin-left: 3%;
  font-size: 4.5vw;
}
.comBlank_scoreClass {
  color: #a0a0a0;
}

.comBlank_text {
  width: 95%;
  margin-left: 3%;
  margin-top: 5vw;
}
.comBlank_text > textarea {
  width: 95%;
  border: 1px solid gainsboro;
  background: transparent;
}
</style>
           

9.com_judge.vue(判断题——子组件)

<template>
  <div class="comJudge">
    <div class="comJudge_div" v-if="type==='0'">
      <div class="comJudge_title">
        {{obj.num}}.
        <span style="margin-left:1vw">{{obj.title}}</span>
        <span class="comJudge_scoreClass">({{obj.score}}分)</span>
      </div>
      <div
        v-for="(item,index) in obj.tmList"
        :key="index"
        :class="item.state||item.id===obj.answer?'inputClassOk':'inputClass'"
        @click="changeFun(item)"
      >{{item.key}}</div>
    </div>

    <!-- 考试结束预览试题 -->
    <div v-if="type==='1'" class="commentRadio">
      <div v-for="(item,index) in obj.tmList" :key="index" class="inputClass">
        <input
          :id="item.id"
          type="radio"
          :value="item.id"
          :disabled="true"
          :checked="item.id===radioVal?true:false"
          @change="changeFun(item,'1')"
        >
        <label :for="item.id"></label>
        <span>
          <label :for="item.id">{{item.key}}</label>
        </span>
      </div>
    </div>
  </div>
</template>
 
<script>
export default {
  components: {},
  props: ['obj', 'type'],
  data() {
    return {
      // 选中的答案
      radioVal: ''
    }
  },
  watch: {
    obj: {
      handler(val) {
        //拿到后台返回的正确选项显示,单选默认选中
        this.radioVal = val.answer
        //  this.$emit('getRadioVal', { tmId: this.questionId, radioValue: val })
      },
      deep: true,
      immediate: true
    }
  },
  created() {},
  methods: {
    // 选中试题
    changeFun(val) {
      this.radioVal = val.id
      val.state = !val.state
    }
  }
}
</script>
 
<style scoped>
.comJudge_div .comJudge_title {
  margin-top: 3vw;
  width: 95%;
  font-weight: bold;
  text-align: left;
  margin-left: 5%;
  font-size: 4.5vw;
}
.comJudge_div .comJudge_scoreClass {
  color: #a0a0a0;
}
/* 处理单选样式 */
.comJudge_div .comJudge input {
  width: 4.5vw;
  height: 4.5vw;
}

.comJudge_div .inputClass {
  width: 90%;
  position: relative;
  height: 8vw;
  padding-top: 3vw;
  padding-left: 2vw;
  margin-left: 15px;
  border: 1px solid;
  text-align: left;
  margin-top: 3vw;
  background: #f6f7f9;
  border: 1px solid #e9e9e9;
  border-radius: 1vw;
}
.comJudge_div .inputClassOk {
  width: 90%;
  position: relative;
  height: 8vw;
  padding-top: 3vw;
  padding-left: 2vw;
  margin-left: 15px;
  border: 1px solid;
  text-align: left;
  margin-top: 3vw;
  background: #eb3132;
  border: 1px solid #eb3132;
  border-radius: 1vw;
  color: #ffffff;
}
.comJudge_div .inputClass input[type='radio'] {
  width: 20px;
  height: 20px;
  opacity: 0;
}

/* /另一种样式 (预览试题)*/
.commentRadio input {
  width: 4.5vw;
  height: 4.5vw;
}
.commentRadio .inputClass {
  position: relative;
  line-height: 6vw;
  margin-left: 15px;
  text-align: left;
}

.commentRadio .inputClass input[type='radio'] {
  width: 20px;
  height: 20px;
  opacity: 0;
}

.commentRadio .inputClass > label {
  position: absolute;
  left: -2px;
  top: 9px;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  border: 1px solid #999;
}

/*设置选中的input的样式*/
/* + 是兄弟选择器,获取选中后的label元素*/
.commentRadio .inputClass input:checked + label {
  background-color: #f24d4b;
  border: 1px solid #f24d4b;
}
.commentRadio .inputClass input:checked + label::after {
  position: absolute;
  content: '';
  width: 5px;
  height: 10px;
  top: 0;
  left: 4.1px;
  border: 2px solid #fff;
  border-top: none;
  border-left: none;
  transform: rotate(45deg);
}
</style>
           

10.com_shortAnswer.vue(简答题——子组件)

<template>
  <div class="comShortAnswer">
    <div class="comShortAnswer_title" v-if="type==='0'">
      {{obj.num}}.
      <span style="margin-left:1vw">{{obj.title}}</span>
      <span class="comShortAnswer_scoreClass">({{obj.score}}分)</span>
    </div>
    <div class="comShortAnswer_text">
      <textarea :disabled="type==='1'?true:false" cols="25" rows="10" v-model="obj.answer"></textarea>
    </div>
  </div>
</template>
 
<script>
export default {
  components: {},
  props: ['obj', 'type'],
  data() {
    return {}
  },
  watch: {},
  created() {},
  methods: {}
}
</script>
 
<style scoped>
.comShortAnswer_title {
  margin-top: 3vw;
  width: 95%;
  font-weight: bold;
  text-align: left;
  margin-left: 3%;
  font-size: 4.5vw;
}
.comShortAnswer_scoreClass {
  color: #a0a0a0;
}

.comShortAnswer_text {
  width: 95%;
  margin-left: 3%;
  margin-top: 5vw;
}
.comShortAnswer_text > textarea {
  width: 95%;
  border: 1px solid gainsboro;
  background: transparent
}
</style>
           

11.com_zxksTip.vue(查看提示——子组件)

<template>
  <div class="com_zxksTip">
    <div class="com_zxksTip_title">
      <div>{{title}}</div>
      <div>
        <img @click="cancelFun()" src="./../assets/icons/[email protected]" alt>
      </div>
    </div>
    <div v-if="type==='ts'" class="com_zxksTip_content">{{tip}}</div>
    <div v-if="type==='qj'" class="com_zxksTip_content">
      <van-field
        v-model="qjVal"
        rows="4"
        clearable
        autosize
        type="textarea"
        maxlength="100"
        placeholder="请输入请假理由"
        show-word-limit
      />
    </div>
    <div v-if="type==='fy'" class="com_zxksTip_content">
      <van-field
        v-model="fyVal"
        rows="4"
        clearable
        autosize
        type="textarea"
        maxlength="100"
        placeholder="请输入发言内容"
        show-word-limit
      />
    </div>
    <div class="com_zxksTip_btn" v-if="type==='qj'||type==='fy'">
      <van-button type="danger">确定</van-button>
    </div>
  </div>
</template>
 
<script>
//import * from '@/*/*'
export default {
  components: {},
  props: ['tip', 'title', 'type'],
  data() {
    return {
      // 请假
      qjVal: '',
      // 发言
      fyVal: ''
    }
  },
  watch: {},
  created() {},
  methods: {
    // 取消弹框
    cancelFun() {
      this.$emit('cancelMask')
    }
  }
}
</script>
 
<style scoped>
.com_zxksTip {
  overflow-y: hidden;
}
.com_zxksTip /deep/ .van-field__word-num {
  color: red;
}
.com_zxksTip_title {
  width: 100%;
  height: 8vh;
  line-height: 8vh;
  display: flex;
  border-bottom: 1px solid #efefef;
}
.com_zxksTip_title > div:nth-child(1) {
  width: 90%;
}
.com_zxksTip_title > div:nth-child(2) {
  width: 5%;
}
.com_zxksTip_title img {
  width: 5vw;
  height: 5vw;
}
.com_zxksTip_content {
  width: 95%;
  text-align: left;
  height: 30vh;
  margin-left: 2%;
  margin-top: 5vw;
  line-height: 8vw;
  overflow-y: auto;
  margin-bottom: 3vw;
}
.com_zxksTip_btn /deep/ .van-button {
  width: 90vw;
  height: 10vw;
  line-height: 10vw;
  margin-left: 3vw;
  border-radius: 10vw;
}
</style>
           

12.com_know.vue(我知道了弹框——子组件)

<template>
  <div class="com_know">
    <div class="com_know_top">提示</div>
    <div class="com_know_title">{{tip}}</div>
    <div class="com_know_know">
      <van-button type="danger" @click="cancelTestTip">我知道了</van-button>
    </div>
  </div>
</template>
 
<script>
//import * from '@/*/*'
export default {
  components: {},
  props: ['tip'],
  data() {
    return {}
  },
  watch: {},
  created() {},
  methods: {
    cancelTestTip() {
      this.$emit('cancelTestTip')
    }
  }
}
</script>
 
<style scoped>
.com_know {
  overflow-y: hidden;
  height: 35vh;
}
.com_know_top {
  height: 6vh;
  line-height: 6vh;
  background: #eb3132;
  color: #ffffff;
}
.com_know_title {
  height: 18vh;
  line-height: 18vh;
  font-weight: bold;
  font-size: 4.5vw;
  border-bottom: 1px solid #f3f1f1;
}
.com_know_know {
  height: 15vh;
}
.com_know_know /deep/ .van-button {
  width: 90%;
  border-radius: 10vw;
  margin-top: 4vw;
}
           

继续阅读