Realization effect
General idea
First, I want to judge the number of each question type queried in the interface, find the question type ID whose count is not zero, and it appears first. I won't enter it after query, and then query and render the question
resolvent
At the beginning, I thought about how to change the activeName of the tabs tab to the first place with value
First, I cycle the data obtained from the topic set type interface, and then change the value
The code is as follows:
// Get the list of topic types under the topic set async getTypeList() { const data = await api.getTopicSetTypeList.getTopicSetTypeList({ topicSetId: this.$route.query.topicSetId, }) for (let i = 0; i < data.data.length; i++) { /** * Judge the first one that is not empty and modify the activeName */ if (data.data[i].count !== 0 && this.judgeTabs === 0) { data.data[i].topicTypeId -= 1; this.activeName = data.data[i].topicTypeId.toString() this.getTopicList(data.data[i].topicTypeId) this.judgeTabs = 1 } } this.topSetTypeList = data.data },
Variables defined for me by judgeTabs
Because in the tabs tab, the entire page is in the same vue file, and there will be no re refresh
But changed here, but found that the user experience is poor
Click confirm every time you enter the page, which is illogical and makes users feel inexplicable
Then when I went to explore the code, I found that the confirm pop-up window could only appear in one place, but I clearly made restrictions in that place
The code is as follows:
// tabs switching leaveTab() { if(this.judgeCount !== 0){ let a = confirm('Are you sure you want to leave this question type?') if (a) { console.log('confirm') return true } else { console.log('cancel') return false } } else { this.judgeCount = 1; } },
So I guess, called twice!!!
Because at the beginning, the judgeCount can only be 0, and the value will not change until this method is called once
Print it, as expected
console.log("Did I call this twice??"); console.log("Maybe activeName Twice?",this.activeName);
At the beginning, this method will also be called when assigning the default activename: 0, that is, enter the page from the first
Because every time you query where the first type of topic is, you only modify the activeName once, and then initialize it once, only twice
Amend as follows:
// tabs switching leaveTab() { console.log("Did I call this twice??"); /** * Because I called it in the created method. * getTypeList First value found in * Changed twice, so > = 2 is enough */ console.log("Maybe activeName Twice?",this.activeName); if (this.judgeCount >= 2 ) { let a = confirm('Are you sure you want to leave this question type?') if (a) { console.log('confirm') return true } else { console.log('cancel') return false } } else { this.judgeCount ++; } },
So far, the function has been realized. The above ideas are only for reference and need to be combined with practice
Paste the complete code
<template> <div> <div> <el-tabs v-model="activeName" :before-leave="leaveTab"> <el-tab-pane v-for="item in topSetTypeList" :label="item.typeDescription" :name="item.index" :key="item.index" :disabled="item.count === 0" @click="sendTopicList()" > <oj-topic-judge v-if="item.topicTypeId === 1" :topicList="topicList" :showValue="haveTopicOrNot" :endState="endState && haveTopicOrNot" :judgeData="judgeData" ></oj-topic-judge> <oj-topic-single v-if="item.topicTypeId === 2" :topicList="topicList" :showValue="endState" :selectData="selectData" ></oj-topic-single> <oj-topic-mult-radio v-if="item.topicTypeId === 3" :topicList="topicList" :showValue="endState" :multAnswerList="multAnswerList" ></oj-topic-mult-radio> <oj-topic-blank v-if="item.topicTypeId === 4" :topicList="topicList" :qtopicsetId="qtopicsetId" :eachBlankNum="eachBlankNum" :startIndex="startIndex" :showValue="endState" :preBlankAnswer="preBlankAnswer" ></oj-topic-blank> </el-tab-pane> </el-tabs> </div> </div> </template> <script> import { questionTypeInfo } from '@/components/comTopicSet/topicSetJs/topicSet.js' import ojTopicHeader from '@/components/comTopic/ojTopicHeader.vue' import showJudge from '@/components/comTopic/baseShow/showJudge.vue' import showMultRadio from '@/components/comTopic/baseShow/showMultRadio.vue' import showPack from '@/components/comTopic/baseShow/showPack.vue' import showRadio from '@/components/comTopic/baseShow/showRadio.vue' import api from 'api' import marked from 'marked' import OjTopicSingle from '../comMakeQuestion/ojTopicSingle.vue' import OjTopicMultRadio from '../comMakeQuestion/ojTopicMultRadio.vue' import OjTopicJudge from '../comMakeQuestion/ojTopicJudge.vue' import OjTopicBlank from '../comMakeQuestion/ojTopicBlank.vue' import { topic } from '../comTopic/const' export default { components: { ojTopicHeader, showJudge, showMultRadio, showPack, showRadio, OjTopicSingle, OjTopicMultRadio, OjTopicJudge, OjTopicBlank, }, props: ['url', 'questionId', 'dataType', 'answerStyle'], data() { return { haveTopicOrNot: false, activeName: 0, questionTypeInfo, isShow: true, endState: true, publicStatus: window.localStorage.getItem('status'), // dataType:[], topicList: [], topSetTypeList: [], showPackList: false, qtopicsetId: [], eachBlankNum: [], topicSetId: this.$route.query.topicSetId, topicTypeIdTemp: '', startIndex: 1, judgeCount: 0, multAnswerList: [], judgeData: [], answerList: [], selectData: [], str: "<input class='testBlank' type='text' style='height:28px' >", preBlankAnswer: [], judgeTabs: 0, } }, watch: { activeName: function (val) { this.getTypeList() this.getTopicList(val) this.endStateCheck() }, }, created() { this.getTypeList() this.endStateCheck() }, filters: { topic_fraction(list) { let fraction = 0 list.forEach((e) => { fraction += e.topicFraction }) return fraction }, }, methods: { // tabs switching leaveTab() { console.log("Did I call this twice??"); /** * Because I called it in the created method. * getTypeList First value found in * Changed twice, so > = 2 is enough */ console.log("Maybe activeName Twice?",this.activeName); if (this.judgeCount >= 2 ) { let a = confirm('Are you sure you want to leave this question type?') if (a) { console.log('confirm') return true } else { console.log('cancel') return false } } else { this.judgeCount ++; } }, /* End */ async endStateCheck() { const data = await api.queryTopicSetInfo.queryTopicSetInfo({ topicSetId: this.$route.query.topicSetId, }) if ( data.data.status === 'Has ended' && window.localStorage.getItem('accountTypeId') !== '3' ) { this.endState = false } }, // Get the list of topic types under the topic set async getTypeList() { const data = await api.getTopicSetTypeList.getTopicSetTypeList({ topicSetId: this.$route.query.topicSetId, }) for (let i = 0; i < data.data.length; i++) { /** * Judge the first one that is not empty and modify the activeName */ if (data.data[i].count !== 0 && this.judgeTabs === 0) { data.data[i].topicTypeId -= 1; this.activeName = data.data[i].topicTypeId.toString() this.getTopicList(data.data[i].topicTypeId) this.judgeTabs = 1 } } this.topSetTypeList = data.data }, async getTopicList(val) { let topicTypeId = val this.topicTypeIdTemp = topicTypeId topicTypeId = parseInt(topicTypeId) + 1 if (topicTypeId === 6) { this.showPackList = true } else { this.showPackList = false } const data = await api.showTopicList.showTopicList({ topicSetId: parseInt(this.$route.query.topicSetId), topicTypeId: topicTypeId, }) if (topicTypeId === 3 && this.multAnswerList.length == 0) { data.data.forEach((item) => { this.multAnswerList.push({ qtopicsetId: item.qTopicSetId, answer: [], }) }) } this.showAnswerList(topicTypeId) /** * Operational blank filling questions */ if (topicTypeId === 4) { for (let i = 0; i < data.data.length; i++) { let changeBlank = data.data[i].topicDescription.split('') for (let j = 0; j < data.data[i].fillInfo.length; j++) { changeBlank[data.data[i].fillInfo[j].fillIndex] = this.str + '[' + data.data[i].fillInfo[j].fillFraction + 'branch]' } // console.log('ok? ', changeBlank) changeBlank = changeBlank.join('') data.data[i].topicDescription = changeBlank.toString() this.qtopicsetId[i] = data.data[i].qTopicSetId this.eachBlankNum[i] = data.data[i].fillInfo.length } } if (topicTypeId !== 4) { data.data.forEach((item) => { item.topicDescription = marked(item.topicDescription) }) } this.topicList = data.data this.sendTopicList() }, /** * description Answer echo */ async showAnswerList(topicTypeId) { const data = await api.userObjectAnswer.userObjectAnswer({ topicSetId: this.$route.query.topicSetId, topicTypeId: topicTypeId, accountId: window.localStorage.getItem('accountId'), }) this.answerList = data.data if (topicTypeId === 3) { this.answerList.forEach((item, index) => { let answer = [] item.topicAnswer.forEach((ans) => { answer.push(ans.answer) }) this.multAnswerList[index].answer = answer }) } else if (topicTypeId === 1) { this.answerList.forEach((item, index) => { item.topicAnswer.forEach((ans) => { if (ans.answer === '0' || ans.answer === '1') { this.judgeData.push(ans.answer) } else { this.judgeData.push('') } }) }) } else if (topicTypeId === 2) { let anslist = [] this.answerList.forEach((item, index) => { item.topicAnswer.forEach((ans) => { anslist.push(ans.answer) }) }) this.selectData = anslist } else if (topicTypeId === 4) { this.preBlankAnswer = data.data } }, async sendTopicList() { //Transfer TopicList to the parent component topicSetDetail.vue file let topicData = {} topicData.topicTypeId = this.topicTypeIdTemp if (this.topicTypeIdTemp !== 4) { topicData.topicList = this.topicList } else topicData.topicList = await api.showTopicList.showTopicList({ topicSetId: parseInt(this.$route.query.topicSetId), topicTypeId: this.topicTypeIdTemp, }) this.$emit('topicListTransfer', topicData) }, linkTo(val) { this.$router.push({ path: 'makeQuestion', query: { topicId: val.topicId, topicSetId: this.$route.query.topicSetId, topicTypeId: val.topicTypeId, }, }) }, }, } </script> <style lang="less" scoped> .topic-set-topic-list { font-size: 14px; .answer { width: 90%; padding: 10px 20px; background-color: #f5f7fa; margin: auto auto; } .answer2 { width: 90%; padding: 10px 20px; background-color: #f5f7fa; margin: auto auto; display: none; } #topic { margin: 10px; } a { cursor: pointer; } } .questionTypeNav { position: absolute; height: 0.7%; width: 63%; /* background-color: red; */ } </style>