前言:openCC是什么?
OpenCC(Open Chinese Convert )是一个开源的中文简繁体转换工具,专为高质量、可控的中文转换而设计。它可以在不同中文地区(中国大陆、台湾、香港等)之间进行精确的字符和词汇转换。
🔧 核心特点
特性 |
说明 |
✅ 高质量转换 |
不只是字符替换,还支持词语级转换(考虑语境) |
✅ 支持多种转换模式 |
简体 ↔ 繁体、简体 ↔ 台湾正体、简体 ↔ 香港繁体等 |
✅ 多平台支持 |
支持 C++、Node.js、Python、WebAssembly(浏览器)等 |
✅ 配置可定制 |
使用 JSON 格式的配置文件控制转换规则 |
✅ 开源免费 |
GitHub 开源,遵循 Apache 2.0 协议 |
🔄 支持的转换方向
配置文件 |
转换方向 |
s2t.json |
简体 → 繁体(通用) |
t2s.json |
繁体 → 简体 |
s2tw.json |
简体 → 台湾正体 |
tw2s.json |
台湾正体 → 简体 |
s2hk.json |
简体 → 香港繁体 |
hk2s.json |
香港繁体 → 简体 |
📦 应用场景
- 国际化网站(i18n)支持简繁切换
- 中文文档统一标准格式
- 电商、社交、新闻等跨区域中文内容发布
- NLP/文本处理中的语言标准化预处理
在VUE2框架中实操
- 下载 opencc-js
js
复制代码
npm install opencc-js
- 创建language.js自定义方法
js
复制代码
// src/utils/language.js
import OpenCC from "opencc-js";
const changeLang = (lang = "cn") => {
const converter = OpenCC.Converter({
from: lang === "hk" ? "cn" : "hk",
to: lang,
});
convertPageText(converter);
localStorage.setItem("lang", lang);
};
const convertPageText = (converter) => {
const walker = document.createTreeWalker(
document.body,
NodeFilter.SHOW_TEXT,
null,
false
);
while (walker.nextNode()) {
const node = walker.currentNode;
node.nodeValue = converter(node.nodeValue);
}
};
export default {
changeLang,
convertPageText,
};
- 将自定义的方法挂载到全局
js
复制代码
// src/main.js
// 引入自定义方法
import LanguageUtil from './utils/language';
// 挂在全局方法
Vue.prototype.$changeLang = LanguageUtil.changeLang;
Vue.prototype.$convertPageText = LanguageUtil.convertPageText;
- public/index.html 中引入 OpenCC(或者访问路径直接将文件内容保存到public下./引入)
js
复制代码
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/full.js">
- 自定义组件
html
复制代码
<template>
<div class="lang-switch">
<el-select
v-model="currentLang"
@change="changeLang"
placeholder="请选择语言"
size="mini"
style="width: 120px"
>
<el-option label="中文简体" value="cn" />
<el-option label="中文繁体" value="hk" />
</el-select>
</div>
</template>
<script>
export default {
name: "LangSwitch",
data() {
return {
// 拿到lang值,没有默认中文简体cn
currentLang: localStorage.getItem("lang") || "cn",
};
},
watch: {
// 监听路由变化
$route() {
// 确保路由变化后dom渲染完成后执行语言切换
this.$nextTick(() => {
const lang = localStorage.getItem("lang") || "cn";
const converter = OpenCC.Converter({
from: lang === "hk" ? "cn" : "hk",
to: lang,
});
this.convertPageText(converter);
this.currentLang = lang;
localStorage.setItem("lang", lang);
});
},
},
mounted() {
// 组件加载后执行语言转换(如果不是默认简体)
if (this.currentLang !== "cn") {
this.changeLang(this.currentLang);
}
},
methods: {
changeLang(lang) {
const converter = OpenCC.Converter({
from: lang === "hk" ? "cn" : "hk",
to: lang,
});
this.convertPageText(converter);
this.currentLang = lang;
localStorage.setItem("lang", lang);
// 派发全局事件
// 这里派发全局事件,因为element-ui的输入框、选择框、时间选择器等里带有placeholder的文字提示内容在document.body中获取不到,所以无法翻译,需要手动派发事件在输入框、选择框、时间选择器等所在的页面中手动触发调用翻译方法
window.dispatchEvent(
// 事件名称 langChanged
new CustomEvent("langChanged")
);
},
convertPageText(converter) {
// 这里获取document.body来翻译
const walker = document.createTreeWalker(
document.body,
NodeFilter.SHOW_TEXT,
null,
false
);
while (walker.nextNode()) {
const node = walker.currentNode;
node.nodeValue = converter(node.nodeValue);
}
},
},
};
</script>
<style scoped>
.lang-switch {
padding: 10px;
}
</style>
- 每个页面中调用自定义方法来翻译
js
复制代码
// 在每个页面中watch中监听数据变化,数据变化时获取选择的语言值,更新语言
// 例如分页数据会变化,如果不再次调用翻译方法,分页后的数据翻译则失效
watch: {
// 例如监听 listData,列表数据变化则翻译,防止页面切换翻译失效
listData: {
handler(newVal) {
if (newVal && newVal.length > 0) {
const lang = localStorage.getItem("lang") || "cn";
this.$nextTick(() => {
if (lang !== "cn") {
// 直接调用全局已挂载的方法
this.$changeLang(lang);
}
});
}
},
immediate: true, // 初始化时也触发一次(如果需要)
deep: true, // 深度监听,监听数组内部元素变化
},
},
- 解决placeholder内容在document.body中获取不到的问题
js
复制代码
<tempate>
// 输入框、选择框、时间选择器等的所在页面
// 例如是输入框
<el-input
v-model="searchData.file_name"
:placeholder="fileNameText"
></el-input>
</template>
export default {
name:"",
data(){
return {
searchData: {
file_name:"",
},
fileNameText:"", // 单独定义每个placeholder
}
}
mounted() {
// 这里触发派发的事件(事件名,事件执行函数)
window.addEventListener("langChanged", this.onLangChanged);
this.onPlaceholder();// 用来转换placeholder中的文字
];
},
beforeDestroy() {
// 移除监听器,防止内存泄漏
window.removeEventListener("langChanged", this.onLangChanged);
},
methods: {
onLangChanged(e) {
this.onPlaceholder();
},
async onPlaceholder() {
this.fileNameText = await this.deepCopyAndConvert("请输入...");
},
// 深拷贝数据根据进行 简-繁或繁-简 的转换
async deepCopyAndConvert(value) {
const lang = localStorage.getItem("lang");
if (value == null) return value;
const copiedValue = JSON.parse(JSON.stringify(value));
if (typeof copiedValue === "string") {
let converter;
if (lang !== "cn") {
converter = await OpenCC.Converter({ from: "cn", to: "hk" });
} else {
converter = await OpenCC.Converter({ from: "hk", to: "cn" });
}
return converter(copiedValue);
}
return copiedValue;
},
}
}