84 lines
2.5 KiB
Vue
84 lines
2.5 KiB
Vue
<script setup>
|
|
import { ref, watch, onMounted, onBeforeUnmount } from "vue";
|
|
import audioManager from "@/audioManager";
|
|
import useStore from "@/store";
|
|
|
|
const store = useStore();
|
|
|
|
// 私有 HeaderProgress 只负责展示提示/箭数和静音开关。
|
|
// 报靶、轮到谁射箭、比赛结束等语音统一由 team-battle 页面队列播放,避免重复播报。
|
|
const tips = ref("");
|
|
const sound = ref(true);
|
|
const currentShot = ref(0);
|
|
const totalShot = ref(0);
|
|
|
|
const updateSound = () => {
|
|
sound.value = !sound.value;
|
|
audioManager.setMuted(!sound.value);
|
|
};
|
|
|
|
const onUpdateTips = (newVal) => {
|
|
// 兼容页面通过 uni.$emit("update-tips") 触发的即时刷新。
|
|
tips.value = newVal;
|
|
};
|
|
|
|
// 监听 Pinia store 中 totalShot 变化,用于比赛恢复时同步箭数(替代 uni.$emit 避免时序问题)
|
|
// 使用 immediate: true 确保组件创建时立即读取 store 当前值(解决重入时 totalShot 值不变 watch 不触发的问题)
|
|
watch(
|
|
() => [store.game.currentShot, store.game.totalShot],
|
|
([newCurrentShot, newTotalShot]) => {
|
|
currentShot.value = newCurrentShot || 0;
|
|
totalShot.value = newTotalShot || 0;
|
|
},
|
|
{ immediate: true }
|
|
);
|
|
|
|
// 监听 Pinia store 中 tips 变化,用于比赛恢复时同步提示文案(替代 uni.$emit 避免时序问题)
|
|
// 使用 immediate: true 确保组件创建时立即读取 store 当前值(解决 onShow 早于 onMounted 导致 uni.$emit 事件丢失的问题)
|
|
// 注意:使用 != null 而非 if(newVal),确保空字符串 "" 也能触发清空(避免重新开赛时旧文案残留)
|
|
watch(() => store.game.tips, (newVal) => {
|
|
if (newVal != null) {
|
|
tips.value = newVal;
|
|
}
|
|
}, { immediate: true });
|
|
|
|
onMounted(() => {
|
|
uni.$on("update-tips", onUpdateTips);
|
|
});
|
|
|
|
onBeforeUnmount(() => {
|
|
uni.$off("update-tips", onUpdateTips);
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<view class="container">
|
|
<text>{{ (tips || "").replace(/你/g, "").replace(/重回/g, "") }}</text>
|
|
<text v-if="totalShot > 0"> ({{ currentShot }}/{{ totalShot }}) </text>
|
|
<button v-if="!!tips" hover-class="none" @click="updateSound">
|
|
<image :src="`../../../static/sound${sound ? '' : '-off'}-yellow.png`" mode="widthFix" />
|
|
</button>
|
|
</view>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.container {
|
|
width: 50vw;
|
|
color: #fed847;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.container>button:last-child {
|
|
width: 36px;
|
|
height: 36px;
|
|
}
|
|
|
|
.container>button:last-child>image {
|
|
width: 36px;
|
|
min-height: 36px;
|
|
}
|
|
</style>
|