aslan-h5/src/components/GeneralHeader.vue

294 lines
5.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div>
<!-- 状态栏占位区域仅在APP中显示 -->
<div v-if="isInAppEnvironment" style="height: 30px"></div>
<!-- header内容 -->
<div
style="
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 16px;
height: 60px;
"
>
<!-- 返回键 -->
<div style="width: 6%; display: flex; align-items: center">
<button v-if="showBack" class="back-btn" @click="handleBack">
<img
v-smart-img
class="flipImg"
:src="backImg"
alt=""
style="width: 100%; aspect-ratio: 1/1; display: block"
/>
</button>
</div>
<!-- 标题 -->
<h1
style="
font-size: 1.2em;
font-weight: 600;
margin: 0;
text-align: center;
flex: 1;
letter-spacing: 0.3px;
"
:style="{ color }"
>
{{ title }}
</h1>
<!-- 右侧按钮 -->
<!-- 帮助按钮 -->
<button v-if="showHelp" class="help-btn" style="width: 10%" @click="$emit('help')">
<img
v-smart-img
src="../assets/icon/helpWhite.png"
alt=""
style="width: 100%; display: block"
/>
</button>
<!-- 语言切换 -->
<div
v-if="showLanguageList"
style="
display: flex;
align-items: center;
position: relative;
color: rgba(187, 146, 255, 1) !important;
"
@click="showLang"
>
<div style="font-weight: bold">{{ currentLangName }}</div>
<transition name="slide-fade">
<div v-show="visibleList" class="extraList">
<div
style="padding: 8px; color: black !important; font-weight: 590"
v-for="lang in langStore.langList"
@click.stop="handleLanguageChange(lang)"
>
{{ lang.value }}
</div>
</div>
</transition>
</div>
<!-- 插槽 -->
<slot name="extraFunction"></slot>
</div>
</div>
</template>
<script setup>
import { computed, ref, onMounted, watch, nextTick } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useLangStore } from '@/stores/lang'
import { setLocale } from '@/locales/i18n'
import { isInApp, closePage } from '@/utils/appBridge.js'
// 定义props
const props = defineProps({
// 标题
title: {
type: String,
required: true,
},
// 是否显示返回按钮
showBack: {
type: Boolean,
default: true,
},
// 是否显示帮助按钮
showHelp: {
type: Boolean,
default: false,
},
// 是否为首页
isHomePage: {
type: Boolean,
default: false,
},
// 是否显示语言列表
showLanguageList: {
type: Boolean,
default: false,
},
// 标题颜色
color: {
type: String,
default: '#fff',
},
// 返回图标
backImg: {
type: String,
default: () => {
return new URL('../assets/icon/arrowBack.png', import.meta.url).href
},
},
// 携带参数返回
backQuery: {
type: Object,
default: null,
},
})
// 定义emits
defineEmits(['help'])
const router = useRouter()
const route = useRoute()
const langStore = useLangStore()
const visibleList = ref(false) //语言列表显示
// 当前语言类型
const currentLangName = computed(() => {
return langStore.selectedLang?.value || 'EN'
})
// 监听语言变化确保UI更新
watch(
() => langStore.selectedLang,
(newLang) => {
console.log('Language changed in header:', newLang)
},
{ deep: true }
)
const handleLanguageChange = (item) => {
visibleList.value = false
console.log('visibleList.value', visibleList.value)
console.log('Changing language to:', item)
setLocale(langStore, item.type)
// 立即更新visibleList状态
}
// 检测是否在APP环境中
const isInAppEnvironment = ref(false)
// 计算是否为首页
const isCurrentlyHomePage = computed(() => {
return !!props.isHomePage
})
const handleBack = () => {
if (isCurrentlyHomePage.value && isInApp()) {
// 首页且在APP中关闭页面
console.log('home back')
closePage()
} else {
// 非首页或浏览器环境:正常返回
router.go(-1)
if (props.backQuery != null) {
console.log('props.backQuery', props.backQuery)
// 使用 nextTick 确保上一步完成
nextTick(() => {
// 使用 replace 替换为带参数的版本
router.replace({
path: props.backQuery.from,
query: {
activeAction: props.backQuery.activeAction,
},
})
})
}
}
}
//语言列表显示
const showLang = () => {
visibleList.value = !visibleList.value
console.log('visibleList.value', visibleList.value)
}
// 组件挂载时检测环境
onMounted(() => {
isInAppEnvironment.value = isInApp()
})
</script>
<style scoped>
* {
font-family: 'SF Pro Text';
}
.back-btn,
.help-btn {
border: none;
background: transparent;
transition: all 0.2s ease;
}
.back-btn:active,
.help-btn:active {
transform: scale(0.9);
}
.extraList {
position: absolute;
z-index: 9;
right: 0;
top: 100%;
padding: 10px;
display: flex;
flex-direction: column;
width: max-content;
background-color: rgba(255, 255, 255);
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
margin-top: 5px;
backdrop-filter: blur(8px);
}
.extraList > div:not(:last-child) {
border-bottom: 0.1px solid black;
}
[dir='rtl'] .flipImg {
transform: scaleX(-1);
}
[dir='rtl'] .extraList {
right: auto;
left: 0;
}
@media screen and (max-width: 360px) {
* {
font-size: 10px;
}
}
@media screen and (min-width: 360px) {
* {
font-size: 16px;
}
}
@media screen and (min-width: 768px) {
* {
font-size: 24px;
}
}
@media screen and (min-width: 1024px) {
* {
font-size: 32px;
}
}
</style>