1、安装node包
npm install vue-i18n -S //安装8.x版本是为了兼容vue的2.x版本
npm install i18next-scanner -D // 开发依赖
npm install crc -S // 中文通过crc32转码获得唯一的key, 也避免中文作为索引导致性能不佳和索取不准确问题
2、根目录新建 i18next-scaner.config.js 文件
const fs = require('fs')
const { crc32 } = require('crc')
const systemLanguage = {
zh: 'zh-cn',
en: 'en'
}
// 读取已经存在在en.json文件的词条
const existJsonData = fs.readFileSync('./scan/i18n/en.json')
let existData = {}
try {
existData = JSON.parse(existJsonData)
} catch {
existData = {}
}
const keyList = Object.keys(existData)
module.exports = {
input: [
'src/**/*.{js,jsx,vue}',
// 不需要扫描的文件加!
'!src/i18n/**',
'!src/locales/**',
'!**/node_modules/**'
],
output: './scan', // 输出目录
options: {
debug: true,
func: false,
trans: false,
lngs: [systemLanguage.zh, systemLanguage.en],
defaultLng: systemLanguage.zh,
resource: {
loadPath: './i18n/newJson/{{lng}}.json', // 输入路径 (手动新建目录)
savePath: './i18n/newJson/{{lng}}.json', // 输出路径 (输出会根据输入路径内容自增, 不会覆盖已有的key)
jsonIndent: 2,
lineEnding: '\n'
},
removeUnusedKeys: true,
nsSeparator: false, // namespace separator
keySeparator: false, // key separator
interpolation: {
prefix: '{{',
suffix: '}}'
}
},
// 这里我们要实现将中文转换成crc格式, 通过crc格式key作为索引, 最终实现语言包的切换.
transform: function customTransform(file, enc, done) {
// 自己通过该函数来加工key或value
const { parser } = this
const content = fs.readFileSync(file.path, enc)
parser.parseFuncFromString(content, { list: ['t'] }, (key, options) => {
options.defaultValue = key
const hashKey = `K${crc32(key).toString(16)}` // crc32转换格式
// 如果词条不存在,则写入
if (!keyList.includes(hashKey)) {
parser.set(hashKey, options)
}
})
done()
}
}
3、根目录package.json配置扫描的运行命令
"scripts": {
"serve": "vite",
"dev": "vite --mode development",
"build": "vite build",
"preview": "vite preview",
"prepare": "husky install",
"prod": "vite --mode production",
"scan": "i18next-scanner --config i18next-scaner.config.js"
},
4、执行 npm run scan 扫描自动生成中英文档
5、这个文件根据业务自行存放, 我的放在src/locale/index.js
import { createI18n } from 'vue-i18n'
import zhCN from 'ant-design-vue/es/locale/zh_CN'
import enGB from 'ant-design-vue/es/locale/en_GB'
import localZh from '@scan/i18n/zh-cn.json' // 本地翻译中文文件
import localEn from '@scan/i18n/en.json' // 本地翻译英文文件
import crc32 from 'crc/crc32'
import tool from '@/utils/tool'
import sysConfig from '@/config/index'
export const messages = {
'zh-cn': {
lang: zhCN,
...localZh
},
'en': {
lang: enGB,
...localEn
}
}
const defaultLang = tool.data.get('APP_LANG') || sysConfig.LANG
const i18n = createI18n({
legacy: false, // 是否允许在 Legacy API 模式下使用 Composition API
locale: defaultLang,
fallbackLocale: defaultLang,
globalInjection: true,
silentTranslationWarn: true, // 去除国际化警告
messages
})
// --------这里是i18next-scanner新增的配置-------------
function lang(key, params) {
const hashKey = `K${crc32(key).toString(16)}` // 将中文转换成crc32格式去匹配对应的json语言包
let words = i18n.global.t(hashKey)
if (words === hashKey) {
words = key
}
// 配置传递参数的场景, 目前仅支持数组,可在此拓展
if (Array.isArray(params)) {
const reg = /\((\d)\)/g
words = words.replace(reg, (a, b) => {
return params[b]
})
}
return words
}
// --------这里是i18next-scanner新增的配置-------------
window.$t = lang
export const _lang = lang
export default i18n
6、main.js里配置
import i18n, {_lang} from './locales'
const app = createApp(App)
app.use(i18n)
app.config.globalProperties.$t = _lang
7、页面中使用
8、语言切换
在App.vue中设置
<template>
<a-config-provider :locale="locale">
<router-view />
</a-config-provider>
</template>
// import { useI18n } from 'vue-i18n'
// const { locale } = useI18n()
// locale.value = lang // 设置当前语言
import i18n from './locales'
import 'dayjs/locale/zh-cn'
const locale = ref(null);
locale.value = i18n.global.messages.value[lang].lang
i18n.global.locale.value = lang