AudioPlay.vue 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. <template>
  2. <div class="audio-wrapper">
  3. <span class="audio-play" @click="playAudio">
  4. <SvgIcon :size="audio.paused ? 20 : 14" :icon-class="iconClass" />
  5. </span>
  6. <audio ref="audio" :src="url" preload="metadata"></audio>
  7. </div>
  8. </template>
  9. <script>
  10. import { GetFileURLMap } from '@/api/app';
  11. export default {
  12. name: 'AudioPlay',
  13. props: {
  14. fileId: {
  15. type: String,
  16. required: true
  17. }
  18. },
  19. data() {
  20. return {
  21. url: '',
  22. audio: {
  23. paused: true
  24. }
  25. };
  26. },
  27. computed: {
  28. iconClass() {
  29. return this.audio.paused ? 'audio' : 'audio-stop';
  30. }
  31. },
  32. watch: {
  33. fileId: {
  34. handler(val) {
  35. if (!val) return;
  36. GetFileURLMap({ file_id_list: [val] }).then(({ url_map }) => {
  37. this.url = url_map[val];
  38. });
  39. },
  40. immediate: true
  41. }
  42. },
  43. mounted() {
  44. this.$refs.audio.addEventListener('ended', () => {
  45. this.audio.paused = true;
  46. });
  47. this.$refs.audio.addEventListener('pause', () => {
  48. this.audio.paused = true;
  49. });
  50. this.$refs.audio.addEventListener('play', () => {
  51. this.audio.paused = false;
  52. });
  53. },
  54. methods: {
  55. playAudio() {
  56. const audio = this.$refs.audio;
  57. audio.paused ? audio.play() : audio.pause();
  58. }
  59. }
  60. };
  61. </script>
  62. <style lang="scss" scoped>
  63. .audio-wrapper {
  64. .audio-play {
  65. display: flex;
  66. align-items: center;
  67. justify-content: center;
  68. width: 40px;
  69. height: 40px;
  70. cursor: pointer;
  71. background-color: $main-color;
  72. border-radius: 50%;
  73. }
  74. }
  75. </style>