FillPreview.vue 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. <!-- eslint-disable vue/no-v-html -->
  2. <template>
  3. <div class="fill-preview">
  4. <div class="stem">
  5. <span class="question-number">{{ data.property.question_number }}.</span>
  6. <span v-html="sanitizeHTML(data.stem)"></span>
  7. </div>
  8. <div v-if="isEnable(data.property.is_enable_description)" class="description">{{ data.description }}</div>
  9. <AudioPlay
  10. v-if="isEnable(data.property.is_enable_listening) && data.file_id_list.length > 0"
  11. :file-id="data.file_id_list[0]"
  12. />
  13. <div class="fill-wrapper">
  14. <p v-for="(item, i) in data.model_essay" :key="i">
  15. <template v-for="(li, j) in item">
  16. <span v-if="li.type === 'text'" :key="j" v-html="sanitizeHTML(li.content)"></span>
  17. <el-input v-if="li.type === 'input'" :key="j" v-model="li.content" @blur="handleTone(li.content, i, j)" />
  18. </template>
  19. </p>
  20. </div>
  21. </div>
  22. </template>
  23. <script>
  24. import PreviewMixin from './components/PreviewMixin';
  25. import { addTone } from '@/views/exercise_questions/data/common';
  26. import { handleToneValue } from '@/views/exercise_questions/data/fill';
  27. export default {
  28. name: 'FillPreview',
  29. mixins: [PreviewMixin],
  30. data() {
  31. return {};
  32. },
  33. watch: {
  34. 'data.model_essay': {
  35. handler(val) {
  36. if (!val) return;
  37. this.answer.answer_list = val
  38. .map((item) => {
  39. return item
  40. .map(({ type, content, mark }) => {
  41. if (type === 'input') {
  42. return {
  43. value: content,
  44. mark,
  45. };
  46. }
  47. })
  48. .filter((item) => item);
  49. })
  50. .flat();
  51. },
  52. deep: true,
  53. immediate: true,
  54. },
  55. },
  56. methods: {
  57. handleTone(value, i, j) {
  58. if (!/^[a-zA-Z0-9\s]+$/.test(value)) return;
  59. this.data.model_essay[i][j].content = value
  60. .trim()
  61. .split(/\s+/)
  62. .map((item) => {
  63. return handleToneValue(item);
  64. })
  65. .map((item) =>
  66. item.map(({ number, con }) => (number && con ? addTone(Number(number), con) : number || con || '')),
  67. )
  68. .filter((item) => item.length > 0)
  69. .join(' ');
  70. },
  71. },
  72. };
  73. </script>
  74. <style lang="scss" scoped>
  75. @use '@/styles/mixin.scss' as *;
  76. .fill-preview {
  77. @include preview;
  78. .fill-wrapper {
  79. .el-input {
  80. width: 120px;
  81. margin: 0 2px;
  82. :deep input.el-input__inner {
  83. padding: 0;
  84. font-size: 16px;
  85. color: $font-color;
  86. text-align: center;
  87. background-color: #fff;
  88. border-width: 0;
  89. border-bottom: 1px solid $font-color;
  90. border-radius: 0;
  91. }
  92. }
  93. }
  94. }
  95. </style>