以下层级嵌套:
国际化语言获取(浏览器中或本地) 重要!----把获取到的语言存到pinia —在语言选择图标组件中拿到pinia中存取的language ----最后进行多语表单组件封装
1、封装多语表单组件-----components里的i18nForm文件的index.vue
<template>
<el-form ref="formRef" :model="formData" :label-width="labelWidth">
<el-form-item v-for="(item, index) in formItems" :key="index" :label="item.name" :prop="item.prop" :rules="rules">
<el-input v-model="FormData[item.prop]" :placeholder="placeholder" :maxlength="maxlength"
:disabled="disabled" />
</el-form-item>
</el-form>
</template>
<script lang="ts" setup>
import { onMounted, reactive, ref, toRefs, nextTick,computed } from "vue";
import { useI18n } from "vue-i18n";
import { ElForm } from "element-plus";
const { t } = useI18n()
const formRef = ref(ElForm)
// 父传子
const props = defineProps({
//不同语言表单项
formItems: {
type: Array,
default: () => [],
required: true
},
// 表单的label宽度
labelWidth: {
type: Number,
default: 100,
required: true
},
// 表单数据
data: {
type: Object,
default: () => ({
en_US: '',
zh_CN: '',
}),
required: true
},
maxlength: {
type: Number,
default: 30
},
placeholder: {
type: String,
default: '请输入'
},
rules: {
type: Object,
default: () => ({
required: true, message: '请输入', trigger: 'blur'
})
},
disabled: {
type: Boolean,
default: false //默认不禁用
}
})
const state = reactive({
formData: {} as any
})
const { formData } = toRefs(state)
onMounted(() => {
state.formData = JSON.parse(JSON.stringify(props.data))
})
defineExpose({
formRef,
formData
})
</script>
2、语言选择页面图标组件-----components里的LangSelect文件的index.vue
<template>
<el-dropdown placement="bottom-end" trigger="click" @command="handleSetLanguage" ref="dropdown">
<div class="lang-select__icon">
<svg-icon class-name="international-icon" icon-class="icon_login_language_english" v-if="language === 'en'"></svg-icon>
<svg-icon icon-class="icon_login_language_chinese" v-if="language === 'zh-cn'" class="enlogo"></svg-icon>
</div>
<template #dropdown>
<el-dropdown-menu class="list">
<el-dropdown-item :disabled="language === 'en'" command="en">
<svg-icon icon-class="icon_login_language_english" class="enlogo">English</svg-icon>
</el-dropdown-item>
<el-dropdown-item :disabled="language === 'zh-cn'" command="zh-cn">
<svg-icon icon-class="icon_login_language_chinese" class="enlogo">中文</svg-icon>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
<script setup lang="ts">
import { computed } from 'vue';
import useStore from '@/store';
import { useI18n } from 'vue-i18n';
import { ElDropdown, ElMessage } from 'element-plus';
import SvgIcon from '@/component/SvgIcon/index.vue';
import { onMounted, nextTick, ref } from 'vue';
const { app } = useStore();
const language = computed(() => app.language);
// 获取当前应用程序的语言环境(locale)
const { locale } = useI18n();
function handleSetLanguage(lang: string) {
locale.value = lang;
// 把实际所选中的语言存到store的app里
app.setLanguage(lang);
if (lang == 'en') {
ElMessage.success('Switch Language Successful!')
} else {
ElMessage.success('切换语言成功!')
}
}
</script>
<style lang="scss">
.list {
.enlogo {
margin-right: 10px;
}
}
</style>
<style lang="scss" scoped>
.lang-select__icon {
line-height: 50px;
}
</style>
3、通过pinia存取language-----store文件下的app.ts模块
import { AppState } from '@types/store/app';
import { getLanguage } from '@/lang/index'; // 拿到文件里获取language的方法
const useAppStore = defineStore({
id: 'app',
state: (): AppState => ({
language: getLanguage(),
}),
actions: {
setLanguage(language: string) {
this.language = language;
localStorage.set('language', language);
},
}
})
4、获取language的方法 重要!-----lang文件的index.ts
//自定义国际化配置
import { createI18n } from 'vue-i18n';
import { localStorage } from '@/utils/storage';
//本地语言包
import enLocale from './en';
import zhCnLocale from './zh-cn';
const messages = {
'zh-cn': {
...zhCnLocale,
},
'en': {
.../enLocale,
},
};
// 获取当前系统使用语言字符串
export const getLanguage = () => {
//本地缓存获取
let language = localStorage.get('language');
if(language) {
return language;
}
//返回当前浏览器的语言设置 navigator对象来访问浏览器信息
language = navigator.language.toLowerCase();
const locales = Object.keys(messages);
for(const local of locales) {
if(language.indexOf(local) > -1) {
return locale;
}
}
return 'zh-cn'
};
const i18n = createI18n({
legacy: false,
locale: getLanguage(),
messages: messages,
});
export default i18n;