Vue3:一页多题答案提示及循环radio和checkbox混合使用

这篇具有很好参考价值的文章主要介绍了Vue3:一页多题答案提示及循环radio和checkbox混合使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一页多题,类型包括单选(单选、判断)和多选,radio和checkbox混合使用,答案检验数据匹配,正确答案格式化,答案提交数据格式化,数据提交。

效果:

Vue3:一页多题答案提示及循环radio和checkbox混合使用,Millia's work,vue.js,javascript,前端

Vue3:一页多题答案提示及循环radio和checkbox混合使用,Millia's work,vue.js,javascript,前端

数据获取:

Vue3:一页多题答案提示及循环radio和checkbox混合使用,Millia's work,vue.js,javascript,前端

数据提交:

Vue3:一页多题答案提示及循环radio和checkbox混合使用,Millia's work,vue.js,javascript,前端

HTML:

<template>

<!--其他HTML结构-->

<ul class="question f16">
  <li v-for="(list,index) in questionData" :key="index">
    <h5>{{list.type}}题</h5>
    <h6 v-if="isScoreTxt">
      <b :class="{daanErr:list.scoreTxt !='正确'}" v-if="list.scoreTxt !='正确'">正确选项是:{{list.scoreTxt}}</b>
      <b v-else>{{list.scoreTxt}}</b>
    </h6>
    
    <!--单选及判断-->
    <dl v-if="list.type != '多选'">
      <dt v-html="list.title"></dt>
      <dd>
        <label v-for="(radio,id) in list.xuanxiang" :key="id">
          <input type="radio" :name="list.id" :value="list.id+'_'+radio.name" v-model="radioData[list.id]">
          <span><b>{{radio.name}}</b>{{radio.content}}</span>
        </label>
      </dd>
    </dl>

    <!--多选-->
    <dl v-else>
      <dt v-html="list.title"></dt>
      <dd>
        <label v-for="(checkbox,checkboxIndex) in list.xuanxiang" :key="checkboxIndex">
          <input type="checkbox" :value="list.id+'_'+checkbox.name" v-model="checkData">
          <span><b>{{checkbox.name}}</b>{{checkbox.content}}</span>
      </label>
    </dd>
    </dl>
  </li>
</ul>
<div class="checkEnterBt f18 sysmt40">
  <button @click="checkEnter">提交答案</button>
  <button @click="checkChange">换题再测试</button>
</div>

<!--其他HTML结构-->

</template>

JS:

<script setup>
import { defineComponent, getCurrentInstance, ref, reactive, computed, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted, onErrorCaptured, onRenderTracked, onRenderTriggered, onActivated, onDeactivated, onServerPrefetch, watch,toRaw } from 'vue';
import {useRoute, onBeforeRouteUpdate} from 'vue-router'
import { useStore } from 'vuex';

//vantUl的showToast请提示
import { showToast } from 'vant';

//使用vue的getCurrentInstance 方法获取当前组件实例
const { proxy } = getCurrentInstance()

//获取vuex数据
let store = useStore();

//使用router
const route = useRoute()


//获取题目列表数据
let questionData = ref([]) //答题数据
let answerData = ref([]) //格式化后答案
const getQuestion = () => {

    /*axois获取题目数据*/

    console.log(response.data.data.data)

    questionData.value = response.data.data.data

    //格式化数据答案为[id,选项],单选[id,A],多选[id,A],[id,C]
    for(let i=0;i<response.data.data.data.length;i++){
      for(let n=0;n<response.data.data.data[i].daan.length;n++){
        if(response.data.data.data[i].daan[n] != "_"){
          answerData.value.push([response.data.data.data[i].id,response.data.data.data[i].daan[n]])
        }
      }
    }

  /*其他代码*/

}


//答案选择
let radioData= ref([]) //单选
let checkData = ref([]) //多选
let selectData = ref([]) //单选和多选合集
let isScoreTxt = ref(false) //答案是否显示校正 防多次点击


