130 lines
3.0 KiB
Vue
130 lines
3.0 KiB
Vue
<template>
|
|
<view class="language-switcher">
|
|
<u-popup v-model="showPicker" mode="bottom" border-radius="20">
|
|
<view class="language-picker">
|
|
<view class="picker-header">
|
|
<text class="picker-title">{{ $t('me.language') }}</text>
|
|
<u-icon name="close" @click="showPicker = false" size="20"></u-icon>
|
|
</view>
|
|
<view class="language-list">
|
|
<view
|
|
class="language-item"
|
|
v-for="lang in languages"
|
|
:key="lang.code"
|
|
@click="changeLanguage(lang.code)"
|
|
:class="{ active: currentLanguage === lang.code }"
|
|
>
|
|
<text class="language-name">{{ lang.name }}</text>
|
|
<u-icon v-if="currentLanguage === lang.code" name="checkmark" color="#007AFF" size="20"></u-icon>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</u-popup>
|
|
|
|
<view class="language-trigger" @click="showPicker = true">
|
|
<text class="trigger-text">{{ getCurrentLanguageName() }}</text>
|
|
<u-icon name="arrow-right" size="16" color="#999"></u-icon>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: 'LanguageSwitcher',
|
|
data() {
|
|
return {
|
|
showPicker: false,
|
|
languages: [
|
|
{ code: 'zh', name: '中文' },
|
|
{ code: 'en', name: 'English' },
|
|
{ code: 'pt', name: 'Português' }
|
|
]
|
|
}
|
|
},
|
|
computed: {
|
|
currentLanguage() {
|
|
return this.$i18n.locale
|
|
}
|
|
},
|
|
methods: {
|
|
changeLanguage(langCode) {
|
|
this.$i18n.locale = langCode
|
|
uni.setStorageSync('language', langCode)
|
|
this.showPicker = false
|
|
|
|
// 触发自定义事件
|
|
this.$emit('language-changed', langCode)
|
|
|
|
// 显示切换成功提示
|
|
uni.showToast({
|
|
title: this.$t('common.success'),
|
|
icon: 'success'
|
|
})
|
|
},
|
|
getCurrentLanguageName() {
|
|
const current = this.languages.find(lang => lang.code === this.currentLanguage)
|
|
return current ? current.name : '中文'
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.language-switcher {
|
|
.language-trigger {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 30rpx 0;
|
|
|
|
.trigger-text {
|
|
font-size: 32rpx;
|
|
color: #333;
|
|
}
|
|
}
|
|
}
|
|
|
|
.language-picker {
|
|
background: white;
|
|
border-radius: 20rpx 20rpx 0 0;
|
|
|
|
.picker-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 40rpx 30rpx 20rpx;
|
|
border-bottom: 1px solid #f0f0f0;
|
|
|
|
.picker-title {
|
|
font-size: 36rpx;
|
|
font-weight: bold;
|
|
color: #333;
|
|
}
|
|
}
|
|
|
|
.language-list {
|
|
padding: 20rpx 0;
|
|
|
|
.language-item {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 30rpx;
|
|
|
|
&.active {
|
|
background-color: #f8f9fa;
|
|
|
|
.language-name {
|
|
color: #007AFF;
|
|
font-weight: 500;
|
|
}
|
|
}
|
|
|
|
.language-name {
|
|
font-size: 32rpx;
|
|
color: #333;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style> |