xuePage.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <!-- 单词区 && 音标区:最多14位,超过换行 词根助记区:宽度不限,可以滚动-->
  2. <!-- 单音节最长:swimming 多音节最长:transportation -->
  3. <template>
  4. <view class="ezy-tab-border">
  5. <view class="ezy-border-body">
  6. <selectTypesVue activeSelect="1"></selectTypesVue>
  7. <view class="words-xue-box">
  8. <view class="words-xue-body">
  9. <!-- 单词区 -->
  10. <view class="word-circle-box">
  11. <text v-for="(item,index) in activeWord.chaifen" :key="index">{{item}}</text>
  12. </view>
  13. <view class="word-block-box">
  14. <text v-for="(item,index) in activeWord.chaifen" :key="index">{{item}}</text>
  15. </view>
  16. <!-- 音标区 -->
  17. <view class="yb-play-box xue-yb-play-box">
  18. <yinbiaoTxtVue :yinbiao="activeWord.yinbiao"></yinbiaoTxtVue>
  19. <!-- 音频播放 -->
  20. <audioTwoVue :active-word="activeWord" @play-audio="handlePlay"></audioTwoVue>
  21. </view>
  22. <!-- 注释区 -->
  23. <view class="pin-words-explain-box xue-words-explain-box">
  24. <view class="words-explain-item" v-for="item in activeWord.jianyi" :key="item">{{item}}</view>
  25. </view>
  26. <!-- 详解触发 -->
  27. <view @click="goXiangjie" class="details-btn">详解 ></view>
  28. <!-- 音标拆分区 -->
  29. <view v-show="data.isPindu" class="word-block-box yb-block-box">
  30. <!-- pindu -->
  31. <audioThreeVue v-for="(item,index) in activeWord.pindu" :key="index" :YItem="item"
  32. @play-audio="handlePlay"></audioThreeVue>
  33. </view>
  34. <view v-show="!data.isPindu" class="yj-block-box">
  35. <!-- yinjie -->
  36. <audioFourVue v-for="(item,index) in activeWord.yinjie" :key="index" :YItem="item"
  37. @play-audio="handlePlay"></audioFourVue>
  38. </view>
  39. <!-- 音标按钮 -->
  40. <view class="xue-change-btn-box">
  41. <view class="change-btn" :class="{active: !data.isPindu}" @click="handlePindu"><text>自然拼读</text></view>
  42. <view class="change-btn" :class="{active: data.isPindu}" @click="handleYinjie"><text>音节拆分</text></view>
  43. </view>
  44. <!-- 词根+实用口语 -->
  45. <view v-if="activeWord.cigenzhuji.length" class="details-content-box xue-details-content-box">
  46. <text class="details-title">词根助记</text>
  47. <scroll-view class="cg-item-list" scroll-x @touchmove.stop>
  48. <view class="cg-item-box" v-for="(item,index) in activeWord.cigenzhuji" :key="index">
  49. <view class="cg-item">
  50. <view
  51. :class="{isEven: index% 2 !== 0 && index!==activeWord.cigenzhuji.length-1,isOdd: index% 2 === 0 && index!==activeWord.cigenzhuji.length-1}">
  52. {{item.en}}</view>
  53. <view>{{item.zn}}</view>
  54. </view>
  55. <view class="cg-symbol" v-if="index<activeWord.cigenzhuji.length-2">+</view>
  56. <view class="cg-symbol" v-if="index == activeWord.cigenzhuji.length - 2">=</view>
  57. </view>
  58. </scroll-view>
  59. </view>
  60. <!-- 实用语句 -->
  61. <view class="details-content-box xue-details-content-box">
  62. <text class="details-title">实用口语</text>
  63. <view v-for="(item,index) in activeWord.kouyu" :key="index" class="syky-content">
  64. <view class="details-en-content">
  65. <rich-text :nodes="highlightWord(item.en)"></rich-text>
  66. </view>
  67. <view class="details-cn-content">{{item.zn}}</view>
  68. </view>
  69. </view>
  70. </view>
  71. </view>
  72. </view>
  73. </view>
  74. </template>
  75. <script setup>
  76. import selectTypesVue from './selectTypes.vue';
  77. import audioTwoVue from './audioTwo.vue';
  78. import audioThreeVue from './audioThree.vue';
  79. import audioFourVue from './audioFour.vue';
  80. import yinbiaoTxtVue from "./yinbiaoTxt.vue"
  81. import {
  82. reactive,
  83. computed,
  84. } from 'vue';
  85. import {
  86. getUserIdentity,
  87. } from "@/utils/common.js"
  88. import * as httpApi from "@/api/word.js"
  89. import {
  90. audioPlayer,
  91. useAudioCache
  92. } from './useAudio.js';
  93. const emits = defineEmits(['play-audio','goXiangjie'])
  94. const userCode = getUserIdentity();
  95. const {
  96. cacheAudio,
  97. clearAudioCache
  98. } = useAudioCache();
  99. const data = reactive({
  100. isPlaying: false,
  101. isPindu: true,
  102. })
  103. const props = defineProps({
  104. activeWord: { // 单词数据
  105. type: Object,
  106. },
  107. activeWords: {
  108. type: Array
  109. },
  110. pageData: {
  111. type: Object,
  112. },
  113. })
  114. const highlightWord = (text) => {
  115. if (!text || !props.activeWord.name) {
  116. return text
  117. }
  118. const word = props.activeWord.name;
  119. const regex = new RegExp(word, 'gi');
  120. return text.replace(regex, (match) => {
  121. return `<span style="color: #3a7fe9;">${match}</span>`;
  122. });
  123. }
  124. async function handlePlay(opt) {
  125. emits('play-audio', opt)
  126. }
  127. function handlePindu() {
  128. data.isPindu = true
  129. }
  130. function handleYinjie() {
  131. data.isPindu = false
  132. }
  133. function goXiangjie() {
  134. if (userCode !== 'Visitor') {
  135. uni.redirectTo({
  136. url: '/pages/newEnglish/components/xiangjie?jieId=' + props.pageData.jieId + '&wordId=' + props
  137. .pageData.activeId
  138. })
  139. } else {
  140. emits('goXiangjie')
  141. }
  142. }
  143. </script>
  144. <style>
  145. </style>