您的位置:首页 > 游戏 > 手游 > 国家工商总局查询平台_自助建站空间怎么用_百度搜题网页版入口_营销团队公司

国家工商总局查询平台_自助建站空间怎么用_百度搜题网页版入口_营销团队公司

2024/12/23 8:56:58 来源:https://blog.csdn.net/snowball_li/article/details/144116316  浏览:    关键词:国家工商总局查询平台_自助建站空间怎么用_百度搜题网页版入口_营销团队公司
国家工商总局查询平台_自助建站空间怎么用_百度搜题网页版入口_营销团队公司

推荐文章

前端-SCMP:技术和业务相辅相成 / 一分钟快速读懂SCMP供应链管理专家_scmp补贴-CSDN博客

一、本文目标

1、实现国际化开发,页面使用$t()实现目标翻译
2、通过调用接口的方法进行翻译
3、一个页面往往有较多需要翻译的字段,一个一个翻译效率不友好,本文实现收集整个页面的需要翻译的字段,然后集中翻译

二、实现

2.1、plugins/i18n.ts

// plugins/mi18n.ts
// 通过调用接口的方式做国际化/翻译
import { App, reactive, ref } from 'vue';
import { readyAwait } from '@v3/const/routerHandle'
import defaultLang from 'element-plus/es/locale/lang/zh-CN'
reactive(defaultLang)
import { interface1, interface2 } from '@v3/api/modules/translate.ts'
export default {async install(app: App, option: any) {const LOCAL_LANFGUAGE = 'chinese_simplified'const BODY_CLASS = 'm-translate--other'// Unicode编码中汉字的基本区域const ZH_REGEXP = /[\u4e00-\u9fa5]+/// 注意中文简体chinese_simplifiedconst CONNECTOR = '>>>>'// 字符分组长度默认1000const GROUP_LEN = 1000// 文本临时存储let cacheTextMap: any = {}// 回调临时存储let callbackMap: any = {}// 单词首字母大写function capitalize(str: string) {return str.replace(/(^|\s)[A-Za-z]/g, ($) => $.toUpperCase())}// 缓存class Store {vueStore: any = null;textMap: any = reactive({});fromTextMap: any = reactive({});constructor() {reactive(this.textMap)}get pageUrl() {const href = location.hrefconst pathname = location.pathnamereturn pathname + href.slice(href.indexOf('#'), href.indexOf('?') > -1 ? href.indexOf('?') : href.length)}get pageName() {const arr = this.vueStore && this.vueStore.state.activeNameArrreturn arr && arr[arr.length - 1]}getFromText(toText: any) {// 添加hash__前缀以防止误传return this.fromTextMap[`hash__${toText}`]}setFromText(toText: any, fromText: any) {this.fromTextMap[`hash__${toText}`] = fromText}getValue(text: any, option: any = {}) {// 文本是否需要翻译if (text === '') {return ''}// 不属于 Unicode编码中汉字的基本区域 直接returnif (!String(text).match(ZH_REGEXP)) {return text}const to = option && option.to || localStorage.getItem('to')const key = this.getKeyByOption(text, option)if (!to || to === LOCAL_LANFGUAGE) {this.textMap[key] = textreturn this.textMap[key]}if (this.textMap[key] === undefined) {this.textMap[key] = ''}return capitalize(this.textMap[key])}getKeyByOption(text: any, option: any) {const to = option && option.to || localStorage.getItem('to')const mark = option && option.mark || ''const pageUrl = option && option.pageUrl || this.pageUrlconst key = [to, pageUrl, mark, text].join(CONNECTOR)return key}setValue(text: any, value: any, option = {}) {this.textMap[this.getKeyByOption(text, option)] = value}setValues(texts = [], values = [], option = {}) {texts.forEach((text, index) => {this.setValue(text, values[index], option)})}reload() {const keys = Object.keys(this.textMap)keys.forEach(key => {this.textMap[key] = ''let arr = key.split(CONNECTOR)translateText(arr[arr.length - 1], { pageUrl: arr[1], mark: arr[4] || '' }, null)})}}// 语言配置class Language {toName: any = ref('');from: any = reactive({});local: any = reactive({});to = '';setLocal(val: any) {this.from = this.local = vallocalStorage.setItem('from', val)}// 切换语言changeLanguage(val: any) {this.to = vallocalStorage.setItem('to', val)if (val && val !== LOCAL_LANFGUAGE) {document.body.classList.add(BODY_CLASS)} else {document.body.classList.remove(BODY_CLASS)}}// 设置目标语言setToName(toName: any) {this.toName.value = toName}}class Translate {static instance: any = null;static resolve: any = null;readonly version = '2.3.1.20230607';store: any = new Store();language: any = new Language();languages: any = reactive([]);readyAwait: any = null;languageMap: any = null;constructor() {if (Translate.instance) {return Translate.instance} else {this._init()}}// 切换语言changeLanguage(to: any) {this.language.changeLanguage(to)this.store.reload()translate(defaultLang, null, null, null)this.language.setToName((this.languages.find((item: any) => item.code === to) || {}).label || '')}async getLanguages() {this.languages.length = 0await interface1({}).then((res: any) => {let data = res.payload || []data.forEach((item: any) => {this.languages.push({label: item.languageName,code: item.languageCode,value: item.browserCode})})})}async _init() {reactive(this)this.readyAwait = new Promise(resolve => {Translate.resolve = resolve})readyAwait.then((store: any) => {trans.store.vueStore = store})Translate.instance = thisthis.language.setLocal(LOCAL_LANFGUAGE)const to = localStorage.getItem('to')const navigatorLanguage = localStorage.getItem('navigatorLanguage')let lang = ''await this.getLanguages()this.languageMap = {}this.languages.forEach((item: any) => {this.languageMap[item.code] = item.value})// 浏览器默认语言改变if (navigatorLanguage !== navigator.language && navigatorLanguage != null) {lang = this.languageMap[navigator.language] || to || ''} else {lang = to !== null ? to : this.languageMap[navigator.language] || '';}localStorage.setItem('to', lang)localStorage.setItem('navigatorLanguage', navigator.language)this.changeLanguage(lang)Translate.resolve()}t(prop: any, option: any) {return translateText(prop, option, null)}translateTexts(texts: any) {return translateTexts(texts, null)}}const trans = new Translate()// 页面/组件需要翻译的内容准备就绪function ready() {return Promise.allSettled([trans.readyAwait, readyAwait])}// groupByLength 的函数,它接收两个参数:arr 和 length。该函数的目的是根据给定的 length 参数,将数组 arr 中的字符串元素分组,每组中所有字符串的长度之和不超过 length 指定的值。如果某个字符串的长度本身大于等于 length,则这个字符串将单独成为一组。函数最终返回一个二维数组,其中每个子数组代表一个分组。function groupByLength(arr: any, length: any) {const res: any = []let len = 0let index = 0arr.forEach((item: any) => {res[index] = res[index] || []if (item.length >= length) {if (res[index].length > 0) {index += 1}res[index] = res[index] || []res[index].push(item)index += 1len = 0return}if (len + item.length <= length) {res[index].push(item)len += item.lengthreturn}len = 0index += 1res[index] = res[index] || []res[index].push(item)})return res}// 接口翻译apifunction translateTextsByApi(texts: any, { pageUrl, pageName, from, to }:any = {}) {const data = {from: from || trans.language.from,to: to || trans.language.to,pageUrl: pageUrl || trans.store.pageUrl,pageName: pageName || trans.store.pageName,text: JSON.stringify(texts)}return interface2(data).then((data: any) => data.payload && data.payload.text).catch((err: any) => {return texts})}// 翻译(本地内存和api混合)const translateTexts = async (texts: any, option: any) => {await ready();const to = option && option.to || trans.language.toconst from = option && option.from || trans.language.fromconst pageUrl = option && option.pageUrl || trans.store.pageUrlconst pageName = [option && option.pageName || trans.store.pageName, option && option.mark || ''].filter(item => item).join(CONNECTOR)if (!to || to === from) {return Promise.resolve(texts)}const requestTexts = [...new Set(texts)].filter(text => !trans.store.getValue(text, option))if (requestTexts.length === 0) {return Promise.resolve(texts.map((text: any) => trans.store.getValue(text, option)))}// 分组const requestTextsGroups = groupByLength(requestTexts, GROUP_LEN)const promises = requestTextsGroups.map((group: any) => translateTextsByApi(group, { pageUrl, pageName, to, from }).then((values: any) => {trans.store.setValues(group, values, option)}))return Promise.all(promises).then(res => {return texts.map((text: any) => trans.store.getValue(text, option))})};// 文本翻译function translateText(text: any, option: any, callback: any) {const key = trans.store.getKeyByOption('', option)cacheTextMap[key] = cacheTextMap[key] || []if (text) {cacheTextMap[key].push(text)}callbackMap[key] = callbackMap[key] || []if (callback) {callbackMap[key].push(() => {callback(trans.store.getValue(text, option), text)})}ready().then(_ => {translateFromCacheKey(key, option)})// 没有内容直接返回 return ''if (!text) {return ''}// 根据页面和标记分组if (trans.store.getValue(text, option, callback)) {return trans.store.getValue(text, option)}return trans.store.getValue(text, option)}// 文本异步翻译function translateFromCacheKey(key: any, option: any) {if (cacheTextMap[key]) {const callbacks = callbackMap[key]translateTexts(cacheTextMap[key], { pageUrl: trans.store.pageUrl, ...(option || {}) }).then(_ => {callbacks.forEach((f: any) => f())})}cacheTextMap[key] = []callbackMap[key] = []}function translate(text: any, option: any, callback: any, loop: any) {if (typeof text === 'string') {return translateText(text, option, callback)}if (text === null || typeof text !== 'object') {return text}// 避免对象循环引用loop = loop || new Set()if (loop.has(text)) {return}loop.add(text)// 遍历属性Object.keys(text).forEach(prop => {if ((typeof text[prop] === 'string')) {const textStr = text[prop]// 切换语言环境找回原来文本(无需刷新页面)if (trans.store.getFromText(textStr)) {const from = trans.store.getFromText(text[prop])translateText(from, option, (resText: any) => {text[prop] = resTexttrans.store.setFromText(text[prop], from)})return}// 中文匹配if (textStr.match(ZH_REGEXP)) {const from = textStrtranslateText(from, option, (resText: any) => {text[prop] = resTexttrans.store.setFromText(text[prop], from)})return}}if (text[prop] !== null && typeof text[prop] === 'object') {// 递归translate(text[prop], option, null, loop)}})// 对象回调放到最后const key = trans.store.getKeyByOption('', option)callbackMap[key] = callbackMap[key] || []if (callback) {callbackMap[key].push(() => {callback(text, text)})}return text}app.config.globalProperties.$translate = new Translate()app.config.globalProperties.$t = translateapp.provide('$translate', new Translate())app.provide('$t', translate)}
};

2.2、main.ts

import mi18n from '@v3/plugins/mi18n'app.use(mi18n, { option: true })

2.3、页面使用

<el-button :text="true" @click="getOpenHistory">{{ $t('查看') }}</el-button>

三、效果

经测试,满足使用

四、欢迎交流指正

五、参考链接

Vue3 + TS + Element Plus + i18n / 国际化:vue-i18n 的使用 / 国际化_element plus i18n-CSDN博客

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com