appointment_system/components/language-switcher.vue
2025-12-11 22:50:18 +08:00

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>