Vue脚手架实现试卷页面

1,606 阅读1分钟

页面

store/modules/moduleA

  • 将moduleA中的store模块化
  • 在state中放入变量subjectList,通过mutations更新subjectList
  • 在Home.vue中通过mapMutations激活mutations中的getSubjectList,从而更新subjectList
import '@/mock'
export default {
    namespaced: true,
    state: {
        subjectList: []
    },
    mutations: {
        getSubjectList(state, payload) {
            state.subjectList = payload
        }
    }
}

store/index.js

import Vuex from 'vuex'
import Vue from 'vue'
Vue.use(Vuex)
import user from './modules/user'
import moduleA from './modules/moduleA'
let store =new Vuex.Store({
    modules:{
        moduleA
    }
})
export default store

Home.vue

  • fmtSubjectType,fmtOrder2ABC为过滤器,checkSubjectType为方法,统一放在Vue.mixin中,保存在mixin中的index.js文件中
  • 通过checkSubjectType方法的结果真假控制此div是否存在
<template>
  <div class="main">
    <ul>
      <li class="item" v-for="(item, i) in subjectList" :key="i">
        <h4>{{i+1}}.[{{item.type|fmtSubjectType}}] {{item.title}}</h4>
        <div style="color:#888;font-size:14px">
          {{item.author}}{{item.createDate}}
        </div>
        <fieldset style="padding:0 10px;" v-if="checkSubjectType(item.type)">
          <legend >选项</legend>
          <div v-for="(choice, j) in item.choice" :key="j">
            {{j|fmtOrder2ABC}}  {{choice.answer}}
          </div>
        </fieldset>
        <div v-if="checkSubjectType(item.type)">答案:{{item.answer}}</div>
        <div >解析:{{item.desc}}</div>
      </li>
    </ul>
  </div>
</template>

<script>
import '@/mock'
import {createNamespacedHelpers} from 'vuex'
let {mapState,mapMutations,mapActions}= createNamespacedHelpers('moduleA')
export default {
  async created() {
    let {subjectList} = await this.$get('/subjectList')
    this.getSubjectList(subjectList)   
  },
  computed: {
    ...mapState(['subjectList'])
  },
  methods: {
    ...mapMutations(['getSubjectList']),
  }
};
</script>

<style scoped lang='scss'>
.main{
  border: 1px solid red;
  .item{
    padding: 20px 10px;
    border-bottom: 1px solid #ccc;
  }
}
</style>

mixin/index.js

  • 通过切换BASE_URL来切换接口,axios中的url是通过BASE_URL拼接的
import axios from 'axios'
import Vue from 'vue'
import { BASE_URL } from '@/config'
import {SUBJECT_TYPE} from '@/config/enum'
Vue.mixin({
    methods: {
       async $get(url,params){
           let {data} = await axios.get(BASE_URL+url,{params})
            return data
        },
        checkSubjectType(type){
            return type===SUBJECT_TYPE.DANXUAN||type===SUBJECT_TYPE.DUOXUAN
        }
    },
    filters:{
        fmtSubjectType(val){
            return ['单选题', '多选题', '判断题', '简答题'][val]
        },
        fmtOrder2ABC(val) {
            return 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[val]
        }
    },
    data() {
        return {
            SUBJECT_TYPE
        }
    },
})

config/index.js

  • 通过MODE的改变,更换接口
import {MODE_TYPE} from './enum'
const BASE_URL_BEF=''
const BASE_URL_PRO='XXX'
const BASE_URL_DEV='PPPP'
const MODE=MODE_TYPE.BEF
export const BASE_URL = [BASE_URL_BEF,BASE_URL_PRO,BASE_URL_DEV][MODE]

config/enum.js

  • 鉴于魔法数字的缘故,通过如下,使代码更清晰
//枚举
export const MODE_TYPE={
    BEF:0,
    PRO:1,
    DEV:2
}
export const SUBJECT_TYPE={
    DANXUAN:0,
    DUOXUAN:1,
    PANDUAN:2,
    JIANDA:3
}

mock/index.js

  • 通过mock伪造数据
import Mock from 'mockjs'
Mock.mock('/subjectList',{
    "subjectList|10":[
        {
            "id|+1": 1,
            "title": "@cword(5,10)",
            "type": "@integer(0,3)",
            author:"@cname",
            createDate:'@datetime',
            "choice": [
                {
                    "id": 11,
                    "choice": "A",
                    "answer": 0
                },
                {
                    "id": 12,
                    "choice": "B",
                    "answer": 1
                },
                {
                    "id": 13,
                    "choice": "C",
                    "answer": 2
                },
                {
                    "id": 14,
                    "choice": "D",
                    "answer": 3
                }
            ],
            "answer": "C",
            desc:'@cword(8,25)'
        }
    ]
})

页面效果