修复播放器
This commit is contained in:
		
							parent
							
								
									e7beed15cd
								
							
						
					
					
						commit
						4ce5492139
					
				@ -92,12 +92,10 @@
 | 
				
			|||||||
            :songServer="playerData.server"
 | 
					            :songServer="playerData.server"
 | 
				
			||||||
            :songType="playerData.type"
 | 
					            :songType="playerData.type"
 | 
				
			||||||
            :songId="playerData.id"
 | 
					            :songId="playerData.id"
 | 
				
			||||||
 | 
					            :volume="volumeNum"
 | 
				
			||||||
 | 
					            :shuffle="true"
 | 
				
			||||||
            ref="playerRef"
 | 
					            ref="playerRef"
 | 
				
			||||||
          />
 | 
					          />
 | 
				
			||||||
          <div class="error" v-if="!store.musicIsOk">
 | 
					 | 
				
			||||||
            <play-wrong theme="outline" size="60" />
 | 
					 | 
				
			||||||
            <span>音乐播放器加载失败</span>
 | 
					 | 
				
			||||||
          </div>
 | 
					 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </Transition>
 | 
					      </Transition>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
@ -105,7 +103,7 @@
 | 
				
			|||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script setup>
 | 
					<script setup>
 | 
				
			||||||
import { ref, reactive, watch, onMounted } from "vue";
 | 
					import { ref, reactive, watch, onMounted, nextTick } from "vue";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  GoStart,
 | 
					  GoStart,
 | 
				
			||||||
  PlayOne,
 | 
					  PlayOne,
 | 
				
			||||||
@ -115,7 +113,6 @@ import {
 | 
				
			|||||||
  VolumeMute,
 | 
					  VolumeMute,
 | 
				
			||||||
  VolumeSmall,
 | 
					  VolumeSmall,
 | 
				
			||||||
  VolumeNotice,
 | 
					  VolumeNotice,
 | 
				
			||||||
  PlayWrong,
 | 
					 | 
				
			||||||
} from "@icon-park/vue-next";
 | 
					} from "@icon-park/vue-next";
 | 
				
			||||||
import Player from "@/components/Player/index.vue";
 | 
					import Player from "@/components/Player/index.vue";
 | 
				
			||||||
import { mainStore } from "@/store";
 | 
					import { mainStore } from "@/store";
 | 
				
			||||||
@ -123,11 +120,7 @@ const store = mainStore();
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// 音量条数据
 | 
					// 音量条数据
 | 
				
			||||||
let volumeShow = ref(false);
 | 
					let volumeShow = ref(false);
 | 
				
			||||||
