引子
因为我本身一直在学日语,碰到了一个比较尴尬的问题,日常对话听得懂,但是讲出口要思考很久,碰巧接触到了TalkAI口语,里面的功能确实很牛逼,就是要充米 终身会员500+。那我是程序员,包白piao的,所以自己动手开发一个多语种的口语练习AI,顺便学习一些项目上还用不上的技术。
比如今天要讲的i18n。i18n的使用非常简单,但是里面最复杂的操作就是一个一个去覆盖文字定义,并且编写不同语言的语言包。那我这个demo刚好用上了AI技术,所以编写一个脚本只需要一份中文范本就可以生成N种语言的语言包。
i18n基础使用
安装
npm i vue-i18n -S // 下载这个版本是9 Vue3版本的
使用
// 语言包的结构其实就是和你正常引用对象一样
const LANG = {
talk: {
name: "123",
},
};
// 基础引入
import { createI18n } from "vue-i18n";
import CN from "@/lang/zh-CN.json";
import US from "@/lang/en-US.json";
const i18n = createI18n({
legacy: false, // 设置为 false,启用 composition API 模式
messages: {
"zh-CN": CN,
"en-US": US,
},
locale: navigator.language, // 设置默认语言
});
app.use(i18n);
// 在setup中使用
import { useI18n } from "vue-i18n";
const { locale: language, t } = useI18n();
// 更换语言
language.value = "en-US";
// 在setup中获取数据
const talk = t("talk.name");
在页面中使用
<van-nav-bar :title="$t('record.title')">
<van-tabbar route>
<van-tabbar-item
icon="home-o"
to="/talk"
>{{$t('talk.title')}}</van-tabbar-item>
<van-tabbar-item
icon="search"
to="/record"
>{{$t('record.title')}}</van-tabbar-item>
<van-tabbar-item
icon="user-circle-o"
to="/my"
>{{$t('my.title')}}</van-tabbar-item>
</van-tabbar>
进阶 自动引入语言包
二次封装语言包并自动加载语言包 首先在src下创建一个lang文件夹拥有这几个文件
lang/zh-CN.json 需要拿来转换的中文范本
{
"my": {
"title": "我的",
"day": "坚持天数",
"practice": "练习次数",
"time": "累计时长",
"point": "累计得分",
"unit": { "day": "天", "count": "次", "mintues": "分钟", "point": "分" },
"lang": "界面语言",
"engine": " 语音引擎",
"clear": "数据清空"
},
"talk": {
"title": "AI对话",
"split": "可以开始对话了~",
"call": "通话模式",
"talk": "开始对话吧",
"over": "练习结束",
"end": "结束",
"send": "发送",
"identifying": "识别中...",
"creating": "等待回复...",
"speaking": "AI朗读中..."
},
"sceneSetting": {
"scene": "场景",
"title": "场景设置",
"sceneplaceholder": "输入场景",
"userplaceholder": "输入用户所扮演的角色",
"aiplaceholder": " 输入AI所扮演的角色",
"inplaceholder": "请输入场景简述",
"user": "用户角色",
"ai": "AI角色",
"introduce": "场景描述",
"count": "对话数量",
"avgPoint": "平均得分",
"evaluate": "评价",
"continue": "继续",
"updatedAt": "练习时间"
},
"record": { "title": "练习记录", "list": "记录列表", "chartTitle": "最近十次练习平均分", "nomore": "没有更多了", "loading": "加载中" },
"langauge": { "chinese": "中文", "english": "英语", "japanese": "日语" }
}
lang/lang.js 用于选择语言的数据源 其实用json就好了 但是因为我用了vant组件 它自身也有国际化配置
import enUS from "vant/es/locale/lang/en-US";
import zhCN from "vant/es/locale/lang/zh-CN";
import jaJP from "vant/es/locale/lang/ja-JP";
// 这样只有import的地方才能使用 require是不行的
// webpack编译模块为ES Modules
// 如果没有语言包的需求 其实用lang.json就可以 一个配置通用辐射到Vue和AI脚本
export default [
{
text: "中文",
value: "zh-CN",
lang: zhCN,
},
{
text: "英语",
value: "en-US",
lang: enUS,
},
{
text: "日语",
value: "ja-JP",
lang: jaJP,
},
];
lang/index.js 二次封装并自动化引入所有的语言
// 获取lang文件下的所有语言json文件 文件名为键 数据为值
const langFiles = require.context("./", true, /\.json$/);
import { createI18n } from "vue-i18n";
// 自动获取语言数据
export default {
install(app) {
let messages = {};
langFiles.keys().forEach((lang) => {
const langName = lang.replace(/^\.\/(.*)\.\w+$/, "$1");
const value = langFiles(lang);
messages[langName] = value;
});
const i18n = createI18n({
legacy: false, // 设置为 false,启用 composition API 模式
messages,
locale: navigator.language, // 设置默认语言
});
app.use(i18n);
},
};
main.js 引入
import { createApp } from "vue";
import App from "./App.vue";
import lang from "./lang";
const app = createApp(App);
app.use(lang).mount("#app");
使用AI自动生成别的语言包
我用的是通义千问 里面有免费额度 大家获取APIKey去注册就好了
添加lang/AITranslate脚本 这个后续要打包配置忽略掉这个文件
// import 和 require 的识别格式不同
const axios = require("axios");
const source = require("./zh-CN.json");
const fs = require("fs");
const path = require("path");
// 引入不了因为node是用的commonjs 识别不了es modules的js
const langOptions = [
{
text: "英语",
value: "en-US",
},
{
text: "日语",
value: "ja-JP",
},
];
async function translate() {
for (let lang of langOptions) {
const res = await axios.post(
"https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions",
{
model: "qwen-plus",
messages: [
{
role: "system",
content: `你现在是一个json数据多语言转换工具 会接收到用户的json数据 请你把用户要求的值 从中文转换成所需的语言 替换掉里面对应的值 只需要返回数据不需要多余的回答且不需要已任何形式包裹`,
},
{
role: "user",
content: `我想把下面的值 转换成${lang.text} 这是我的json数据 ${JSON.stringify(source)}`,
},
],
},
{
headers: {
Authorization: "Bearer 输入你的APIKEY",
"Content-Type": "application/json",
},
}
);
if (res && res.status == 200) {
let result = res.data.choices[0].message.content;
fs.writeFileSync(path.join(__dirname, `./${lang.value}.json`), result);
console.log(`生成语言包${lang.text}/${lang.value}.json成功`);
}
}
}
translate();
在package.json scripts中加入
"i18n-create": "node ./src/lang/AITranslate.js"
运行脚本