Questions.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <template>
  2. <view
  3. class="question-item"
  4. :class="{
  5. 'question-item-correct': mode === 'practice' && isSelected && isCorrect,
  6. 'question-item-wrong': mode === 'practice' && isSelected && !isCorrect,
  7. 'question-item-selected': mode === 'exam' && isSelected
  8. }"
  9. @tap="handleClick"
  10. >
  11. <view
  12. class="option-label"
  13. :class="{
  14. 'option-label-correct': mode === 'practice' && isSelected && isCorrect,
  15. 'option-label-wrong': mode === 'practice' && isSelected && !isCorrect,
  16. 'option-label-selected': mode === 'exam' && isSelected
  17. }"
  18. >
  19. {{ TopicMapList[index] }}
  20. </view>
  21. <view class="option-text">{{ question.label }}</view>
  22. <view class="option-icon" v-if="isSelected && !isCorrect">
  23. <uni-icons type="closeempty" color="#f00"></uni-icons>
  24. </view>
  25. <view class="option-icon" v-if="isSelected && isCorrect">
  26. <uni-icons type="checkmarkempty" color="#00be00"></uni-icons>
  27. </view>
  28. </view>
  29. </template>
  30. <script setup>
  31. import { computed } from "vue";
  32. const TopicMapList = ["A", "B", "C", "D", "E"];
  33. // Props 定义
  34. const props = defineProps({
  35. answerList: {
  36. type: Array,
  37. default: () => [],
  38. },
  39. index: {
  40. type: Number,
  41. required: true,
  42. },
  43. selectCount: {
  44. type: Array,
  45. default: () => [],
  46. },
  47. question: {
  48. type: Object,
  49. required: true,
  50. default: () => ({
  51. label: "",
  52. value: 0,
  53. }),
  54. },
  55. parindex: {
  56. type: Number,
  57. required: true,
  58. },
  59. mode: {
  60. type: String,
  61. default: "exam", // practice: 练习模式, exam: 考试模式
  62. },
  63. });
  64. // Emits 定义
  65. const emit = defineEmits(["select", "showAnswer"]);
  66. // 计算属性
  67. const isSelected = computed(() =>
  68. props.selectCount.includes(props.question.value)
  69. );
  70. const isCorrect = computed(() =>
  71. props.answerList.includes(props.question.value)
  72. );
  73. // 方法
  74. const handleClick = () => {
  75. // 如果已经选中,则取消选择
  76. if (isSelected.value) {
  77. emit("select", props.question.value, props.parindex);
  78. return;
  79. }
  80. // 如果是练习模式,且已经达到答案数量,则不允许继续选择
  81. if (props.mode === 'practice' && props.selectCount.length === props.answerList.length) {
  82. return;
  83. }
  84. // 如果是练习模式,且即将完成所有选择,则显示答案
  85. if (props.mode === 'practice' && props.answerList.length - 1 === props.selectCount.length) {
  86. emit("showAnswer", true);
  87. }
  88. emit("select", props.question.value, props.parindex);
  89. };
  90. </script>
  91. <style lang="scss" scoped>
  92. @import "@/uni.scss";
  93. .question-item {
  94. display: flex;
  95. padding: 0 16px;
  96. height: 76rpx;
  97. border: 1px solid #ccc;
  98. border-radius: 8px;
  99. background-color: #FAFBFD;
  100. gap: 12px;
  101. align-items: center;
  102. color: #333;
  103. }
  104. .question-item-correct {
  105. border-color: $success;
  106. background-color: #e8f5e9;
  107. }
  108. .question-item-wrong {
  109. border-color: $error;
  110. background-color: #ffebee;
  111. }
  112. .question-item-selected {
  113. border-color: $uni-primary;
  114. background-color: #e3f2fd;
  115. }
  116. .option-label {
  117. border: 1px solid #ccc;
  118. border-radius: 50%;
  119. padding: 0 5px;
  120. }
  121. .option-label-correct {
  122. border-color: $success;
  123. background-color: $success;
  124. color: #fff;
  125. }
  126. .option-label-wrong {
  127. border-color: $error;
  128. background-color: $error;
  129. color: #fff;
  130. }
  131. .option-label-selected {
  132. border-color: $uni-primary;
  133. background-color: $uni-primary;
  134. color: #fff;
  135. }
  136. .option-text {
  137. flex: 1;
  138. }
  139. </style>