Audio.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. <template>
  2. <div class="audio_area" :style="getAreaStyle()">
  3. <div class="sn-position" :style="getJustifyContentStyle()">
  4. {{ data.property.serial_number }}
  5. </div>
  6. <div class="main">
  7. <ul v-if="'list' === data.property.view_method" class="view_list">
  8. <li v-for="(file, i) in data.file_list" :key="i">
  9. <AudioPlay view-size="small" :file-id="file.file_id" :audio-index="i" view-method="list" />
  10. </li>
  11. </ul>
  12. <div
  13. v-if="'independent' === data.property.view_method || 'icon' === data.property.view_method"
  14. class="view_independent"
  15. >
  16. <el-carousel
  17. ref="audio_carousel"
  18. indicator-position="none"
  19. direction="vertical"
  20. :autoplay="false"
  21. :interval="0"
  22. >
  23. <el-carousel-item v-for="(file, i) in data.file_list" :key="i">
  24. <AudioPlay
  25. view-size="big"
  26. :file-id="file.file_id"
  27. :show-slider="true"
  28. :cur-audio-index="curAudioIndex"
  29. @changeFile="changeFile"
  30. />
  31. </el-carousel-item>
  32. </el-carousel>
  33. <ul class="view_independent_list">
  34. <li v-for="(file, i) in data.file_list" :key="i" @click="handleAudioClick(i)">
  35. <AudioPlay
  36. view-size="small"
  37. :file-id="file.file_id"
  38. :show-slider="false"
  39. :audio-index="i"
  40. :cur-audio-index="curAudioIndex"
  41. />
  42. </li>
  43. </ul>
  44. </div>
  45. </div>
  46. </div>
  47. </template>
  48. <script>
  49. import { getAudioData } from '@/views/book/courseware/data/audio';
  50. import PreviewMixin from '../common/PreviewMixin';
  51. import AudioPlay from '../common/AudioPlay.vue';
  52. export default {
  53. name: 'AudioPreview',
  54. components: { AudioPlay },
  55. mixins: [PreviewMixin],
  56. data() {
  57. return {
  58. data: getAudioData(),
  59. curAudioIndex: 0,
  60. };
  61. },
  62. methods: {
  63. handleAudioClick(index) {
  64. // 获取 Carousel 实例
  65. const carousel = this.$refs.audio_carousel;
  66. // 切换到对应索引的文件
  67. carousel.setActiveItem(index);
  68. this.curAudioIndex = index;
  69. },
  70. changeFile(type) {
  71. // 获取 Carousel 实例
  72. const carousel = this.$refs.audio_carousel;
  73. // 切换到对应索引的文件
  74. if (type === 'prev') {
  75. carousel.prev();
  76. this.curAudioIndex += -1;
  77. } else {
  78. carousel.next();
  79. this.curAudioIndex += 1;
  80. }
  81. if (this.curAudioIndex >= this.data.file_id_list.length) {
  82. this.curAudioIndex = 0;
  83. }
  84. if (this.curAudioIndex < 0) {
  85. this.curAudioIndex = this.data.file_id_list.length - 1;
  86. }
  87. },
  88. /**
  89. * 得到序号外部样式
  90. */
  91. getAreaStyle() {
  92. const position = this.data.property.sn_position;
  93. let grid = '';
  94. if (position.includes('right')) {
  95. grid = `"main position" / 1fr auto`;
  96. } else if (position.includes('left')) {
  97. grid = `"position main" / auto 1fr`;
  98. } else if (position.includes('top')) {
  99. grid = `"position" auto "main" 1fr`;
  100. } else if (position.includes('bottom')) {
  101. grid = `"main" 1fr "position" auto`;
  102. }
  103. return {
  104. grid,
  105. };
  106. },
  107. /**
  108. * 得到序号位置样式
  109. */
  110. getJustifyContentStyle() {
  111. const position = this.data.property.sn_position;
  112. let placeSelf = '';
  113. if (position.includes('start')) {
  114. placeSelf = 'flex-start';
  115. } else if (position.includes('end')) {
  116. placeSelf = 'flex-end';
  117. } else {
  118. placeSelf = 'center';
  119. }
  120. return {
  121. placeSelf,
  122. };
  123. },
  124. },
  125. };
  126. </script>
  127. <style lang="scss" scoped>
  128. .audio_area {
  129. display: grid;
  130. gap: 6px;
  131. padding: 8px;
  132. .sn-position {
  133. grid-area: position;
  134. }
  135. > .main {
  136. display: flex;
  137. margin: 4px auto;
  138. > span {
  139. display: flex;
  140. }
  141. }
  142. .main {
  143. grid-area: main;
  144. width: 100%;
  145. .view_list {
  146. display: flex;
  147. flex-wrap: wrap;
  148. gap: 32px 28px;
  149. width: 100%;
  150. > li {
  151. width: 23%;
  152. height: 46px;
  153. }
  154. }
  155. .view_independent {
  156. display: flex;
  157. flex: 1;
  158. column-gap: 12px;
  159. :deep .el-carousel {
  160. flex: 1;
  161. max-height: 500px;
  162. padding: 20% 13px;
  163. background-color: #d9d9d9;
  164. &__container {
  165. max-width: 500px;
  166. height: 100px;
  167. max-height: 500px;
  168. margin: 0 auto;
  169. }
  170. &__item {
  171. transition: none !important;
  172. }
  173. }
  174. .view_independent_list {
  175. display: flex;
  176. flex-direction: column;
  177. row-gap: 2px;
  178. width: 20%;
  179. min-width: 110px;
  180. max-height: 500px;
  181. overflow-y: auto;
  182. }
  183. }
  184. }
  185. }
  186. </style>