vue3国际化语言设置及表单组件封装

文章描述了一个Vue应用中实现国际化语言处理的流程,包括从浏览器或本地获取语言,存储到Pinia状态管理库,以及封装一个多语种表单组件。同时,提到了语言选择图标组件的实现,用于切换应用语言并更新存储。此外,还展示了如何通过Pinia管理和获取选定的语言。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以下层级嵌套:

国际化语言获取(浏览器中或本地) 重要!----把获取到的语言存到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;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值