ElemFillQuestion.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. <template>
  2. <div :class="classes">
  3. <div v-if="isFirstSpin" class="elem-title" :style="nameStyles">
  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. nameStyles() {
  73. return {
  74. fontWeight: this.data.parent.nameFontWeight,
  75. fontSize: this.data.parent.nameFontSize,
  76. };
  77. },
  78. },
  79. data() {
  80. return {
  81. questions: [],
  82. };
  83. },
  84. methods: {
  85. parseQuestion(data) {
  86. let questionNo = data.startNumber;
  87. let questions = [];
  88. const choiceList = this.getChoiceList(data);
  89. if (data.questionDirection === "vertical") {
  90. const groupNum = Math.ceil(
  91. data.questionsCount / data.questionCountPerGroup
  92. );
  93. for (let i = 0; i < groupNum; i++) {
  94. questions[i] = [];
  95. const questionCountPerGroup =
  96. i === groupNum - 1
  97. ? data.questionsCount - data.questionCountPerGroup * i
  98. : data.questionCountPerGroup;
  99. for (let j = 0; j < questionCountPerGroup; j++) {
  100. questions[i][j] = [questionNo++, ...choiceList];
  101. }
  102. }
  103. } else {
  104. for (let i = 0; i < data.questionsCount; i++) {
  105. const groupIndex = i % data.groupPerLine;
  106. if (!questions[groupIndex]) questions[groupIndex] = [];
  107. questions[groupIndex].push([questionNo++, ...choiceList]);
  108. }
  109. }
  110. this.questions = questions;
  111. },
  112. getChoiceList(data) {
  113. if (data.isBoolean) {
  114. return ["", ""];
  115. } else {
  116. return "abcdefghijklmnopqrstuv"
  117. .toUpperCase()
  118. .slice(0, data.optionCount)
  119. .split("");
  120. }
  121. },
  122. getQuestionGapStyles(group, qindex) {
  123. const size =
  124. group.length - 1 === qindex
  125. ? 0
  126. : this.data.optionDirection === "vertical"
  127. ? this.data.optionGap
  128. : this.data.questionGap;
  129. return this.data.optionDirection === "vertical"
  130. ? { marginRight: size + "px" }
  131. : { marginBottom: size + "px" };
  132. },
  133. },
  134. watch: {
  135. data: {
  136. immediate: true,
  137. handler(val) {
  138. this.parseQuestion(val);
  139. },
  140. },
  141. },
  142. };
  143. </script>