textReplaceIcon.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. <template>
  2. <view v-html="formattedText" :myflag="myflag" :question="question" @click.native="handleClick"
  3. :change:myflag="YY.updateFlag" :change:question="YY.watchQuestionChange"></view>
  4. </template>
  5. <script>
  6. import { debounce } from '@/utils/common';
  7. export default {
  8. props: {
  9. placeholders: { // 占位符
  10. type: Array,
  11. required: true
  12. },
  13. text: {
  14. type: String,
  15. },
  16. showError: {
  17. type: Boolean,
  18. default: false
  19. },
  20. question: {
  21. type: Object,
  22. },
  23. },
  24. data() {
  25. return {
  26. myflag: 0,
  27. isplaying: null,
  28. num: 0,
  29. }
  30. },
  31. computed: {
  32. // 计算属性,用于生成填空后的文本
  33. formattedText() {
  34. let result = this.text;
  35. this.placeholders.forEach((placeholder, index) => {
  36. // 使用正则表达式全局替换占位符
  37. const regex = new RegExp(`\\${placeholder}`, 'g');
  38. if (!this.isplaying) {
  39. result = result.replace(regex,
  40. `<view class="yy-box"><view class="yingyu-canplay-img" id="t_${this.question.stId}_${index}">【图片1】</view></view>`
  41. );
  42. } else if (this.question.stId == this.isplaying.stId && this.isplaying.index == index) {
  43. result = result.replace(regex,
  44. `<view class="yy-box"><view class="yingyu-playing-img" id="t_${this.question.stId}_${index}">【图片2】</view></view>`
  45. );
  46. } else {
  47. result = result.replace(regex,
  48. `<view class="yy-box"><view class="yingyu-canplay-img" id="t_${this.question.stId}_${index}">【图片1】</view></view>`
  49. );
  50. }
  51. });
  52. this.myflag++;
  53. return result;
  54. },
  55. },
  56. methods: {
  57. handleClick() {
  58. this.$emit('@itemclick')
  59. },
  60. audioClick(data) {
  61. if (this.isplaying) {
  62. uni.$emit('do-yy-audio-stop', data);
  63. return;
  64. }
  65. // 重复播放
  66. if (this.isplaying && data.stId == this.isplaying.stId && data.index == this.isplaying.index) {
  67. uni.$emit('do-yy-audio-stop', data);
  68. return;
  69. }
  70. // 初次播放
  71. if (!this.isplaying) {
  72. uni.$emit('do-yy-audio-play', data);
  73. return;
  74. }
  75. }
  76. },
  77. created() {
  78. // 音频播放
  79. uni.$on('yy-audio-playing',(data) => {
  80. console.log('ccc1')
  81. if (this.isplaying) {
  82. // 存在播放实例 并且播放非同一音频
  83. if (this.isplaying.stId != data.value.stId) {
  84. this.isplaying = null;
  85. }
  86. } else {
  87. // 不存在播放实例
  88. this.isplaying = data;
  89. }
  90. })
  91. // 音频异常 重置音频
  92. uni.$on('yy-audio-error',(data) => {
  93. this.isplaying = null;
  94. })
  95. // 音频自然播放结束 重置音频
  96. uni.$on('yy-audio-end',(data) => {
  97. this.isplaying = null;
  98. })
  99. // 音频销毁 重置音频
  100. uni.$on('destory-stop',(data) => {
  101. this.isplaying = null;
  102. })
  103. // 试题切换 重置音频
  104. uni.$on('swiper-change',() => {
  105. this.isplaying = null;
  106. })
  107. // 解析关闭 重置音频
  108. uni.$on('question-jiexi-close',() => {
  109. this.isplaying = null;
  110. })
  111. uni.$on('unitTest-submit',() => {
  112. this.isplaying = null;
  113. })
  114. }
  115. }
  116. </script>
  117. <script module="YY" lang="renderjs">
  118. import {debounce} from "@/utils/common.js"
  119. export default {
  120. props: {
  121. showError: {
  122. type: Boolean,
  123. default: false
  124. },
  125. placeholders: { // 占位符
  126. type: Array,
  127. required: true
  128. },
  129. },
  130. data() {
  131. return {
  132. myQ: null,
  133. callbacks: []
  134. }
  135. },
  136. methods: {
  137. updateFlag() {
  138. this.initListener(this.myQ)
  139. },
  140. updateFn({stId,index}) {
  141. const url = this.myQ.audioList[index]
  142. this.$ownerInstance.callMethod('audioClick', {stId,index,url});
  143. },
  144. watchQuestionChange(newValue, oldValue, ownerInstance, instance) {
  145. if (newValue) {
  146. this.myQ = newValue;
  147. this.initListener(newValue)
  148. }
  149. },
  150. initListener(question) {
  151. if (!question) {
  152. return;
  153. }
  154. if (this.showError) {
  155. return;
  156. }
  157. question.placeholders.forEach((item, index) => {
  158. const dom = document.getElementById(`t_${question.stId}_${index}`)
  159. if (dom) {
  160. const qaindex = this.callbacks.findIndex(item => item.index === index)
  161. if (qaindex>-1) {
  162. dom && dom.removeEventListener('click', this.callbacks[qaindex].callback);
  163. this.callbacks = this.callbacks.filter(item => item.index !=qaindex);
  164. }
  165. const callbackFn = debounce(() => { this.updateFn({ stId: question.stId, index})},100)
  166. this.callbacks.push({index: index, callback: callbackFn
  167. })
  168. dom && dom.addEventListener('click', this.callbacks.find(cIte => cIte.index === index).callback)
  169. }
  170. })
  171. },
  172. },
  173. }
  174. </script>
  175. <style>
  176. </style>