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

以下层级嵌套:

国际化语言获取(浏览器中或本地) 重要!----把获取到的语言存到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;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3中封装form表单组件的思路可以参考以下步骤: 1. 创建一个Form组件,作为整个表单的容器。该组件可以包含一个form元素,并接受一个表单数据对象作为props。 2. 在Form组件内部,使用v-for指令遍历表单数据对象的属性,并根据属性的类型渲染对应的表单项。 3. 对于每个表单项,可以创建一个FormItem组件,并根据属性的类型渲染对应的表单元素,比如input、select、textarea等。 4. FormItem组件可以接受属性的名称、类型和值作为props,并根据类型渲染不同的表单元素。 5. 可以根据需要扩展Form组件和FormItem组件,添加更多的表单项类型,比如富文本编辑器、上传图片等。 6. 在Form组件中,可以监听表单元素的值变化,并将变化的值更新到表单数据对象中。 7. 可以在Form组件中添加提交按钮,并在点击按钮时触发表单提交事件,将表单数据对象作为参数传递给父组件。 需要注意的是,这只是一个基本的封装思路,如果需要使用到更多的业务场景,可以根据具体需求进行扩展和定制。<span class="em">1</span><span class="em">2</span> #### 引用[.reference_title] - *1* *2* [vue3 ts element plus form表单二次封装详细步骤 (附参数、类型详细介绍及简单使用示例)](https://blog.csdn.net/weixin_45291937/article/details/126275955)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值