const checkEnter = ()=>{
  if(!isScoreTxt.value){
    let newSelect = [] //单选+多选
    newSelect = Object.values({...checkData.value,...radioData.value})
    //console.log(newSelect)
    for(let y=0;y<newSelect.length;y++){
      selectData.value.push(newSelect[y].split("_"))
    }
    //console.log(selectData.value)
    for(let s=0;s<selectData.value.length;s++){
      let selectID =  selectData.value[s][0] //用户答题id
      let selectTxt = '' //用户选择答案
      let daanTxt = '' //正确答案
      let enterTxt = '' //按后端要求格式化用户每次选择答案
      let find=0 //查找次数
      for(let i=0;i<selectData.value.length;i++){
        if(selectData.value[i][0] == selectID){
          selectTxt += selectData.value[i][1]
          enterTxt += selectData.value[i][1]+'_'
        }
      }
      for(let a=0;a<answerData.value.length;a++){
        if(answerData.value[a][0] == selectID){
          daanTxt += answerData.value[a][1]
        }
      }
      for(let x=0;x<scoreEnter.length;x++){
        if(selectID == scoreEnter[x][0]){
          find=1
        }
      }
      if(find ==0){
        let enter = [selectID,'-'+enterTxt]
        scoreEnter.push(enter)
        let index = '' //查找对应id的下标
        for(let q=0;q<questionData.value.length;q++){
          index = questionData.value.findIndex(item => item.id == selectID)
        }
        if(selectTxt.split("").sort().join("") == daanTxt.split("").sort().join("")){
          questionData.value[index].scoreTxt="正确"
        }else{
          questionData.value[index].scoreTxt=daanTxt
        }
      }
    }
    if(scoreEnter.length == questionData.value.length){
      isScoreTxt.value = true
      let enterData = []
      for(let u=0;u<scoreEnter.length;u++){
        enterData.push(scoreEnter[u].join("").slice(0,-1))
      }
      let params = {
       /*其他参数 category_id:proxy.$route.params.category_id,*/
        ti_str:enterData.toString(),
      }

      /*数据提交*/

        if(response.data.status == 1){
          showToast("答题提交成功!");
        }

      /*数据提交*/

    }else{
      showToast("回答完全部问题再提交答案哦!");
    }
  }else{
    showToast("校正及正确选项已显示,请换题再测!");
  }
}

//换题再测试
const checkChange = ()=>{
  questionData.value = undefined
  answerData.value = []
  radioData.value = []
  checkData.value = []
  selectData.value = []
  scoreEnter=[]
  getQuestion()

}


onBeforeMount(() => {
  getQuestion()

})

</script>

CSS:

