tabs to achieve dynamic data switching

Keywords: Javascript node.js Vue.js elementUI

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>

Posted by Fergusfer on Wed, 13 Oct 2021 21:05:13 -0700