获取代码中的所有中文文本
使用 fe-js-utils
cmd
pnpm add fe-js-utils -D在 package.json 中添加以下 scripts:
json
{
"scripts": {
"cleanInvalidComments": "fe-js-utils cleanInvalidComments",
"checkAny": "fe-js-utils checkAny",
"extractChinese": "fe-js-utils extractChinese",
"extractCommonLocaleValues": "fe-js-utils extractCommonLocaleValues",
"findModuleInCommonLocaleValues": "fe-js-utils findModuleInCommonLocaleValues",
"autoGenerateLocaleModules": "fe-js-utils autoGenerateLocaleModules",
"autoReplaceChinese": "fe-js-utils autoReplaceChinese"
}
}在项目根目录创建 fe-js-utils.config.ts
ts
const commonLocaleModules = ['SiderNav']
const langFile = './extract-en-results.js'
const langName = 'en_US'
export default {
extractChinese: {
targetDir: './src',
outputFile: langFile,
extFiles: ['.js', '.ts', '.vue'],
excludeDirs: ['node_modules', 'dist', 'build', 'locales'],
},
extractCommonLocaleValues: {
outputFile: `./src/locales/${langName}/Common.ts`,
},
autoGenerateLocaleModules: {
// 输入文件路径(中文提取结果文件)
inputFile: langFile,
outputDir: `./src/locales/${langName}`,
runExtractFirst: false, // 自动先执行extractChinese
autoExtractCommonLocale: true, // 自动执行extractCommonLocaleValues
},
findModuleInCommonLocaleValues: {
localeDir: `./src/locales/${langName}`,
commonLocaleModule: 'Common',
localModules: commonLocaleModules,
},
autoReplaceChinese: {
localeDir: './src/locales/zh_CN',
commonLocaleModule: 'Common',
localModules: commonLocaleModules,
// 变量声明插入位置,默认为 // #region Hooks,如果值为空或在文件中未找到,则插入到 import 语句的最后
variableDeclarationInsertPosition: '',
// 显示详细日志
verbose: false,
// 自定义 import 语句的回调函数
customImportStatements: (
imports: string[],
filePath: string,
localModule: string
) => {
// 返回一个 import 语句字符串的数组,为空时不会添加任何 import 语句
return [
"import { useI18n } from 'vue-i18n'",
"import i18n from '@/i18n'",
]
},
// 自定义变量声明的回调函数
customVariableDeclarations: (
fileContent: string,
filePath: string,
localModule: string,
needsCommon: boolean
) => {
// 返回一个变量声明字符串,为空时不会添加任何变量声明
return 'const { t } = useI18n()'
},
// 自定义替换文本的回调函数
customReplaceTextFunction: (
filePath: string,
localModule: string,
chineseKey: string,
englishValue: string,
isCommon: boolean,
context: string
) => {
// 返回一个替换后的字符串,为空时将不会替换任何中文字符
// 示例:
return `$t('${localModule}.${englishValue}')`
},
},
}extractChinese(中文提取)
将代码中所有中文按照组件位置提取出来
cmd
pnpm extractChineseextractCommonLocaleValues(提取公共语言包)
根据组件生成 extract-chinese-results.js ,可以自己手动通过翻译此文件生成其他语言版本,最后再生成模块化语言包配置到 vue-i18n 中
cmd
pnpm extractCommonLocaleValuesautoGenerateLocaleModules(生成模块化语言包)
生成根据组件路径区分的多个语言键值配置文件
cmd
pnpm autoGenerateLocaleModulesautoReplaceChinese(替换源码中的中文)
cmd
pnpm autoReplaceChinese配置 vue-i18n
下载
cmd
pnpm add vue-i18n@11创建 i18n/index.ts
ts
// src/i18n/index.ts
import { createI18n } from 'vue-i18n'
import type { I18nInstance } from 'vue-i18n'
import messages from '../locales/index' // fe-js-utils 生成的语言包
// 从 localStorage 读取保存的语言(默认 zh-CN)
const getSavedLocale = (): string => {
if (typeof window !== 'undefined') {
return localStorage.getItem('app-locale') || 'zh-CN'
}
return 'zh-CN'
}
// 创建 i18n 实例
const i18n: I18nInstance = createI18n({
legacy: false, // 开启 Vue 3 组合式 API 支持
locale: getSavedLocale(), // 初始语言(优先从本地存储读取)
fallbackLocale: 'en', // 降级语言
messages: messages, // 注册 fe-js-utils 生成的语言包
})
export default i18nmain.ts 中导入
ts
import i18n from './i18n'
const app = createApp(App)
app.use(i18n)设置语言文件
创建 locales/index.ts
ts
// src/locale/index.ts(示例结构)
import zh from './zh' // 中文语言包
import en from './en' // 英文语言包
// 其他语言...
// 导出所有语言包(key 是语言标识,value 是对应语言的键值对)
export default {
'zh': zh,
'en': en,
// 如:'ja': ja, 'ko': ko...
}语言包示例
ts
export default {
按键选择: 'Key Selection',
开始调试: 'Start Calibration',
}配置 store
创建 stores/i18nStore.ts
ts
// src/stores/i18nStore.ts
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { useI18n } from 'vue-i18n'
export const useI18nStore = defineStore('i18n', () => {
const { locale, t } = useI18n()
// 可用语言列表
const availableLocales = ref([
{ code: 'en', name: 'English' },
{ code: 'zh', name: '中文' },
])
// 当前语言
const currentLocale = computed(() => locale.value)
// 切换语言
const setLocale = (lang: string) => {
locale.value = lang
localStorage.setItem('preferred-language', lang)
}
// 响应式组件获取文本
// const trans = (key: string) => computed(() => t(key))
const trans = (key: string) => t(key)
// 初始化语言
const initLocale = () => {
const saved = localStorage.getItem('preferred-language')
const browserLang = navigator.language
const defaultLang =
saved || (browserLang.startsWith('zh') ? 'zh' : 'en')
setLocale(defaultLang)
}
return {
availableLocales,
currentLocale,
setLocale,
initLocale,
trans,
t
}
})组件中使用
vue
<script>
import { useI18nStore } from '@/stores/i18nStore'
const i18nStore = useI18nStore()
</script>
<template>
<div class="first-content">
<div
class="nav-item"
v-for="item in fixedNavData.first.navItems"
:class="{ 'is-select': item.isSelect }"
:key="item.path"
>
<div>
<!-- {{ item.svg }} -->
<SvgIcon
:icon-class="item.icon"
size="2em"
:color="item.isSelect ? '#b4b47b' : ''"
/>
</div>
<div>{{ i18nStore.trans(item.name) }}</div>
</div>
</div>
<div>{{ i18nStore.trans('文本内容作为键') }}</div>
</template>