ElemFillQuestion.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. <template>
  2. <div :class="classes">
  3. <div class="elem-title" v-if="isFirstSpin">
  4. {{ data.parent.topicName }}
  5. </div>
  6. <div class="elem-body">
  7. <ul
  8. class="group-item"
  9. v-for="(group, gindex) in questions"
  10. :key="gindex"
  11. :style="gindex !== questions.length - 1 ? groupGapStyles : null"
  12. >
  13. <li
  14. class="question-item"
  15. v-for="(question, qindex) in group"
  16. :key="qindex"
  17. :style="getQuestionGapStyles(group, qindex)"
  18. >
  19. <span
  20. class="option-item"
  21. v-for="(option, oindex) in question"
  22. :key="oindex"
  23. :style="optionGapStyles"
  24. >
  25. <i>{{ option }}</i>
  26. </span>
  27. </li>
  28. </ul>
  29. </div>
  30. </div>
  31. </template>
  32. <script>
  33. export default {
  34. name: "elem-fill-question",
  35. props: {
  36. data: {
  37. type: Object,
  38. },
  39. },
  40. computed: {
  41. isFirstSpin() {
  42. return (
  43. this.data.parent &&
  44. this.data.startNumber === this.data.parent.startNumber
  45. );
  46. },
  47. classes() {
  48. return [
  49. "elem-fill-question",
  50. `elem-fill-question-${this.data.optionDirection}`,
  51. {
  52. "elem-fill-question-simple":
  53. !this.data.isMultiply && !this.data.isBoolean,
  54. "elem-fill-question-multiply": this.data.isMultiply,
  55. "elem-fill-question-boolean": this.data.isBoolean,
  56. "elem-fill-question-first": this.isFirstSpin,
  57. },
  58. ];
  59. },
  60. groupGapStyles() {
  61. return {
  62. marginRight: this.data.groupGap + "px",
  63. };
  64. },
  65. optionGapStyles() {
  66. const styles =
  67. this.data.optionDirection === "vertical"
  68. ? { marginBottom: this.data.optionGap + "px" }
  69. : { marginRight: this.data.optionGap + "px" };
  70. return styles;
  71. },
  72. },
  73. data() {
  74. return {
  75. questions: [],
  76. };
  77. },
  78. methods: {
  79. parseQuestion(data) {
  80. let questionNo = data.startNumber;
  81. let questions = [];
  82. const choiceList = this.getChoiceList(data);
  83. if (data.questionDirection === "vertical") {
  84. const groupNum = Math.ceil(
  85. data.questionsCount / data.questionCountPerGroup
  86. );
  87. for (let i = 0; i < groupNum; i++) {
  88. questions[i] = [];
  89. const questionCountPerGroup =
  90. i === groupNum - 1
  91. ? data.questionsCount - data.questionCountPerGroup * i
  92. : data.questionCountPerGroup;
  93. for (let j = 0; j < questionCountPerGroup; j++) {
  94. questions[i][j] = [questionNo++, ...choiceList];
  95. }
  96. }
  97. } else {
  98. for (let i = 0; i < data.questionsCount; i++) {
  99. const groupIndex = i % data.groupPerLine;
  100. if (!questions[groupIndex]) questions[groupIndex] = [];
  101. questions[groupIndex].push([questionNo++, ...choiceList]);
  102. }
  103. }
  104. this.questions = questions;
  105. },
  106. getChoiceList(data) {
  107. if (data.isBoolean) {
  108. return ["", ""];
  109. } else {
  110. return "abcdefghijklmnopqrstuv"
  111. .toUpperCase()
  112. .slice(0, data.optionCount)
  113. .split("");
  114. }
  115. },
  116. getQuestionGapStyles(group, qindex) {
  117. const size =
  118. group.length - 1 === qindex
  119. ? 0
  120. : this.data.optionDirection === "vertical"
  121. ? this.data.optionGap
  122. : this.data.questionGap;
  123. return this.data.optionDirection === "vertical"
  124. ? { marginRight: size + "px" }
  125. : { marginBottom: size + "px" };
  126. },
  127. },
  128. watch: {
  129. data: {
  130. immediate: true,
  131. handler(val) {
  132. this.parseQuestion(val);
  133. },
  134. },
  135. },
  136. };
  137. </script>