vue+i18n的引用与封装
·
1.安装i8N
// 安装vue-i18n
npm install vue-i18n
// 指定版本安装vue-i18n
npm install vue-i18n@9
配置多语言文件
在项目中创建语言资源文件,例如:
src/locales/en.json(英文)
示例内容(英文):
{
"message": {
"hello": "Hello World",
"welcome": "Welcome {name}",
"language": "Language"
}
}
src/locales/zh.json(中文)
{
"message": {
"hello": "你好世界",
"welcome": "欢迎 {name}",
"language": "语言"
}
}
初始化 i18n 实例
新建i18文件 在 src/i18n.js 中配置:并封装
import { createI18n } from 'vue-i18n'
import en from './lang/en'
import zh from './lang/zh'
export type LocaleKey = 'zh' | 'en'
// 统一管理应用内可用的语言包,新增语言时只需要扩展这里。
const messages = {
zh,
en,
}
// 启动时优先恢复上次选择的语言,没有则默认中文。
const getSavedLocale = (): LocaleKey => {
const locale = localStorage.getItem('locale')
return locale === 'en' ? 'en' : 'zh'
}
const i18n = createI18n({
legacy: false,
globalInjection: true,
locale: getSavedLocale(),
fallbackLocale: 'en',
messages,
})
// 统一切换语言,页面和组件都通过这个入口改语言。
export function setLocale(lang: LocaleKey) {
i18n.global.locale.value = lang
localStorage.setItem('locale', lang)
}
// 统一获取当前语言,供组合式函数和组件读取。
export function getLocale(): LocaleKey {
return i18n.global.locale.value as LocaleKey
}
export default i18n
挂载到 Vue 实例
在 main.js 中引入并挂载:
import { createApp } from 'vue';
import App from './App.vue';
import i18n from './i18n';
const app = createApp(App);
app.use(i18n);
app.mount('#app');
模板中使用翻译
在组件模板中通过 $t 使用:
<template>
<a-space direction="vertical" style="width: 100%" size="middle">
<a-drawer v-model:open="drawerOpen" :title="drawerTitle" width="520" destroyOnClose @ok="handleSubmit">
<a-form layout="vertical">
<a-form-item :label="t('task.form.taskNo')"><a-input v-model:value="form.taskNo" /></a-form-item>
<a-form-item :label="t('task.form.orderNo')"><a-input v-model:value="form.orderNo" /></a-form-item>
<a-form-item :label="t('task.form.pilot')"><a-input v-model:value="form.pilot" /></a-form-item>
<a-form-item :label="t('task.form.drone')"><a-input v-model:value="form.drone" /></a-form-item>
<a-form-item :label="t('task.form.status')"><a-select v-model:value="form.status" :options="statusOptions" /></a-form-item>
</a-form>
</a-drawer>
</a-space>
</template>
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
</script>
封装统一的语言读写
src\composables\useLocale.ts
import { computed } from 'vue'
import { getLocale, setLocale, type LocaleKey } from '@/i18n'
// 统一封装语言读写,页面只关心当前语言和切换动作。
export function useLocale() {
const locale = computed(() => getLocale())
const changeLocale = (lang: LocaleKey) => {
setLocale(lang)
}
return {
locale,
changeLocale,
}
}
优化:封装成统一的自注册组件,避免重复注册
新建 在src/i18n文件新建i18nCompent.ts
import { useI18n } from 'vue-i18n'
type LocaleKey = 'zh' | 'en'
type Messages = Record<LocaleKey, Record<string, any>>
// 自动收集 views 下每个页面目录的局部语言文件,页面只需要传自己的目录名。
const zhModules = import.meta.glob('../views/**/i18n/zh.ts', { eager: true }) as Record<string, { default: Record<string, any> }>
const enModules = import.meta.glob('../views/**/i18n/en.ts', { eager: true }) as Record<string, { default: Record<string, any> }>
function resolveMessages(viewName: string): Messages {
const zhPath = `../views/${viewName}/i18n/zh.ts`
const enPath = `../views/${viewName}/i18n/en.ts`
const zh = zhModules[zhPath]
const en = enModules[enPath]
if (!zh || !en) {
throw new Error(`Missing local i18n module: ${viewName}`)
}
return { zh: zh.default, en: en.default }
}
// 统一的页面级 i18n 入口,避免每个页面单独导入 zh/en。
export function useViewI18n(viewName: string): any {
return useI18n({
useScope: 'local',
messages: resolveMessages(viewName),
})
}
在文件中使用:
<template>
<a-space direction="vertical" style="width: 100%" size="middle">
<a-drawer v-model:open="drawerOpen" :title="drawerTitle" width="520" destroyOnClose @ok="handleSubmit">
<a-form layout="vertical">
<a-form-item :label="t('task.form.taskNo')"><a-input v-model:value="form.taskNo" /></a-form-item>
<a-form-item :label="t('task.form.orderNo')"><a-input v-model:value="form.orderNo" /></a-form-item>
<a-form-item :label="t('task.form.pilot')"><a-input v-model:value="form.pilot" /></a-form-item>
<a-form-item :label="t('task.form.drone')"><a-input v-model:value="form.drone" /></a-form-item>
<a-form-item :label="t('task.form.status')"><a-select v-model:value="form.status" :options="statusOptions" /></a-form-item>
</a-form>
</a-drawer>
</a-space>
</template>
<script setup lang="ts">
import { useViewI18n } from '@/i18n/i18nCompent'
const { t } = useViewI18n('task') //task是文件名
//也可以修改 i18nCompent 的方法匹配view下的所有子文件
</script>
更多推荐
所有评论(0)