.question li{background:#fff;padding:30px 20px 20px 20px;border-radius:10px;box-shadow:0 0 7px #ccc;border:1px solid #eaeaea;margin-bottom:40px;position:relative;}
.question li h6{position:absolute;right:20px;top:30px;}
.question li h6 b.daanErr{color:#e60000;}
.question li h6 b{color:#018407;}
.question li h5{border-left:4px solid #ff6e52;font-size:20px;font-weight:bold;padding-left:15px;margin-bottom:20px;}
.question li dt{padding:0 0 20px 20px;}
.question li dd{padding-right:50px;}
.question li label{display:line-block;position:relative;margin:0 20px 20px 0;padding-left:20px;}
.question li label span{border:1px solid #d0d0d0;border-radius:10px;padding:7px 20px;box-sizing:border-box;display:inline-block;line-height:26px;}
.question li label input{display:none;}
.question li label input:checked+span{background:#fffafa;z-index:2;color:#b80000;border:1px solid #b80000;border-radius:10px;}
.question li label span b{display:inline-block;font-weight:normal;margin-right:5px;}


.checkEnterBt{display:flex;justify-content:space-around;align-items:center;}
.checkEnterBt button{width:40%;background:#e60000;color:#fff;border:none;padding:20px 0;border-radius:10px;}
.checkEnterBt button:nth-child(2){background:#007ce6;}

解释:

数据里的答案为:A_B_C_D

需要校正展示的答案为:ABCD

提交数据的答案为:题目id-A_B_C_D

通过 :value="list.id+'_'+radio.name"  和  :value="list.id+'_'+checkbox.name" 将选中数据统一为题目id_选项

<input type="radio" :name="list.id" :value="list.id+'_'+radio.name" v-model="radioData[list.id]">


<input type="checkbox" :value="list.id+'_'+checkbox.name" v-model="checkData">

展开运算符(用于展开可迭代对象(如数组、字符串等)为独立的元素,或者用于将多个元素合并为一个数组或对象)+Object.values()(返回一个给定对象自己的所有可枚举属性值的数组将单选和多选数据选择数据合并到一个数组中,将原数据['题目id_选项值','题目id_选项值']格式化成[题目id,选项值],[题目id,选项值]

let newSelect = [] //单选+多选
newSelect = Object.values({...checkData.value,...radioData.value})
//格式化单选多选合并后的数据为[id,选项] 单选[id,A],多选[id,A],[id,C]
for(let y=0;y<newSelect.length;y++){
  selectData.value.push(newSelect[y].split("_"))
}

Vue3:一页多题答案提示及循环radio和checkbox混合使用,Millia's work,vue.js,javascript,前端

查找格式化数据中相同id的数据,比较格式化后的正确答案,比较正确,组合成提交答案要求的格式和校正展示的格式。文章来源地址https://www.toymoban.com/news/detail-745283.html

到了这里,关于Vue3:一页多题答案提示及循环radio和checkbox混合使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue3【列表渲染】v-for 详细介绍(vue中的“循环”)

    在本文之前已经有文章简单概要介绍过vue中的渲染,点击帮你快速复习👏👏,包括 条件渲染 和 列表渲染 。 二者同样重要,但是 对于项目而言,使用更多的是列表渲染,主要表现为“循环”。 下面让我们继续深入地了解列表渲染的相关内容吧~👏👏👏 我们可以使用 v-f

    2024年02月22日
    浏览(35)
  • vite vue3+ts @引入无提示/解决提示报错

    1. setting.json  这时候已经有提示了 但是ts会报错   tsconfig.json  以@开头代表src目录下 以#开头代表ts目录下  配置好后 重新引入 没有红色波浪线但是 vite不认识 @符号 运行项目还是会报错  这时候就需要在vite.config.ts中添加配置 如果path会报错 需要下载一下@types/node 再重启下

    2024年02月15日
    浏览(34)
  • Vue3 select循环多个,选项option不能重复被选

    环境 :vue3+ts+vite+element plus 实现目标 :Vue3 select循环多个,当其中一个option值被选后,其他select里面不能再重复选择该option值。第二种,当其中一个option值被选后,其他select里面就不出现被选option的值 第一种 :代码如下 效果: 第二种: 效果: 或者用script setup的写法 如果没

    2024年02月10日
    浏览(27)
  • Vue3 - 实现路由 “新开一页“ 进行页面跳转功能,Router 路由跳转时在新窗口打开页面(网站跳转页面时浏览器新开页签打开网页,支持在页面、纯 js/ts 文件中使用,详细示例代码教程)

    网上这方面教程很少,本文提供多种解决方案,适用于任何场景。 本文 实现了在 vue3 项目开发中,当页面跳转时浏览器打开新窗口(新页签)跳转,Router 路由跳转并新开一页教程, 无论您是在普通页面、纯 js/ts 文件中,都可以使用, 如下图所示,当执行路由跳转时浏览器

    2024年02月03日
    浏览(48)
  • 【实操】vue+element UI tab页多表单合并校验提交

    一个页面中tab栏切换多个form表单组件,只有一个保存按钮。需要把各组件下的表达数据合并校验提交。 父组件通过两次调用$refs获取子组件的dom元素以及组件内部form的dom元素。 通过循环表单项获取validate值获取校验结果,通过Promise.all合并表单。 子组件内部getData方法返回表

    2024年02月11日
    浏览(31)
  • vue3引入.vue文件以及.ts文件时提示找不到模块

    1.找不到vue文件的,是因为ts无法解析我们的vue结尾的文件,所以需要在src目录下, 新建一个d.ts结尾的文件(可以叫env.d.ts) 然后里面这样写就可以 2,找不到ts文件就更正常了,我们需要在tsconfig.json里面进行配置(没有的话就新建一个,在根src同级的目录下面)。就直接复制就

    2024年02月11日
    浏览(57)
  • 如何解决vue3.0+typescript项目提示找不到模块“./App.vue

    一、解决方案如下:需在项目目录下加上下面这段代码即可!如果没有vite-env.d.ts目录需要继续往下看 二、如果没有创建vite-env.d.ts这个文件,需要在和main.ts同级目录创建一个vite-env.d.ts文件,如图 创建好后,可能你没有tsconfig.json文件,那么你还要新创建一个tsconfig.json文件,

    2024年02月10日
    浏览(24)
  • vite+vue3+ts项目中提示无法找到模块

    今天在开发过程中碰到了导入模块时提示无法找到模块这个问题,分享一下我的解决思路 首先产生这个错误是: 无法找到模块XXX,并且提示\\\'XXX\\\' is declared but its value is never read 产生这个问题的原因是我们使用了ts语法,他只能识别.ts文件,并不能识别.vue文件,所以在引入组件

    2024年02月11日
    浏览(31)
  • vue3中使用codemirror6增加代码提示功能

    1、安装依赖 // 安装codemirror、语言包、主题、自动补全 本人安装的版本是 2、创建编辑器

    2024年02月15日
    浏览(33)
  • 解决vue3使用iconpark控制台预警提示问题

    最近在项目中使用 iconpark-icon 来管理图标,一切都很顺利,引入链接后,图标正常显示,没有报错。但是控制台却发出了预警信息。 [Vue warn]: Failed to resolve component: iconpark-icon If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement. 虽说不

    2024年02月04日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包