let volumeNum = ref(
 | 
					let volumeNum = ref(store.musicVolume ? store.musicVolume : 0.7);
 | 
				
			||||||
  localStorage.getItem("aplayer-setting")
 | 
					 | 
				
			||||||
    ? JSON.parse(localStorage.getItem("aplayer-setting")).volume
 | 
					 | 
				
			||||||
    : 0.7
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 播放列表数据
 | 
					// 播放列表数据
 | 
				
			||||||
let musicListShow = ref(false);
 | 
					let musicListShow = ref(false);
 | 
				
			||||||
@ -138,23 +131,21 @@ const playerData = reactive({
 | 
				
			|||||||
  type: import.meta.env.VITE_SONG_TYPE,
 | 
					  type: import.meta.env.VITE_SONG_TYPE,
 | 
				
			||||||
  id: import.meta.env.VITE_SONG_ID,
 | 
					  id: import.meta.env.VITE_SONG_ID,
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 音乐播放暂停
 | 
					// 音乐播放暂停
 | 
				
			||||||
const changePlayState = () => {
 | 
					const changePlayState = () => {
 | 
				
			||||||
  playerRef.value.playToggle();
 | 
					  playerRef.value.playToggle();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 音乐上下曲
 | 
					// 音乐上下曲
 | 
				
			||||||
const changeMusicIndex = (type) => {
 | 
					const changeMusicIndex = (type) => {
 | 
				
			||||||
  if (type) {
 | 
					  playerRef.value.changeSong(type);
 | 
				
			||||||
    playerRef.value.changeSongPrev();
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    playerRef.value.changeSongNext();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
onMounted(() => {
 | 
					onMounted(() => {
 | 
				
			||||||
  // 空格键事件
 | 
					  // 空格键事件
 | 
				
			||||||
  window.addEventListener("keydown", (e) => {
 | 
					  window.addEventListener("keydown", (e) => {
 | 
				
			||||||
    if (e.code == "Space" && store.musicIsOk) {
 | 
					    if (e.code == "Space") {
 | 
				
			||||||
      changePlayState();
 | 
					      changePlayState();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
@ -164,8 +155,8 @@ onMounted(() => {
 | 
				
			|||||||
watch(
 | 
					watch(
 | 
				
			||||||
  () => volumeNum.value,
 | 
					  () => volumeNum.value,
 | 
				
			||||||
  (value) => {
 | 
					  (value) => {
 | 
				
			||||||
    console.log(value);
 | 
					    store.musicVolume = value;
 | 
				
			||||||
    playerRef.value.changeVolume(value);
 | 
					    playerRef.value.changeVolume(store.musicVolume);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
@ -184,12 +175,10 @@ watch(
 | 
				
			|||||||
  flex-direction: column;
 | 
					  flex-direction: column;
 | 
				
			||||||
  animation: fade;
 | 
					  animation: fade;
 | 
				
			||||||
  -webkit-animation: fade 0.5s;
 | 
					  -webkit-animation: fade 0.5s;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  .btns {
 | 
					  .btns {
 | 
				
			||||||
    display: flex;
 | 
					    display: flex;
 | 
				
			||||||
    align-items: center;
 | 
					    align-items: center;
 | 
				
			||||||
    margin-bottom: 6px;
 | 
					    margin-bottom: 6px;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    span {
 | 
					    span {
 | 
				
			||||||
      background: #ffffff26;
 | 
					      background: #ffffff26;
 | 
				
			||||||
      padding: 2px 8px;
 | 
					      padding: 2px 8px;
 | 
				
			||||||
@ -198,20 +187,17 @@ watch(
 | 
				
			|||||||
      text-overflow: ellipsis;
 | 
					      text-overflow: ellipsis;
 | 
				
			||||||
      overflow-x: hidden;
 | 
					      overflow-x: hidden;
 | 
				
			||||||
      white-space: nowrap;
 | 
					      white-space: nowrap;
 | 
				
			||||||
 | 
					 | 
				
			||||||
      &:hover {
 | 
					      &:hover {
 | 
				
			||||||
        background: #ffffff4d;
 | 
					        background: #ffffff4d;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  .control {
 | 
					  .control {
 | 
				
			||||||
    display: flex;
 | 
					    display: flex;
 | 
				
			||||||
    flex-direction: row;
 | 
					    flex-direction: row;
 | 
				
			||||||
    align-items: center;
 | 
					    align-items: center;
 | 
				
			||||||
    justify-content: space-evenly;
 | 
					    justify-content: space-evenly;
 | 
				
			||||||
    width: 100%;
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    .state {
 | 
					    .state {
 | 
				
			||||||
      .i-icon {
 | 
					      .i-icon {
 | 
				
			||||||
        width: 50px;
 | 
					        width: 50px;
 | 
				
			||||||
@ -219,7 +205,6 @@ watch(
 | 
				
			|||||||
        display: block;
 | 
					        display: block;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    .i-icon {
 | 
					    .i-icon {
 | 
				
			||||||
      width: 36px;
 | 
					      width: 36px;
 | 
				
			||||||
      height: 36px;
 | 
					      height: 36px;
 | 
				
			||||||
@ -229,17 +214,14 @@ watch(
 | 
				
			|||||||
      justify-content: center;
 | 
					      justify-content: center;
 | 
				
			||||||
      border-radius: 6px;
 | 
					      border-radius: 6px;
 | 
				
			||||||
      transform: scale(1);
 | 
					      transform: scale(1);
 | 
				
			||||||
 | 
					 | 
				
			||||||
      &:hover {
 | 
					      &:hover {
 | 
				
			||||||
        background: #ffffff33;
 | 
					        background: #ffffff33;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					 | 
				
			||||||
      &:active {
 | 
					      &:active {
 | 
				
			||||||
        transform: scale(0.95);
 | 
					        transform: scale(0.95);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  .menu {
 | 
					  .menu {
 | 
				
			||||||
    height: 26px;
 | 
					    height: 26px;
 | 
				
			||||||
    width: 100%;
 | 
					    width: 100%;
 | 
				
			||||||
@ -248,18 +230,15 @@ watch(
 | 
				
			|||||||
    flex-direction: column;
 | 
					    flex-direction: column;
 | 
				
			||||||
    align-items: center;
 | 
					    align-items: center;
 | 
				
			||||||
    justify-content: center;
 | 
					    justify-content: center;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    .name {
 | 
					    .name {
 | 
				
			||||||
      width: 100%;
 | 
					      width: 100%;
 | 
				
			||||||
      text-align: center;
 | 
					      text-align: center;
 | 
				
			||||||
      text-overflow: ellipsis;
 | 
					      text-overflow: ellipsis;
 | 
				
			||||||
      overflow-x: hidden;
 | 
					      overflow-x: hidden;
 | 
				
			||||||
      white-space: nowrap;
 | 
					      white-space: nowrap;
 | 
				
			||||||
      // font-size: 1.1rem;
 | 
					 | 
				
			||||||
      animation: fade;
 | 
					      animation: fade;
 | 
				
			||||||
      -webkit-animation: fade 0.3s;
 | 
					      -webkit-animation: fade 0.3s;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    .volume {
 | 
					    .volume {
 | 
				
			||||||
      width: 100%;
 | 
					      width: 100%;
 | 
				
			||||||
      padding: 0 12px;
 | 
					      padding: 0 12px;
 | 
				
			||||||
@ -268,25 +247,20 @@ watch(
 | 
				
			|||||||
      flex-direction: row;
 | 
					      flex-direction: row;
 | 
				
			||||||
      animation: fade;
 | 
					      animation: fade;
 | 
				
			||||||
      -webkit-animation: fade 0.3s;
 | 
					      -webkit-animation: fade 0.3s;
 | 
				
			||||||
 | 
					 | 
				
			||||||
      .icon {
 | 
					      .icon {
 | 
				
			||||||
        margin-right: 12px;
 | 
					        margin-right: 12px;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        span {
 | 
					        span {
 | 
				
			||||||
          width: 24px;
 | 
					          width: 24px;
 | 
				
			||||||
          height: 24px;
 | 
					          height: 24px;
 | 
				
			||||||
          display: block;
 | 
					          display: block;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					 | 
				
			||||||
      :deep(*) {
 | 
					      :deep(*) {
 | 
				
			||||||
        transition: none;
 | 
					        transition: none;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					 | 
				
			||||||
      :deep(.el-slider__button) {
 | 
					      :deep(.el-slider__button) {
 | 
				
			||||||
        transition: 0.3s;
 | 
					        transition: 0.3s;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					 | 
				
			||||||
      .el-slider {
 | 
					      .el-slider {
 | 
				
			||||||
        margin-right: 12px;
 | 
					        margin-right: 12px;
 | 
				
			||||||
        --el-slider-main-bg-color: #efefef;
 | 
					        --el-slider-main-bg-color: #efefef;
 | 
				
			||||||
@ -296,7 +270,6 @@ watch(
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
.music-list {
 | 
					.music-list {
 | 
				
			||||||
  position: fixed;
 | 
					  position: fixed;
 | 
				
			||||||
  top: 0;
 | 
					  top: 0;
 | 
				
			||||||
@ -307,7 +280,6 @@ watch(
 | 
				
			|||||||
  background-color: #00000080;
 | 
					  background-color: #00000080;
 | 
				
			||||||
  backdrop-filter: blur(20px);
 | 
					  backdrop-filter: blur(20px);
 | 
				
			||||||
  z-index: 1;
 | 
					  z-index: 1;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  .list {
 | 
					  .list {
 | 
				
			||||||
    position: absolute;
 | 
					    position: absolute;
 | 
				
			||||||
    display: flex;
 | 
					    display: flex;
 | 
				
			||||||
@ -320,7 +292,6 @@ watch(
 | 
				
			|||||||
    background-color: #ffffff66;
 | 
					    background-color: #ffffff66;
 | 
				
			||||||
    border-radius: 6px;
 | 
					    border-radius: 6px;
 | 
				
			||||||
    z-index: 999;
 | 
					    z-index: 999;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    .close {
 | 
					    .close {
 | 
				
			||||||
      position: absolute;
 | 
					      position: absolute;
 | 
				
			||||||
      top: 12px;
 | 
					      top: 12px;
 | 
				
			||||||
@ -328,33 +299,22 @@ watch(
 | 
				
			|||||||
      width: 28px;
 | 
					      width: 28px;
 | 
				
			||||||
      height: 28px;
 | 
					      height: 28px;
 | 
				
			||||||
      display: block;
 | 
					      display: block;
 | 
				
			||||||
 | 
					 | 
				
			||||||
      &:hover {
 | 
					      &:hover {
 | 
				
			||||||
        transform: scale(1.2);
 | 
					        transform: scale(1.2);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					 | 
				
			||||||
      &:active {
 | 
					      &:active {
 | 
				
			||||||
        transform: scale(0.95);
 | 
					        transform: scale(0.95);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    .error {
 | 
					 | 
				
			||||||
      display: flex;
 | 
					 | 
				
			||||||
      flex-direction: column;
 | 
					 | 
				
			||||||
      align-items: center;
 | 
					 | 
				
			||||||
      .i-icon {
 | 
					 | 
				
			||||||
        margin-bottom: 20px;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 弹窗动画
 | 
					// 弹窗动画
 | 
				
			||||||
.fade-enter-active {
 | 
					.fade-enter-active {
 | 
				
			||||||
    animation: fade 0.3s ease-in-out;
 | 
					  animation: fade 0.3s ease-in-out;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
.fade-leave-active {
 | 
					.fade-leave-active {
 | 
				
			||||||
    animation: fade 0.3s ease-in-out reverse;
 | 
					  animation: fade 0.3s ease-in-out reverse;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
.zoom-enter-active {
 | 
					.zoom-enter-active {
 | 
				
			||||||
  animation: zoom 0.4s ease-in-out;
 | 
					  animation: zoom 0.4s ease-in-out;
 | 
				
			||||||
 | 
				
			|||||||
@ -92,10 +92,12 @@
 | 
				
			|||||||
            :songServer="playerData.server"
 | 
					            :songServer="playerData.server"
 | 
				
			||||||
            :songType="playerData.type"
 | 
					            :songType="playerData.type"
 | 
				
			||||||
            :songId="playerData.id"
 | 
					            :songId="playerData.id"
 | 
				
			||||||
            :volume="volumeNum"
 | 
					 | 
				
			||||||
            :shuffle="true"
 | 
					 | 
				
			||||||
            ref="playerRef"
 | 
					            ref="playerRef"
 | 
				
			||||||
          />
 | 
					          />
 | 
				
			||||||
 | 
					          <div class="error" v-if="!store.musicIsOk">
 | 
				
			||||||
 | 
					            <play-wrong theme="outline" size="60" />
 | 
				
			||||||
 | 
					            <span>音乐播放器加载失败</span>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </Transition>
 | 
					      </Transition>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
@ -103,7 +105,7 @@
 | 
				
			|||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script setup>
 | 
					<script setup>
 | 
				
			||||||
import { ref, reactive, watch, onMounted, nextTick } from "vue";
 | 
					import { ref, reactive, watch, onMounted } from "vue";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  GoStart,
 | 
					  GoStart,
 | 
				
			||||||
  PlayOne,
 | 
					  PlayOne,
 | 
				
			||||||
@ -113,14 +115,19 @@ import {
 | 
				
			|||||||
  VolumeMute,
 | 
					  VolumeMute,
 | 
				
			||||||
  VolumeSmall,
 | 
					  VolumeSmall,
 | 
				
			||||||
  VolumeNotice,
 | 
					  VolumeNotice,
 | 
				
			||||||
 | 
					  PlayWrong,
 | 
				
			||||||
} from "@icon-park/vue-next";
 | 
					} from "@icon-park/vue-next";
 | 
				
			||||||
import Player from "@/components/Player/Beta.vue";
 | 
					import Player from "@/components/Player/index.vue";
 | 
				
			||||||
import { mainStore } from "@/store";
 | 
					import { mainStore } from "@/store";
 | 
				
			||||||
const store = mainStore();
 | 
					const store = mainStore();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 音量条数据
 | 
					// 音量条数据
 | 
				
			||||||
let volumeShow = ref(false);
 | 
					let volumeShow = ref(false);
 | 
				
			||||||
let volumeNum = ref(store.musicVolume ? store.musicVolume : 0.7);
 | 
					let volumeNum = ref(
 | 
				
			||||||
 | 
					  localStorage.getItem("aplayer-setting")
 | 
				
			||||||
 | 
					    ? JSON.parse(localStorage.getItem("aplayer-setting")).volume
 | 
				
			||||||
 | 
					    : 0.7
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 播放列表数据
 | 
					// 播放列表数据
 | 
				
			||||||
let musicListShow = ref(false);
 | 
					let musicListShow = ref(false);
 | 
				
			||||||
@ -131,21 +138,23 @@ const playerData = reactive({
 | 
				
			|||||||
  type: import.meta.env.VITE_SONG_TYPE,
 | 
					  type: import.meta.env.VITE_SONG_TYPE,
 | 
				
			||||||
  id: import.meta.env.VITE_SONG_ID,
 | 
					  id: import.meta.env.VITE_SONG_ID,
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					 | 
				
			||||||
// 音乐播放暂停
 | 
					// 音乐播放暂停
 | 
				
			||||||
const changePlayState = () => {
 | 
					const changePlayState = () => {
 | 
				
			||||||
  playerRef.value.playToggle();
 | 
					  playerRef.value.playToggle();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					 | 
				
			||||||
// 音乐上下曲
 | 
					// 音乐上下曲
 | 
				
			||||||
const changeMusicIndex = (type) => {
 | 
					const changeMusicIndex = (type) => {
 | 
				
			||||||
  playerRef.value.changeSong(type);
 | 
					  if (type) {
 | 
				
			||||||
 | 
					    playerRef.value.changeSongPrev();
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    playerRef.value.changeSongNext();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
onMounted(() => {
 | 
					onMounted(() => {
 | 
				
			||||||
  // 空格键事件
 | 
					  // 空格键事件
 | 
				
			||||||
  window.addEventListener("keydown", (e) => {
 | 
					  window.addEventListener("keydown", (e) => {
 | 
				
			||||||
    if (e.code == "Space") {
 | 
					    if (e.code == "Space" && store.musicIsOk) {
 | 
				
			||||||
      changePlayState();
 | 
					      changePlayState();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
@ -155,8 +164,8 @@ onMounted(() => {
 | 
				
			|||||||
watch(
 | 
					watch(
 | 
				
			||||||
  () => volumeNum.value,
 | 
					  () => volumeNum.value,
 | 
				
			||||||
  (value) => {
 | 
					  (value) => {
 | 
				
			||||||
    store.musicVolume = value;
 | 
					    console.log(value);
 | 
				
			||||||
    playerRef.value.changeVolume(store.musicVolume);
 | 
					    playerRef.value.changeVolume(value);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
@ -175,10 +184,12 @@ watch(
 | 
				
			|||||||
  flex-direction: column;
 | 
					  flex-direction: column;
 | 
				
			||||||
  animation: fade;
 | 
					  animation: fade;
 | 
				
			||||||
  -webkit-animation: fade 0.5s;
 | 
					  -webkit-animation: fade 0.5s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .btns {
 | 
					  .btns {
 | 
				
			||||||
    display: flex;
 | 
					    display: flex;
 | 
				
			||||||
    align-items: center;
 | 
					    align-items: center;
 | 
				
			||||||
    margin-bottom: 6px;
 | 
					    margin-bottom: 6px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    span {
 | 
					    span {
 | 
				
			||||||
      background: #ffffff26;
 | 
					      background: #ffffff26;
 | 
				
			||||||
      padding: 2px 8px;
 | 
					      padding: 2px 8px;
 | 
				
			||||||
@ -187,17 +198,20 @@ watch(
 | 
				
			|||||||
      text-overflow: ellipsis;
 | 
					      text-overflow: ellipsis;
 | 
				
			||||||
      overflow-x: hidden;
 | 
					      overflow-x: hidden;
 | 
				
			||||||
      white-space: nowrap;
 | 
					      white-space: nowrap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      &:hover {
 | 
					      &:hover {
 | 
				
			||||||
        background: #ffffff4d;
 | 
					        background: #ffffff4d;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .control {
 | 
					  .control {
 | 
				
			||||||
    display: flex;
 | 
					    display: flex;
 | 
				
			||||||
    flex-direction: row;
 | 
					    flex-direction: row;
 | 
				
			||||||
    align-items: center;
 | 
					    align-items: center;
 | 
				
			||||||
    justify-content: space-evenly;
 | 
					    justify-content: space-evenly;
 | 
				
			||||||
    width: 100%;
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .state {
 | 
					    .state {
 | 
				
			||||||
      .i-icon {
 | 
					      .i-icon {
 | 
				
			||||||
        width: 50px;
 | 
					        width: 50px;
 | 
				
			||||||
@ -205,6 +219,7 @@ watch(
 | 
				
			|||||||
        display: block;
 | 
					        display: block;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .i-icon {
 | 
					    .i-icon {
 | 
				
			||||||
      width: 36px;
 | 
					      width: 36px;
 | 
				
			||||||
      height: 36px;
 | 
					      height: 36px;
 | 
				
			||||||
@ -214,14 +229,17 @@ watch(
 | 
				
			|||||||
      justify-content: center;
 | 
					      justify-content: center;
 | 
				
			||||||
      border-radius: 6px;
 | 
					      border-radius: 6px;
 | 
				
			||||||
      transform: scale(1);
 | 
					      transform: scale(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      &:hover {
 | 
					      &:hover {
 | 
				
			||||||
        background: #ffffff33;
 | 
					        background: #ffffff33;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      &:active {
 | 
					      &:active {
 | 
				
			||||||
        transform: scale(0.95);
 | 
					        transform: scale(0.95);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .menu {
 | 
					  .menu {
 | 
				
			||||||
    height: 26px;
 | 
					    height: 26px;
 | 
				
			||||||
    width: 100%;
 | 
					    width: 100%;
 | 
				
			||||||
@ -230,15 +248,18 @@ watch(
 | 
				
			|||||||
    flex-direction: column;
 | 
					    flex-direction: column;
 | 
				
			||||||
    align-items: center;
 | 
					    align-items: center;
 | 
				
			||||||
    justify-content: center;
 | 
					    justify-content: center;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .name {
 | 
					    .name {
 | 
				
			||||||
      width: 100%;
 | 
					      width: 100%;
 | 
				
			||||||
      text-align: center;
 | 
					      text-align: center;
 | 
				
			||||||
      text-overflow: ellipsis;
 | 
					      text-overflow: ellipsis;
 | 
				
			||||||
      overflow-x: hidden;
 | 
					      overflow-x: hidden;
 | 
				
			||||||
      white-space: nowrap;
 | 
					      white-space: nowrap;
 | 
				
			||||||
 | 
					      // font-size: 1.1rem;
 | 
				
			||||||
      animation: fade;
 | 
					      animation: fade;
 | 
				
			||||||
      -webkit-animation: fade 0.3s;
 | 
					      -webkit-animation: fade 0.3s;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .volume {
 | 
					    .volume {
 | 
				
			||||||
      width: 100%;
 | 
					      width: 100%;
 | 
				
			||||||
      padding: 0 12px;
 | 
					      padding: 0 12px;
 | 
				
			||||||
@ -247,20 +268,25 @@ watch(
 | 
				
			|||||||
      flex-direction: row;
 | 
					      flex-direction: row;
 | 
				
			||||||
      animation: fade;
 | 
					      animation: fade;
 | 
				
			||||||
      -webkit-animation: fade 0.3s;
 | 
					      -webkit-animation: fade 0.3s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      .icon {
 | 
					      .icon {
 | 
				
			||||||
        margin-right: 12px;
 | 
					        margin-right: 12px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        span {
 | 
					        span {
 | 
				
			||||||
          width: 24px;
 | 
					          width: 24px;
 | 
				
			||||||
          height: 24px;
 | 
					          height: 24px;
 | 
				
			||||||
          display: block;
 | 
					          display: block;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      :deep(*) {
 | 
					      :deep(*) {
 | 
				
			||||||
        transition: none;
 | 
					        transition: none;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      :deep(.el-slider__button) {
 | 
					      :deep(.el-slider__button) {
 | 
				
			||||||
        transition: 0.3s;
 | 
					        transition: 0.3s;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      .el-slider {
 | 
					      .el-slider {
 | 
				
			||||||
        margin-right: 12px;
 | 
					        margin-right: 12px;
 | 
				
			||||||
        --el-slider-main-bg-color: #efefef;
 | 
					        --el-slider-main-bg-color: #efefef;
 | 
				
			||||||
@ -270,6 +296,7 @@ watch(
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.music-list {
 | 
					.music-list {
 | 
				
			||||||
  position: fixed;
 | 
					  position: fixed;
 | 
				
			||||||
  top: 0;
 | 
					  top: 0;
 | 
				
			||||||
@ -280,6 +307,7 @@ watch(
 | 
				
			|||||||
  background-color: #00000080;
 | 
					  background-color: #00000080;
 | 
				
			||||||
  backdrop-filter: blur(20px);
 | 
					  backdrop-filter: blur(20px);
 | 
				
			||||||
  z-index: 1;
 | 
					  z-index: 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .list {
 | 
					  .list {
 | 
				
			||||||
    position: absolute;
 | 
					    position: absolute;
 | 
				
			||||||
    display: flex;
 | 
					    display: flex;
 | 
				
			||||||
@ -292,6 +320,7 @@ watch(
 | 
				
			|||||||
    background-color: #ffffff66;
 | 
					    background-color: #ffffff66;
 | 
				
			||||||
    border-radius: 6px;
 | 
					    border-radius: 6px;
 | 
				
			||||||
    z-index: 999;
 | 
					    z-index: 999;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .close {
 | 
					    .close {
 | 
				
			||||||
      position: absolute;
 | 
					      position: absolute;
 | 
				
			||||||
      top: 12px;
 | 
					      top: 12px;
 | 
				
			||||||
@ -299,22 +328,33 @@ watch(
 | 
				
			|||||||
      width: 28px;
 | 
					      width: 28px;
 | 
				
			||||||
      height: 28px;
 | 
					      height: 28px;
 | 
				
			||||||
      display: block;
 | 
					      display: block;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      &:hover {
 | 
					      &:hover {
 | 
				
			||||||
        transform: scale(1.2);
 | 
					        transform: scale(1.2);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      &:active {
 | 
					      &:active {
 | 
				
			||||||
        transform: scale(0.95);
 | 
					        transform: scale(0.95);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .error {
 | 
				
			||||||
 | 
					      display: flex;
 | 
				
			||||||
 | 
					      flex-direction: column;
 | 
				
			||||||
 | 
					      align-items: center;
 | 
				
			||||||
 | 
					      .i-icon {
 | 
				
			||||||
 | 
					        margin-bottom: 20px;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 弹窗动画
 | 
					// 弹窗动画
 | 
				
			||||||
.fade-enter-active {
 | 
					.fade-enter-active {
 | 
				
			||||||
  animation: fade 0.3s ease-in-out;
 | 
					    animation: fade 0.3s ease-in-out;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
.fade-leave-active {
 | 
					.fade-leave-active {
 | 
				
			||||||
  animation: fade 0.3s ease-in-out reverse;
 | 
					    animation: fade 0.3s ease-in-out reverse;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
.zoom-enter-active {
 | 
					.zoom-enter-active {
 | 
				
			||||||
  animation: zoom 0.4s ease-in-out;
 | 
					  animation: zoom 0.4s ease-in-out;
 | 
				
			||||||
@ -1,306 +0,0 @@
 | 
				
			|||||||
<template>
 | 
					 | 
				
			||||||
  <aplayer
 | 
					 | 
				
			||||||
    showLrc
 | 
					 | 
				
			||||||
    ref="player"
 | 
					 | 
				
			||||||
    v-if="playList[0]"
 | 
					 | 
				
			||||||
    :music="playList[playIndex]"
 | 
					 | 
				
			||||||
    :list="playList"
 | 
					 | 
				
			||||||
    :autoplay="autoplay"
 | 
					 | 
				
			||||||
    :theme="theme"
 | 
					 | 
				
			||||||
    :repeat="repeat"
 | 
					 | 
				
			||||||
    :shuffle="shuffle"
 | 
					 | 
				
			||||||
    :listMaxHeight="listMaxHeight"
 | 
					 | 
				
			||||||
    :listFolded="listFolded"
 | 
					 | 
				
			||||||
    :volume="volume"
 | 
					 | 
				
			||||||
    @play="onPlay"
 | 
					 | 
				
			||||||
    @pause="onPause"
 | 
					 | 
				
			||||||
    @timeupdate="onTimeUp"
 | 
					 | 
				
			||||||
    @onSelectSong="onSelectSong"
 | 
					 | 
				
			||||||
  />
 | 
					 | 
				
			||||||
</template>
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
<script setup>
 | 
					 | 
				
			||||||
import { MusicOne, PlayWrong } from "@icon-park/vue-next";
 | 
					 | 
				
			||||||
import aplayer from "vue3-aplayer";
 | 
					 | 
				
			||||||
import {
 | 
					 | 
				
			||||||
  h,
 | 
					 | 
				
			||||||
  ref,
 | 
					 | 
				
			||||||
  reactive,
 | 
					 | 
				
			||||||
  nextTick,
 | 
					 | 
				
			||||||
  onMounted,
 | 
					 | 
				
			||||||
  onBeforeUnmount,
 | 
					 | 
				
			||||||
  watch,
 | 
					 | 
				
			||||||
} from "vue";
 | 
					 | 
				
			||||||
import { getPlayerList } from "@/api";
 | 
					 | 
				
			||||||
import { mainStore } from "@/store";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const store = mainStore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 获取播放器 DOM
 | 
					 | 
				
			||||||
const player = ref(null);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 歌曲播放列表
 | 
					 | 
				
			||||||
let playList = ref([]);
 | 
					 | 
				
			||||||
let playerLrc = ref("");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 歌曲播放项
 | 
					 | 
				
			||||||
let playIndex = ref(0);
 | 
					 | 
				
			||||||
let playListCount = ref(0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 配置项
 | 
					 | 
				
			||||||
const props = defineProps({
 | 
					 | 
				
			||||||
  // 音频自动播放
 | 
					 | 
				
			||||||
  autoplay: {
 | 
					 | 
				
			||||||
    type: Boolean,
 | 
					 | 
				
			||||||
    default: false,
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  // 主题色
 | 
					 | 
				
			||||||
  theme: {
 | 
					 | 
				
			||||||
    type: String,
 | 
					 | 
				
			||||||
    default: "#efefef",
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  // 音频循环播放
 | 
					 | 
				
			||||||
  repeat: {
 | 
					 | 
				
			||||||
    type: String,
 | 
					 | 
				
			||||||
    default: "list", //'list' | 'music' | 'none'
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  // 随机播放
 | 
					 | 
				
			||||||
  shuffle: {
 | 
					 | 
				
			||||||
    type: Boolean,
 | 
					 | 
				
			||||||
    default: false,
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  // 默认音量
 | 
					 | 
				
			||||||
  volume: {
 | 
					 | 
				
			||||||
    type: Number,
 | 
					 | 
				
			||||||
    default: 0.7,
 | 
					 | 
				
			||||||
    validator: (value) => {
 | 
					 | 
				
			||||||
      return value >= 0 && value <= 1;
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  // 歌曲服务器 ( netease-网易云, tencent-qq音乐, kugou-酷狗, xiami-小米音乐, baidu-百度音乐 )
 | 
					 | 
				
			||||||
  songServer: {
 | 
					 | 
				
			||||||
    type: String,
 | 
					 | 
				
			||||||
    default: "netease", //'netease' | 'tencent' | 'kugou' | 'xiami' | 'baidu'
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  // 播放类型 ( song-歌曲, playlist-播放列表, album-专辑, search-搜索, artist-艺术家 )
 | 
					 | 
				
			||||||
  songType: {
 | 
					 | 
				
			||||||
    type: String,
 | 
					 | 
				
			||||||
    default: "playlist",
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  // id
 | 
					 | 
				
			||||||
  songId: {
 | 
					 | 
				
			||||||
    type: String,
 | 
					 | 
				
			||||||
    default: "7452421335",
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  // 列表是否默认折叠
 | 
					 | 
				
			||||||
  listFolded: {
 | 
					 | 
				
			||||||
    type: Boolean,
 | 
					 | 
				
			||||||
    default: false,
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  // 列表最大高度
 | 
					 | 
				
			||||||
  listMaxHeight: {
 | 
					 | 
				
			||||||
    type: String,
 | 
					 | 
				
			||||||
    default: "420px",
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 初始化播放器
 | 
					 | 
				
			||||||
onMounted(() => {
 | 
					 | 
				
			||||||
  nextTick(() => {
 | 
					 | 
				
			||||||
    getPlayerList(props.songServer, props.songType, props.songId)
 | 
					 | 
				
			||||||
      .then((res) => {
 | 
					 | 
				
			||||||
        // 生成歌单信息
 | 
					 | 
				
			||||||
        playIndex.value = Math.floor(Math.random() * res.length);
 | 
					 | 
				
			||||||
        playListCount.value = res.length;
 | 
					 | 
				
			||||||
        // 更改播放器加载状态
 | 
					 | 
				
			||||||
        store.musicIsOk = true;
 | 
					 | 
				
			||||||
        console.log(
 | 
					 | 
				
			||||||
          "音乐加载完成",
 | 
					 | 
				
			||||||
          res,
 | 
					 | 
				
			||||||
          playIndex.value,
 | 
					 | 
				
			||||||
          playListCount.value,
 | 
					 | 
				
			||||||
          props.volume
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        // 生成歌单
 | 
					 | 
				
			||||||
        res.forEach((v) => {
 | 
					 | 
				
			||||||
          playList.value.push({
 | 
					 | 
				
			||||||
            title: v.name,
 | 
					 | 
				
			||||||
            artist: v.artist,
 | 
					 | 
				
			||||||
            src: v.url,
 | 
					 | 
				
			||||||
            pic: v.pic,
 | 
					 | 
				
			||||||
            lrc: v.lrc,
 | 
					 | 
				
			||||||
          });
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      })
 | 
					 | 
				
			||||||
      .catch(() => {
 | 
					 | 
				
			||||||
        store.musicIsOk = false;
 | 
					 | 
				
			||||||
        ElMessage({
 | 
					 | 
				
			||||||
          message: "播放器加载失败",
 | 
					 | 
				
			||||||
          grouping: true,
 | 
					 | 
				
			||||||
          icon: h(PlayWrong, {
 | 
					 | 
				
			||||||
            theme: "filled",
 | 
					 | 
				
			||||||
            fill: "#efefef",
 | 
					 | 
				
			||||||
          }),
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 播放暂停事件
 | 
					 | 
				
			||||||
const onPlay = () => {
 | 
					 | 
				
			||||||
  console.log("播放");
 | 
					 | 
				
			||||||
  // 播放状态
 | 
					 | 
				
			||||||
  store.setPlayerState(player.value.audio.paused);
 | 
					 | 
				
			||||||
  // 储存播放器信息
 | 
					 | 
				
			||||||
  store.setPlayerData(
 | 
					 | 
				
			||||||
    player.value.currentMusic.title,
 | 
					 | 
				
			||||||
    player.value.currentMusic.artist
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
  ElMessage({
 | 
					 | 
				
			||||||
    message: store.getPlayerData.name + " - " + store.getPlayerData.artist,
 | 
					 | 
				
			||||||
    grouping: true,
 | 
					 | 
				
			||||||
    icon: h(MusicOne, {
 | 
					 | 
				
			||||||
      theme: "filled",
 | 
					 | 
				
			||||||
      fill: "#efefef",
 | 
					 | 
				
			||||||
    }),
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
const onPause = () => {
 | 
					 | 
				
			||||||
  store.setPlayerState(player.value.audio.paused);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 音频时间更新事件
 | 
					 | 
				
			||||||
const onTimeUp = () => {
 | 
					 | 
				
			||||||
  let playerRef = player.value.$.vnode.el;
 | 
					 | 
				
			||||||
  if (playerRef) {
 | 
					 | 
				
			||||||
    playerLrc.value = playerRef.getElementsByClassName(
 | 
					 | 
				
			||||||
      "aplayer-lrc-current"
 | 
					 | 
				
			||||||
    )[0].innerHTML;
 | 
					 | 
				
			||||||
    store.setPlayerLrc(playerLrc.value);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 切换播放暂停事件
 | 
					 | 
				
			||||||
const playToggle = () => {
 | 
					 | 
				
			||||||
  player.value.toggle();
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 切换音量事件
 | 
					 | 
				
			||||||
const changeVolume = (value) => {
 | 
					 | 
				
			||||||
  player.value.audio.volume = value;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const onSelectSong = (val) => {
 | 
					 | 
				
			||||||
  console.log(val);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 切换上下曲
 | 
					 | 
				
			||||||
const changeSong = (type) => {
 | 
					 | 
				
			||||||
  playIndex.value = player.value.playIndex;
 | 
					 | 
				
			||||||
  playIndex.value += type ? 1 : -1;
 | 
					 | 
				
			||||||
  // 判断是否处于最后/第一首
 | 
					 | 
				
			||||||
  if (playIndex.value < 0) {
 | 
					 | 
				
			||||||
    playIndex.value = playListCount.value - 1;
 | 
					 | 
				
			||||||
  } else if (playIndex.value >= playListCount.value) {
 | 
					 | 
				
			||||||
    playIndex.value = 0;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  // console.log(playIndex.value, playList.value[playIndex.value]);
 | 
					 | 
				
			||||||
  nextTick(() => {
 | 
					 | 
				
			||||||
    player.value.play();
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 暴露子组件方法
 | 
					 | 
				
			||||||
defineExpose({ playToggle, changeVolume, changeSong });
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
<style lang='scss' scoped>
 | 
					 | 
				
			||||||
.aplayer {
 | 
					 | 
				
			||||||
  width: 80%;
 | 
					 | 
				
			||||||
  background: transparent;
 | 
					 | 
				
			||||||
  border-radius: 6px;
 | 
					 | 
				
			||||||
  :deep(.aplayer-body) {
 | 
					 | 
				
			||||||
    .aplayer-pic {
 | 
					 | 
				
			||||||
      display: none;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    .aplayer-info {
 | 
					 | 
				
			||||||
      margin-left: 0;
 | 
					 | 
				
			||||||
      background-color: #ffffff40;
 | 
					 | 
				
			||||||
      border-color: transparent;
 | 
					 | 
				
			||||||
      .aplayer-music {
 | 
					 | 
				
			||||||
        flex-grow: initial;
 | 
					 | 
				
			||||||
        margin-bottom: 2px;
 | 
					 | 
				
			||||||
        overflow: initial;
 | 
					 | 
				
			||||||
        .aplayer-title {
 | 
					 | 
				
			||||||
          font-size: 16px;
 | 
					 | 
				
			||||||
          margin-right: 6px;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        .aplayer-author {
 | 
					 | 
				
			||||||
          color: #efefef;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      .aplayer-lrc {
 | 
					 | 
				
			||||||
        text-align: left;
 | 
					 | 
				
			||||||
        margin: 4px 0 6px 6px;
 | 
					 | 
				
			||||||
        height: 100%;
 | 
					 | 
				
			||||||
        mask: linear-gradient(
 | 
					 | 
				
			||||||
          180deg,
 | 
					 | 
				
			||||||
          hsla(0, 0%, 100%, 0) 0,
 | 
					 | 
				
			||||||
          hsla(0, 0%, 100%, 0.6) 10%,
 | 
					 | 
				
			||||||
          #fff 15%,
 | 
					 | 
				
			||||||
          #fff 85%,
 | 
					 | 
				
			||||||
          hsla(0, 0%, 100%, 0.6) 90%,
 | 
					 | 
				
			||||||
          hsla(0, 0%, 100%, 0)
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        -webkit-mask: linear-gradient(
 | 
					 | 
				
			||||||
          180deg,
 | 
					 | 
				
			||||||
          hsla(0, 0%, 100%, 0) 0,
 | 
					 | 
				
			||||||
          hsla(0, 0%, 100%, 0.6) 10%,
 | 
					 | 
				
			||||||
          #fff 15%,
 | 
					 | 
				
			||||||
          #fff 85%,
 | 
					 | 
				
			||||||
          hsla(0, 0%, 100%, 0.6) 90%,
 | 
					 | 
				
			||||||
          hsla(0, 0%, 100%, 0)
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        &::before,
 | 
					 | 
				
			||||||
        &::after {
 | 
					 | 
				
			||||||
          display: none;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        p {
 | 
					 | 
				
			||||||
          color: #efefef;
 | 
					 | 
				
			||||||
          margin: 2px 0;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        .aplayer-lrc-current {
 | 
					 | 
				
			||||||
          font-size: 0.95rem;
 | 
					 | 
				
			||||||
          margin-bottom: 4px !important;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      .aplayer-controller {
 | 
					 | 
				
			||||||
        display: none;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  :deep(.aplayer-list) {
 | 
					 | 
				
			||||||
    margin-top: 6px;
 | 
					 | 
				
			||||||
    ol {
 | 
					 | 
				
			||||||
      &::-webkit-scrollbar-track{
 | 
					 | 
				
			||||||
        background-color: transparent;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      li {
 | 
					 | 
				
			||||||
        border-color: transparent;
 | 
					 | 
				
			||||||
        &.aplayer-list-light {
 | 
					 | 
				
			||||||
          background: #ffffff40;
 | 
					 | 
				
			||||||
          border-radius: 6px;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        &:hover {
 | 
					 | 
				
			||||||
          background: #ffffff26 !important;
 | 
					 | 
				
			||||||
          border-radius: 6px !important;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        .aplayer-list-index,
 | 
					 | 
				
			||||||
        .aplayer-list-author {
 | 
					 | 
				
			||||||
          color: #efefef;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
</style>
 | 
					 | 
				
			||||||
@ -1,11 +1,27 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div ref="playerRef"></div>
 | 
					  <aplayer
 | 
				
			||||||
 | 
					    showLrc
 | 
				
			||||||
 | 
					    ref="player"
 | 
				
			||||||
 | 
					    v-if="playList[0]"
 | 
				
			||||||
 | 
					    :music="playList[playIndex]"
 | 
				
			||||||
 | 
					    :list="playList"
 | 
				
			||||||
 | 
					    :autoplay="autoplay"
 | 
				
			||||||
 | 
					    :theme="theme"
 | 
				
			||||||
 | 
					    :repeat="repeat"
 | 
				
			||||||
 | 
					    :shuffle="shuffle"
 | 
				
			||||||
 | 
					    :listMaxHeight="listMaxHeight"
 | 
				
			||||||
 | 
					    :listFolded="listFolded"
 | 
				
			||||||
 | 
					    :volume="volume"
 | 
				
			||||||
 | 
					    @play="onPlay"
 | 
				
			||||||
 | 
					    @pause="onPause"
 | 
				
			||||||
 | 
					    @timeupdate="onTimeUp"
 | 
				
			||||||
 | 
					    @onSelectSong="onSelectSong"
 | 
				
			||||||
 | 
					  />
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
<script setup>
 | 
					<script setup>
 | 
				
			||||||
import { MusicOne, PlayWrong } from "@icon-park/vue-next";
 | 
					import { MusicOne, PlayWrong } from "@icon-park/vue-next";
 | 
				
			||||||
import APlayer from "APlayer";
 | 
					import aplayer from "vue3-aplayer";
 | 
				
			||||||
import "aplayer/dist/APlayer.min.css";
 | 
					 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  h,
 | 
					  h,
 | 
				
			||||||
  ref,
 | 
					  ref,
 | 
				
			||||||
@ -17,51 +33,22 @@ import {
 | 
				
			|||||||
} from "vue";
 | 
					} from "vue";
 | 
				
			||||||
import { getPlayerList } from "@/api";
 | 
					import { getPlayerList } from "@/api";
 | 
				
			||||||
import { mainStore } from "@/store";
 | 
					import { mainStore } from "@/store";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const store = mainStore();
 | 
					const store = mainStore();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const playerRef = ref();
 | 
					// 获取播放器 DOM
 | 
				
			||||||
const state = reactive({
 | 
					const player = ref(null);
 | 
				
			||||||
  instance: null,
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
const playerData = reactive({
 | 
					 | 
				
			||||||
  name: null,
 | 
					 | 
				
			||||||
  artist: null,
 | 
					 | 
				
			||||||
  lrc: null,
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// APlayer歌曲信息
 | 
					// 歌曲播放列表
 | 
				
			||||||
class Audio {
 | 
					let playList = ref([]);
 | 
				
			||||||
  // 音频艺术家
 | 
					let playerLrc = ref("");
 | 
				
			||||||
  // artist: String;
 | 
					 | 
				
			||||||
  // 音频名称
 | 
					 | 
				
			||||||
  // name: String;
 | 
					 | 
				
			||||||
  // 音频链接
 | 
					 | 
				
			||||||
  // url: String;
 | 
					 | 
				
			||||||
  // 音频封面
 | 
					 | 
				
			||||||
  // cover: String;
 | 
					 | 
				
			||||||
  // 歌词
 | 
					 | 
				
			||||||
  // lrc: String;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(artist, name, url, cover, lrc) {
 | 
					// 歌曲播放项
 | 
				
			||||||
    this.artist = artist;
 | 
					let playIndex = ref(0);
 | 
				
			||||||
    this.name = name;
 | 
					let playListCount = ref(0);
 | 
				
			||||||
    this.url = url;
 | 
					 | 
				
			||||||
    this.cover = cover;
 | 
					 | 
				
			||||||
    this.lrc = lrc;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 配置项
 | 
				
			||||||
const props = defineProps({
 | 
					const props = defineProps({
 | 
				
			||||||
  // 开启吸底模式
 | 
					 | 
				
			||||||
  fixed: {
 | 
					 | 
				
			||||||
    type: Boolean,
 | 
					 | 
				
			||||||
    default: false,
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  // 开启迷你模式
 | 
					 | 
				
			||||||
  mini: {
 | 
					 | 
				
			||||||
    type: Boolean,
 | 
					 | 
				
			||||||
    default: false,
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  // 音频自动播放
 | 
					  // 音频自动播放
 | 
				
			||||||
  autoplay: {
 | 
					  autoplay: {
 | 
				
			||||||
    type: Boolean,
 | 
					    type: Boolean,
 | 
				
			||||||
@ -73,19 +60,14 @@ const props = defineProps({
 | 
				
			|||||||
    default: "#efefef",
 | 
					    default: "#efefef",
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  // 音频循环播放
 | 
					  // 音频循环播放
 | 
				
			||||||
  loop: {
 | 
					  repeat: {
 | 
				
			||||||
    type: String,
 | 
					    type: String,
 | 
				
			||||||
    default: "all", //'all' | 'one' | 'none'
 | 
					    default: "list", //'list' | 'music' | 'none'
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  // 音频循环顺序
 | 
					  // 随机播放
 | 
				
			||||||
  order: {
 | 
					  shuffle: {
 | 
				
			||||||
    type: String,
 | 
					    type: Boolean,
 | 
				
			||||||
    default: "random", //'list' | 'random'
 | 
					    default: false,
 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  // 预加载
 | 
					 | 
				
			||||||
  preload: {
 | 
					 | 
				
			||||||
    type: String,
 | 
					 | 
				
			||||||
    default: "auto", //'auto' | 'metadata' | 'none'
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  // 默认音量
 | 
					  // 默认音量
 | 
				
			||||||
  volume: {
 | 
					  volume: {
 | 
				
			||||||
@ -110,16 +92,6 @@ const props = defineProps({
 | 
				
			|||||||
    type: String,
 | 
					    type: String,
 | 
				
			||||||
    default: "7452421335",
 | 
					    default: "7452421335",
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  // 互斥,阻止多个播放器同时播放,当前播放器播放时暂停其他播放器
 | 
					 | 
				
			||||||
  mutex: {
 | 
					 | 
				
			||||||
    type: Boolean,
 | 
					 | 
				
			||||||
    default: true,
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  // 传递歌词方式
 | 
					 | 
				
			||||||
  lrcType: {
 | 
					 | 
				
			||||||
    type: Number,
 | 
					 | 
				
			||||||
    default: 3,
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  // 列表是否默认折叠
 | 
					  // 列表是否默认折叠
 | 
				
			||||||
  listFolded: {
 | 
					  listFolded: {
 | 
				
			||||||
    type: Boolean,
 | 
					    type: Boolean,
 | 
				
			||||||
@ -130,11 +102,6 @@ const props = defineProps({
 | 
				
			|||||||
    type: String,
 | 
					    type: String,
 | 
				
			||||||
    default: "420px",
 | 
					    default: "420px",
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  // 存储播放器设置的 localStorage key
 | 
					 | 
				
			||||||
  storageName: {
 | 
					 | 
				
			||||||
    type: String,
 | 
					 | 
				
			||||||
    default: "aplayer-setting",
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 初始化播放器
 | 
					// 初始化播放器
 | 
				
			||||||
@ -142,67 +109,28 @@ onMounted(() => {
 | 
				
			|||||||
  nextTick(() => {
 | 
					  nextTick(() => {
 | 
				
			||||||
    getPlayerList(props.songServer, props.songType, props.songId)
 | 
					    getPlayerList(props.songServer, props.songType, props.songId)
 | 
				
			||||||
      .then((res) => {
 | 
					      .then((res) => {
 | 
				
			||||||
        // console.log(res);
 | 
					        // 生成歌单信息
 | 
				
			||||||
 | 
					        playIndex.value = Math.floor(Math.random() * res.length);
 | 
				
			||||||
 | 
					        playListCount.value = res.length;
 | 
				
			||||||
        // 更改播放器加载状态
 | 
					        // 更改播放器加载状态
 | 
				
			||||||
        store.musicIsOk = true;
 | 
					        store.musicIsOk = true;
 | 
				
			||||||
        console.log("音乐加载完成");
 | 
					        console.log(
 | 
				
			||||||
        let audioList = res.map(
 | 
					          "音乐加载完成",
 | 
				
			||||||
          (value) =>
 | 
					          res,
 | 
				
			||||||
            new Audio(value.artist, value.name, value.url, value.pic, value.lrc)
 | 
					          playIndex.value,
 | 
				
			||||||
 | 
					          playListCount.value,
 | 
				
			||||||
 | 
					          props.volume
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        state.instance = new APlayer({
 | 
					        // 生成歌单
 | 
				
			||||||
          container: playerRef.value,
 | 
					        res.forEach((v) => {
 | 
				
			||||||
          fixed: props.fixed,
 | 
					          playList.value.push({
 | 
				
			||||||
          mini: props.mini,
 | 
					            title: v.name,
 | 
				
			||||||
          autoplay: props.autoplay,
 | 
					            artist: v.artist,
 | 
				
			||||||
          theme: props.theme,
 | 
					            src: v.url,
 | 
				
			||||||
          loop: props.loop,
 | 
					            pic: v.pic,
 | 
				
			||||||
          order: props.order,
 | 
					            lrc: v.lrc,
 | 
				
			||||||
          preload: props.preload,
 | 
					 | 
				
			||||||
          volume: props.volume,
 | 
					 | 
				
			||||||
          mutex: props.mutex,
 | 
					 | 
				
			||||||
          lrcType: props.lrcType,
 | 
					 | 
				
			||||||
          listFolded: props.listFolded,
 | 
					 | 
				
			||||||
          listMaxHeight: props.listMaxHeight,
 | 
					 | 
				
			||||||
          storageName: props.storageName,
 | 
					 | 
				
			||||||
          audio: audioList,
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        state.instance.on("play", () => {
 | 
					 | 
				
			||||||
          // 播放状态
 | 
					 | 
				
			||||||
          store.setPlayerState(state.instance.audio.paused);
 | 
					 | 
				
			||||||
          // 储存播放器信息
 | 
					 | 
				
			||||||
          store.setPlayerData(
 | 
					 | 
				
			||||||
            playerRef.value.getElementsByClassName("aplayer-title")[0]
 | 
					 | 
				
			||||||
              .innerHTML,
 | 
					 | 
				
			||||||
            playerRef.value
 | 
					 | 
				
			||||||
              .getElementsByClassName("aplayer-author")[0]
 | 
					 | 
				
			||||||
              .innerHTML.split("-")[1]
 | 
					 | 
				
			||||||
              .trim()
 | 
					 | 
				
			||||||
          );
 | 
					 | 
				
			||||||
          ElMessage({
 | 
					 | 
				
			||||||
            message:
 | 
					 | 
				
			||||||
              store.getPlayerData.name + " - " + store.getPlayerData.artist,
 | 
					 | 
				
			||||||
            grouping: true,
 | 
					 | 
				
			||||||
            icon: h(MusicOne, {
 | 
					 | 
				
			||||||
              theme: "filled",
 | 
					 | 
				
			||||||
              fill: "#efefef",
 | 
					 | 
				
			||||||
            }),
 | 
					 | 
				
			||||||
          });
 | 
					          });
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					 | 
				
			||||||
        state.instance.on("pause", () => {
 | 
					 | 
				
			||||||
          // 播放状态
 | 
					 | 
				
			||||||
          store.setPlayerState(state.instance.audio.paused);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        state.instance.on("timeupdate", () => {
 | 
					 | 
				
			||||||
          if (playerRef.value) {
 | 
					 | 
				
			||||||
            playerData.lrc = playerRef.value.getElementsByClassName(
 | 
					 | 
				
			||||||
              "aplayer-lrc-current"
 | 
					 | 
				
			||||||
            )[0].innerHTML;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
      .catch(() => {
 | 
					      .catch(() => {
 | 
				
			||||||
        store.musicIsOk = false;
 | 
					        store.musicIsOk = false;
 | 
				
			||||||
@ -218,41 +146,72 @@ onMounted(() => {
 | 
				
			|||||||
  });
 | 
					  });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 销毁播放器
 | 
					// 播放暂停事件
 | 
				
			||||||
onBeforeUnmount(() => {
 | 
					const onPlay = () => {
 | 
				
			||||||
  state.instance.destroy();
 | 
					  console.log("播放");
 | 
				
			||||||
});
 | 
					  // 播放状态
 | 
				
			||||||
 | 
					  store.setPlayerState(player.value.audio.paused);
 | 
				
			||||||
 | 
					  // 储存播放器信息
 | 
				
			||||||
 | 
					  store.setPlayerData(
 | 
				
			||||||
 | 
					    player.value.currentMusic.title,
 | 
				
			||||||
 | 
					    player.value.currentMusic.artist
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					  ElMessage({
 | 
				
			||||||
 | 
					    message: store.getPlayerData.name + " - " + store.getPlayerData.artist,
 | 
				
			||||||
 | 
					    grouping: true,
 | 
				
			||||||
 | 
					    icon: h(MusicOne, {
 | 
				
			||||||
 | 
					      theme: "filled",
 | 
				
			||||||
 | 
					      fill: "#efefef",
 | 
				
			||||||
 | 
					    }),
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					const onPause = () => {
 | 
				
			||||||
 | 
					  store.setPlayerState(player.value.audio.paused);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 音频时间更新事件
 | 
				
			||||||
 | 
					const onTimeUp = () => {
 | 
				
			||||||
 | 
					  let playerRef = player.value.$.vnode.el;
 | 
				
			||||||
 | 
					  if (playerRef) {
 | 
				
			||||||
 | 
					    playerLrc.value = playerRef.getElementsByClassName(
 | 
				
			||||||
 | 
					      "aplayer-lrc-current"
 | 
				
			||||||
 | 
					    )[0].innerHTML;
 | 
				
			||||||
 | 
					    store.setPlayerLrc(playerLrc.value);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 切换播放暂停事件
 | 
					// 切换播放暂停事件
 | 
				
			||||||
const playToggle = () => {
 | 
					const playToggle = () => {
 | 
				
			||||||
  state.instance.toggle();
 | 
					  player.value.toggle();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 切换音量事件
 | 
					// 切换音量事件
 | 
				
			||||||
const changeVolume = (value) => {
 | 
					const changeVolume = (value) => {
 | 
				
			||||||
  state.instance.volume(value);
 | 
					  player.value.audio.volume = value;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const onSelectSong = (val) => {
 | 
				
			||||||
 | 
					  console.log(val);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 切换上下曲
 | 
					// 切换上下曲
 | 
				
			||||||
const changeSongPrev = () => {
 | 
					const changeSong = (type) => {
 | 
				
			||||||
  state.instance.skipBack();
 | 
					  playIndex.value = player.value.playIndex;
 | 
				
			||||||
};
 | 
					  playIndex.value += type ? 1 : -1;
 | 
				
			||||||
const changeSongNext = () => {
 | 
					  // 判断是否处于最后/第一首
 | 
				
			||||||
  state.instance.skipForward();
 | 
					  if (playIndex.value < 0) {
 | 
				
			||||||
 | 
					    playIndex.value = playListCount.value - 1;
 | 
				
			||||||
 | 
					  } else if (playIndex.value >= playListCount.value) {
 | 
				
			||||||
 | 
					    playIndex.value = 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // console.log(playIndex.value, playList.value[playIndex.value]);
 | 
				
			||||||
 | 
					  nextTick(() => {
 | 
				
			||||||
 | 
					    player.value.play();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 暴露子组件方法
 | 
					// 暴露子组件方法
 | 
				
			||||||
defineExpose({ playToggle, changeVolume, changeSongPrev, changeSongNext });
 | 
					defineExpose({ playToggle, changeVolume, changeSong });
 | 
				
			||||||
 | 
					 | 
				
			||||||
// 监听歌词变化
 | 
					 | 
				
			||||||
watch(
 | 
					 | 
				
			||||||
  () => playerData.lrc,
 | 
					 | 
				
			||||||
  (value) => {
 | 
					 | 
				
			||||||
    console.log(value);
 | 
					 | 
				
			||||||
    // 储存至 pinia
 | 
					 | 
				
			||||||
    store.setPlayerLrc(value);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
<style lang='scss' scoped>
 | 
					<style lang='scss' scoped>
 | 
				
			||||||
@ -268,22 +227,47 @@ watch(
 | 
				
			|||||||
      margin-left: 0;
 | 
					      margin-left: 0;
 | 
				
			||||||
      background-color: #ffffff40;
 | 
					      background-color: #ffffff40;
 | 
				
			||||||
      border-color: transparent;
 | 
					      border-color: transparent;
 | 
				
			||||||
      .aplayer-title {
 | 
					      .aplayer-music {
 | 
				
			||||||
        font-size: 16px;
 | 
					        flex-grow: initial;
 | 
				
			||||||
      }
 | 
					        margin-bottom: 2px;
 | 
				
			||||||
      .aplayer-author {
 | 
					        overflow: initial;
 | 
				
			||||||
        color: #efefef;
 | 
					        .aplayer-title {
 | 
				
			||||||
 | 
					          font-size: 16px;
 | 
				
			||||||
 | 
					          margin-right: 6px;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .aplayer-author {
 | 
				
			||||||
 | 
					          color: #efefef;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      .aplayer-lrc {
 | 
					      .aplayer-lrc {
 | 
				
			||||||
        text-align: left;
 | 
					        text-align: left;
 | 
				
			||||||
        margin: 4px 0 0 6px;
 | 
					        margin: 4px 0 6px 6px;
 | 
				
			||||||
        height: 38px;
 | 
					        height: 100%;
 | 
				
			||||||
 | 
					        mask: linear-gradient(
 | 
				
			||||||
 | 
					          180deg,
 | 
				
			||||||
 | 
					          hsla(0, 0%, 100%, 0) 0,
 | 
				
			||||||
 | 
					          hsla(0, 0%, 100%, 0.6) 10%,
 | 
				
			||||||
 | 
					          #fff 15%,
 | 
				
			||||||
 | 
					          #fff 85%,
 | 
				
			||||||
 | 
					          hsla(0, 0%, 100%, 0.6) 90%,
 | 
				
			||||||
 | 
					          hsla(0, 0%, 100%, 0)
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        -webkit-mask: linear-gradient(
 | 
				
			||||||
 | 
					          180deg,
 | 
				
			||||||
 | 
					          hsla(0, 0%, 100%, 0) 0,
 | 
				
			||||||
 | 
					          hsla(0, 0%, 100%, 0.6) 10%,
 | 
				
			||||||
 | 
					          #fff 15%,
 | 
				
			||||||
 | 
					          #fff 85%,
 | 
				
			||||||
 | 
					          hsla(0, 0%, 100%, 0.6) 90%,
 | 
				
			||||||
 | 
					          hsla(0, 0%, 100%, 0)
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
        &::before,
 | 
					        &::before,
 | 
				
			||||||
        &::after {
 | 
					        &::after {
 | 
				
			||||||
          display: none;
 | 
					          display: none;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        p {
 | 
					        p {
 | 
				
			||||||
          color: #efefef;
 | 
					          color: #efefef;
 | 
				
			||||||
 | 
					          margin: 2px 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        .aplayer-lrc-current {
 | 
					        .aplayer-lrc-current {
 | 
				
			||||||
          font-size: 0.95rem;
 | 
					          font-size: 0.95rem;
 | 
				
			||||||
@ -298,6 +282,9 @@ watch(
 | 
				
			|||||||
  :deep(.aplayer-list) {
 | 
					  :deep(.aplayer-list) {
 | 
				
			||||||
    margin-top: 6px;
 | 
					    margin-top: 6px;
 | 
				
			||||||
    ol {
 | 
					    ol {
 | 
				
			||||||
 | 
					      &::-webkit-scrollbar-track{
 | 
				
			||||||
 | 
					        background-color: transparent;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      li {
 | 
					      li {
 | 
				
			||||||
        border-color: transparent;
 | 
					        border-color: transparent;
 | 
				
			||||||
        &.aplayer-list-light {
 | 
					        &.aplayer-list-light {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										319
									
								
								src/components/Player/old.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										319
									
								
								src/components/Player/old.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,319 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div ref="playerRef"></div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					<script setup>
 | 
				
			||||||
 | 
					import { MusicOne, PlayWrong } from "@icon-park/vue-next";
 | 
				
			||||||
 | 
					import APlayer from "APlayer";
 | 
				
			||||||
 | 
					import "aplayer/dist/APlayer.min.css";
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  h,
 | 
				
			||||||
 | 
					  ref,
 | 
				
			||||||
 | 
					  reactive,
 | 
				
			||||||
 | 
					  nextTick,
 | 
				
			||||||
 | 
					  onMounted,
 | 
				
			||||||
 | 
					  onBeforeUnmount,
 | 
				
			||||||
 | 
					  watch,
 | 
				
			||||||
 | 
					} from "vue";
 | 
				
			||||||
 | 
					import { getPlayerList } from "@/api";
 | 
				
			||||||
 | 
					import { mainStore } from "@/store";
 | 
				
			||||||
 | 
					const store = mainStore();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const playerRef = ref();
 | 
				
			||||||
 | 
					const state = reactive({
 | 
				
			||||||
 | 
					  instance: null,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					const playerData = reactive({
 | 
				
			||||||
 | 
					  name: null,
 | 
				
			||||||
 | 
					  artist: null,
 | 
				
			||||||
 | 
					  lrc: null,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// APlayer歌曲信息
 | 
				
			||||||
 | 
					class Audio {
 | 
				
			||||||
 | 
					  // 音频艺术家
 | 
				
			||||||
 | 
					  // artist: String;
 | 
				
			||||||
 | 
					  // 音频名称
 | 
				
			||||||
 | 
					  // name: String;
 | 
				
			||||||
 | 
					  // 音频链接
 | 
				
			||||||
 | 
					  // url: String;
 | 
				
			||||||
 | 
					  // 音频封面
 | 
				
			||||||
 | 
					  // cover: String;
 | 
				
			||||||
 | 
					  // 歌词
 | 
				
			||||||
 | 
					  // lrc: String;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  constructor(artist, name, url, cover, lrc) {
 | 
				
			||||||
 | 
					    this.artist = artist;
 | 
				
			||||||
 | 
					    this.name = name;
 | 
				
			||||||
 | 
					    this.url = url;
 | 
				
			||||||
 | 
					    this.cover = cover;
 | 
				
			||||||
 | 
					    this.lrc = lrc;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const props = defineProps({
 | 
				
			||||||
 | 
					  // 开启吸底模式
 | 
				
			||||||
 | 
					  fixed: {
 | 
				
			||||||
 | 
					    type: Boolean,
 | 
				
			||||||
 | 
					    default: false,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  // 开启迷你模式
 | 
				
			||||||
 | 
					  mini: {
 | 
				
			||||||
 | 
					    type: Boolean,
 | 
				
			||||||
 | 
					    default: false,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  // 音频自动播放
 | 
				
			||||||
 | 
					  autoplay: {
 | 
				
			||||||
 | 
					    type: Boolean,
 | 
				
			||||||
 | 
					    default: false,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  // 主题色
 | 
				
			||||||
 | 
					  theme: {
 | 
				
			||||||
 | 
					    type: String,
 | 
				
			||||||
 | 
					    default: "#efefef",
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  // 音频循环播放
 | 
				
			||||||
 | 
					  loop: {
 | 
				
			||||||
 | 
					    type: String,
 | 
				
			||||||
 | 
					    default: "all", //'all' | 'one' | 'none'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  // 音频循环顺序
 | 
				
			||||||
 | 
					  order: {
 | 
				
			||||||
 | 
					    type: String,
 | 
				
			||||||
 | 
					    default: "random", //'list' | 'random'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  // 预加载
 | 
				
			||||||
 | 
					  preload: {
 | 
				
			||||||
 | 
					    type: String,
 | 
				
			||||||
 | 
					    default: "auto", //'auto' | 'metadata' | 'none'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  // 默认音量
 | 
				
			||||||
 | 
					  volume: {
 | 
				
			||||||
 | 
					    type: Number,
 | 
				
			||||||
 | 
					    default: 0.7,
 | 
				
			||||||
 | 
					    validator: (value) => {
 | 
				
			||||||
 | 
					      return value >= 0 && value <= 1;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  // 歌曲服务器 ( netease-网易云, tencent-qq音乐, kugou-酷狗, xiami-小米音乐, baidu-百度音乐 )
 | 
				
			||||||
 | 
					  songServer: {
 | 
				
			||||||
 | 
					    type: String,
 | 
				
			||||||
 | 
					    default: "netease", //'netease' | 'tencent' | 'kugou' | 'xiami' | 'baidu'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  // 播放类型 ( song-歌曲, playlist-播放列表, album-专辑, search-搜索, artist-艺术家 )
 | 
				
			||||||
 | 
					  songType: {
 | 
				
			||||||
 | 
					    type: String,
 | 
				
			||||||
 | 
					    default: "playlist",
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  // id
 | 
				
			||||||
 | 
					  songId: {
 | 
				
			||||||
 | 
					    type: String,
 | 
				
			||||||
 | 
					    default: "7452421335",
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  // 互斥,阻止多个播放器同时播放,当前播放器播放时暂停其他播放器
 | 
				
			||||||
 | 
					  mutex: {
 | 
				
			||||||
 | 
					    type: Boolean,
 | 
				
			||||||
 | 
					    default: true,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  // 传递歌词方式
 | 
				
			||||||
 | 
					  lrcType: {
 | 
				
			||||||
 | 
					    type: Number,
 | 
				
			||||||
 | 
					    default: 3,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  // 列表是否默认折叠
 | 
				
			||||||
 | 
					  listFolded: {
 | 
				
			||||||
 | 
					    type: Boolean,
 | 
				
			||||||
 | 
					    default: false,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  // 列表最大高度
 | 
				
			||||||
 | 
					  listMaxHeight: {
 | 
				
			||||||
 | 
					    type: String,
 | 
				
			||||||
 | 
					    default: "420px",
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  // 存储播放器设置的 localStorage key
 | 
				
			||||||
 | 
					  storageName: {
 | 
				
			||||||
 | 
					    type: String,
 | 
				
			||||||
 | 
					    default: "aplayer-setting",
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 初始化播放器
 | 
				
			||||||
 | 
					onMounted(() => {
 | 
				
			||||||
 | 
					  nextTick(() => {
 | 
				
			||||||
 | 
					    getPlayerList(props.songServer, props.songType, props.songId)
 | 
				
			||||||
 | 
					      .then((res) => {
 | 
				
			||||||
 | 
					        // console.log(res);
 | 
				
			||||||
 | 
					        // 更改播放器加载状态
 | 
				
			||||||
 | 
					        store.musicIsOk = true;
 | 
				
			||||||
 | 
					        console.log("音乐加载完成");
 | 
				
			||||||
 | 
					        let audioList = res.map(
 | 
				
			||||||
 | 
					          (value) =>
 | 
				
			||||||
 | 
					            new Audio(value.artist, value.name, value.url, value.pic, value.lrc)
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        state.instance = new APlayer({
 | 
				
			||||||
 | 
					          container: playerRef.value,
 | 
				
			||||||
 | 
					          fixed: props.fixed,
 | 
				
			||||||
 | 
					          mini: props.mini,
 | 
				
			||||||
 | 
					          autoplay: props.autoplay,
 | 
				
			||||||
 | 
					          theme: props.theme,
 | 
				
			||||||
 | 
					          loop: props.loop,
 | 
				
			||||||
 | 
					          order: props.order,
 | 
				
			||||||
 | 
					          preload: props.preload,
 | 
				
			||||||
 | 
					          volume: props.volume,
 | 
				
			||||||
 | 
					          mutex: props.mutex,
 | 
				
			||||||
 | 
					          lrcType: props.lrcType,
 | 
				
			||||||
 | 
					          listFolded: props.listFolded,
 | 
				
			||||||
 | 
					          listMaxHeight: props.listMaxHeight,
 | 
				
			||||||
 | 
					          storageName: props.storageName,
 | 
				
			||||||
 | 
					          audio: audioList,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        state.instance.on("play", () => {
 | 
				
			||||||
 | 
					          // 播放状态
 | 
				
			||||||
 | 
					          store.setPlayerState(state.instance.audio.paused);
 | 
				
			||||||
 | 
					          // 储存播放器信息
 | 
				
			||||||
 | 
					          store.setPlayerData(
 | 
				
			||||||
 | 
					            playerRef.value.getElementsByClassName("aplayer-title")[0]
 | 
				
			||||||
 | 
					              .innerHTML,
 | 
				
			||||||
 | 
					            playerRef.value
 | 
				
			||||||
 | 
					              .getElementsByClassName("aplayer-author")[0]
 | 
				
			||||||
 | 
					              .innerHTML.split("-")[1]
 | 
				
			||||||
 | 
					              .trim()
 | 
				
			||||||
 | 
					          );
 | 
				
			||||||
 | 
					          ElMessage({
 | 
				
			||||||
 | 
					            message:
 | 
				
			||||||
 | 
					              store.getPlayerData.name + " - " + store.getPlayerData.artist,
 | 
				
			||||||
 | 
					            grouping: true,
 | 
				
			||||||
 | 
					            icon: h(MusicOne, {
 | 
				
			||||||
 | 
					              theme: "filled",
 | 
				
			||||||
 | 
					              fill: "#efefef",
 | 
				
			||||||
 | 
					            }),
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        state.instance.on("pause", () => {
 | 
				
			||||||
 | 
					          // 播放状态
 | 
				
			||||||
 | 
					          store.setPlayerState(state.instance.audio.paused);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        state.instance.on("timeupdate", () => {
 | 
				
			||||||
 | 
					          if (playerRef.value) {
 | 
				
			||||||
 | 
					            playerData.lrc = playerRef.value.getElementsByClassName(
 | 
				
			||||||
 | 
					              "aplayer-lrc-current"
 | 
				
			||||||
 | 
					            )[0].innerHTML;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      .catch(() => {
 | 
				
			||||||
 | 
					        store.musicIsOk = false;
 | 
				
			||||||
 | 
					        ElMessage({
 | 
				
			||||||
 | 
					          message: "播放器加载失败",
 | 
				
			||||||
 | 
					          grouping: true,
 | 
				
			||||||
 | 
					          icon: h(PlayWrong, {
 | 
				
			||||||
 | 
					            theme: "filled",
 | 
				
			||||||
 | 
					            fill: "#efefef",
 | 
				
			||||||
 | 
					          }),
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 销毁播放器
 | 
				
			||||||
 | 
					onBeforeUnmount(() => {
 | 
				
			||||||
 | 
					  state.instance.destroy();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 切换播放暂停事件
 | 
				
			||||||
 | 
					const playToggle = () => {
 | 
				
			||||||
 | 
					  state.instance.toggle();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 切换音量事件
 | 
				
			||||||
 | 
					const changeVolume = (value) => {
 | 
				
			||||||
 | 
					  state.instance.volume(value);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 切换上下曲
 | 
				
			||||||
 | 
					const changeSongPrev = () => {
 | 
				
			||||||
 | 
					  state.instance.skipBack();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					const changeSongNext = () => {
 | 
				
			||||||
 | 
					  state.instance.skipForward();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 暴露子组件方法
 | 
				
			||||||
 | 
					defineExpose({ playToggle, changeVolume, changeSongPrev, changeSongNext });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 监听歌词变化
 | 
				
			||||||
 | 
					watch(
 | 
				
			||||||
 | 
					  () => playerData.lrc,
 | 
				
			||||||
 | 
					  (value) => {
 | 
				
			||||||
 | 
					    console.log(value);
 | 
				
			||||||
 | 
					    // 储存至 pinia
 | 
				
			||||||
 | 
					    store.setPlayerLrc(value);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					<style lang='scss' scoped>
 | 
				
			||||||
 | 
					.aplayer {
 | 
				
			||||||
 | 
					  width: 80%;
 | 
				
			||||||
 | 
					  background: transparent;
 | 
				
			||||||
 | 
					  border-radius: 6px;
 | 
				
			||||||
 | 
					  :deep(.aplayer-body) {
 | 
				
			||||||
 | 
					    .aplayer-pic {
 | 
				
			||||||
 | 
					      display: none;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .aplayer-info {
 | 
				
			||||||
 | 
					      margin-left: 0;
 | 
				
			||||||
 | 
					      background-color: #ffffff40;
 | 
				
			||||||
 | 
					      border-color: transparent;
 | 
				
			||||||
 | 
					      .aplayer-title {
 | 
				
			||||||
 | 
					        font-size: 16px;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      .aplayer-author {
 | 
				
			||||||
 | 
					        color: #efefef;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      .aplayer-lrc {
 | 
				
			||||||
 | 
					        text-align: left;
 | 
				
			||||||
 | 
					        margin: 4px 0 0 6px;
 | 
				
			||||||
 | 
					        height: 38px;
 | 
				
			||||||
 | 
					        &::before,
 | 
				
			||||||
 | 
					        &::after {
 | 
				
			||||||
 | 
					          display: none;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        p {
 | 
				
			||||||
 | 
					          color: #efefef;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .aplayer-lrc-current {
 | 
				
			||||||
 | 
					          font-size: 0.95rem;
 | 
				
			||||||
 | 
					          margin-bottom: 4px !important;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      .aplayer-controller {
 | 
				
			||||||
 | 
					        display: none;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  :deep(.aplayer-list) {
 | 
				
			||||||
 | 
					    margin-top: 6px;
 | 
				
			||||||
 | 
					    ol {
 | 
				
			||||||
 | 
					      li {
 | 
				
			||||||
 | 
					        border-color: transparent;
 | 
				
			||||||
 | 
					        &.aplayer-list-light {
 | 
				
			||||||
 | 
					          background: #ffffff40;
 | 
				
			||||||
 | 
					          border-radius: 6px;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        &:hover {
 | 
				
			||||||
 | 
					          background: #ffffff26 !important;
 | 
				
			||||||
 | 
					          border-radius: 6px !important;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .aplayer-list-index,
 | 
				
			||||||
 | 
					        .aplayer-list-author {
 | 
				
			||||||
 | 
					          color: #efefef;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
@ -34,7 +34,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<script setup>
 | 
					<script setup>
 | 
				
			||||||
import { ref, onMounted, onBeforeUnmount } from "vue";
 | 
					import { ref, onMounted, onBeforeUnmount } from "vue";
 | 
				
			||||||
import Music from "@/components/Music/test.vue";
 | 
					import Music from "@/components/Music/index.vue";
 | 
				
			||||||
import Hitokoto from "@/components/Hitokoto/index.vue";
 | 
					import Hitokoto from "@/components/Hitokoto/index.vue";
 | 
				
			||||||
import Weather from "@/components/Weather/index.vue";
 | 
					import Weather from "@/components/Weather/index.vue";
 | 
				
			||||||
import { getCurrentTime } from "@/utils/getTime";
 | 
					import { getCurrentTime } from "@/utils/getTime";
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user