<template>
|
<view class="language-switch">
|
<view class="current-lang" @tap="showLanguagePopup">
|
<text class="iconfont icon-language"></text>
|
<text>{{ currentLanguageLabel }}</text>
|
</view>
|
|
<!-- 语言选择弹窗 -->
|
<uni-popup ref="popupRef" type="bottom">
|
<view class="lang-popup">
|
<view class="popup-header">
|
<text class="title">{{ $t('common.language.select') }}</text>
|
<text class="close" @tap="closePopup">×</text>
|
</view>
|
<view class="lang-list">
|
<view
|
class="lang-item"
|
v-for="lang in languages"
|
:key="lang.value"
|
:class="{ active: currentLang === lang.value }"
|
@tap="selectLanguage(lang.value)"
|
>
|
<text>{{ lang.label }}</text>
|
<text class="iconfont icon-check" v-if="currentLang === lang.value"></text>
|
</view>
|
</view>
|
</view>
|
</uni-popup>
|
</view>
|
</template>
|
|
<script setup>
|
import { ref, computed } from 'vue'
|
import { getStoredLanguage, setLanguage } from '@/locale'
|
|
const popupRef = ref(null)
|
const currentLang = ref(getStoredLanguage())
|
const languages = [
|
{ label: '简体中文', value: 'zh-Hans' },
|
{ label: '繁體中文', value: 'zh-Hant' },
|
{ label: 'Português', value: 'pt' }
|
]
|
|
const currentLanguageLabel = computed(() => {
|
const lang = languages.find(l => l.value === currentLang.value)
|
return lang ? lang.label : ''
|
})
|
|
const showLanguagePopup = () => {
|
popupRef.value?.open()
|
}
|
|
const closePopup = () => {
|
popupRef.value?.close()
|
}
|
|
const selectLanguage = (lang) => {
|
if (currentLang.value !== lang) {
|
currentLang.value = lang
|
setLanguage(lang)
|
// 刷新页面应用新语言
|
uni.reLaunch({
|
url: '/pages/index/index'
|
})
|
}
|
closePopup()
|
}
|
</script>
|
|
<style lang="scss">
|
.language-switch {
|
.current-lang {
|
display: flex;
|
align-items: center;
|
height: 72rpx;
|
padding: 10rpx 20rpx;
|
background: #F5F6FA;
|
border-radius: 36rpx;
|
|
.icon-language {
|
width: 36rpx;
|
height: 36rpx;
|
margin-right: 10rpx;
|
}
|
|
text {
|
font-size: 28rpx;
|
color: #333;
|
}
|
}
|
}
|
|
.lang-popup {
|
background: #fff;
|
border-radius: 24rpx 24rpx 0 0;
|
|
.popup-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding: 30rpx;
|
border-bottom: 1rpx solid #eee;
|
|
.title {
|
font-size: 32rpx;
|
font-weight: bold;
|
color: #333;
|
}
|
|
.close {
|
font-size: 40rpx;
|
color: #999;
|
padding: 0 20rpx;
|
}
|
}
|
|
.lang-list {
|
.lang-item {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding: 30rpx;
|
border-bottom: 1rpx solid #eee;
|
|
text {
|
font-size: 30rpx;
|
color: #333;
|
}
|
|
&.active {
|
color: #0066CC;
|
|
text {
|
color: #0066CC;
|
}
|
}
|
|
.icon-check {
|
width: 32rpx;
|
height: 32rpx;
|
}
|
}
|
}
|
}
|
</style>
|