vue 或 js 使用谷歌翻译实现国际化

问题

一般没有适配国际化的页面 我们会使用谷歌翻译插件进行翻译。
但由于使用浏览器中的谷歌翻译插件 会导致dom的结构发生改变,从而导致 vue react与dom操作绑定关系失效!这样就无法触发跳转路由等操作。
下面的方法可以使得我们即使用谷歌翻译 又不会导致dom结构发生改变 兼容vue react(把vue代码改写一下)框架。

效果

hhh-google-translate
请添加图片描述

注意

而且选择语言时,切换语言最好先切换为源语言,再切换翻译语言,不然谷歌翻译会翻译错乱。

代码

hhh-google-translate 组件

这是我参考
利用Google翻译实现网站国际化——js插件
v-google-translate 写的。
目前有两个版本 切换组件的index.vue。 其中( 翻译input提示内容 无法翻译),需要在public 的添加css及js 已放置在google-translate-vue中,可下载使用。
google-translate内容图片
在这里插入图片描述

demo 代码 如下

//hhh-google-translate 组件
<template>
  <div>
    <div id="google_translate_element"></div>
  </div>
</template>

<script>
// import googleElement from "./google-element";
export default {
  name: "hhh-google-translate",
  props: {
    // 语言列表
    languages: {
      type: Array,
      default() {
        // 遵循 ISO 639-1 标准,俩位的code
        // 参考:https://zh.wikipedia.org/wiki/ISO_639-1
        return [
          {
            code: "en",
            name: "English",
            cname: "英语",
            ename: "English",
          },
          {
            code: "af",
            name: "Afrikaans",
            cname: "南非语",
            ename: "Afrikaans",
          },
          {
            code: "sq",
            name: "Gjuha shqipe",
            cname: "阿尔巴尼亚语",
            ename: "Albanian",
          },
          {
            code: "ar",
            name: "العربية",
            cname: "阿拉伯语",
            ename: "Arabic",
          },
          {
            code: "hy",
            name: "Հայերեն",
            cname: "亚美尼亚语",
            ename: "Armenian",
          },
          {
            code: "az",
            name: "Азәрбајҹан дили",
            cname: "阿塞拜疆语",
            ename: "Azerbaijani",
          },
          {
            code: "eu",
            name: "Euskara",
            cname: "巴斯克语",
            ename: "Basque",
          },
          {
            code: "be",
            name: "беларуская мова",
            cname: "白俄罗斯语",
            ename: "Belarusian",
          },
          {
            code: "bg",
            name: "български език",
            cname: "保加利亚语",
            ename: "Bulgarian",
          },
          {
            code: "ca",
            name: "Català",
            cname: "加泰罗尼亚语",
            ename: "Catalan",
          },
          {
            code: "zh-CN",
            name: "Chinese (Simplified)",
            cname: "中文 (简体)",
            ename: "Chinese (Simplified)",
          },
          {
            code: "zh-TW",
            name: "Chinese (Traditional)",
            cname: "中文 (繁体)",
            ename: "Chinese (Traditional)",
          },
          {
            code: "hr",
            name: "Српскохрватски језик",
            cname: "克罗地亚语",
            ename: "Croatian",
          },
          {
            code: "cs",
            name: "čeština",
            cname: "捷克语",
            ename: "Czech",
          },
          {
            code: "da",
            name: "Danmark",
            cname: "丹麦语",
            ename: "Danish",
          },
          {
            code: "nl",
            name: "Nederlands",
            cname: "荷兰语",
            ename: "Dutch",
          },
          {
            code: "et",
            name: "eesti keel",
            cname: "爱沙尼亚语",
            ename: "Estonian",
          },
          {
            code: "tl",
            name: "Filipino",
            cname: "菲律宾语",
            ename: "Filipino",
          },
          {
            code: "fi",
            name: "Finnish",
            cname: "芬兰语",
            ename: "Finnish",
          },
          {
            code: "fr",
            name: "Français",
            cname: "法语",
            ename: "French",
          },
          {
            code: "de",
            name: "Deutsch",
            cname: "德语",
            ename: "German",
          },
          {
            code: "el",
            name: "Ελληνικά",
            cname: "希腊语",
            ename: "Greek",
          },
          {
            code: "hu",
            name: "magyar",
            cname: "匈牙利语",
            ename: "Hungarian",
          },
          {
            code: "id",
            name: "Indonesia",
            cname: "印度尼西亚语",
            ename: "Indonesian",
          },
          {
            code: "ga",
            name: "Irish",
            cname: "爱尔兰语",
            ename: "Irish",
          },
          {
            code: "it",
            name: "Italiano",
            cname: "意大利语",
            ename: "Italian",
          },
          {
            code: "ja",
            name: "にほんご",
            cname: "日语",
            ename: "Japanese",
          },
          {
            code: "ko",
            name: "한국어",
            cname: "韩语",
            ename: "Korean",
          },
          {
            code: "lt",
            name: "lietuvių kalba",
            cname: "立陶宛语",
            ename: "Lithuanian",
          },
          {
            code: "ms",
            name: "Malay",
            cname: "马来西亚语",
            ename: "Malay",
          },
          {
            code: "no",
            name: "norsk",
            cname: "挪威语",
            ename: "Norwegian",
          },
          {
            code: "pl",
            name: "Polski",
            cname: "波兰语",
            ename: "Polish",
          },
          {
            code: "pt",
            name: "Português",
            cname: "葡萄牙语",
            ename: "Portuguese",
          },
          {
            code: "ro",
            name: "limba română",
            cname: "罗马尼亚语",
            ename: "Romanian",
          },
          {
            code: "ru",
            name: "Русский",
            cname: "俄语",
            ename: "Russian",
          },
          {
            code: "es",
            name: "Español",
            cname: "西班牙语",
            ename: "Spanish",
          },
          {
            code: "sv",
            name: "Swedish",
            cname: "瑞典语",
            ename: "Swedish",
          },
          {
            code: "th",
            name: "ภาษาไทย",
            cname: "泰语",
            ename: "Thai",
          },
          {
            code: "tr",
            name: "Turkish",
            cname: "土耳其语",
            ename: "Turkish",
          },
          {
            code: "uk",
            name: "українська мова",
            cname: "乌克兰语",
            ename: "Ukrainian",
          },
        ];
      },
    },
    //默认页面源语言 code
    defaultPageLanguageCode: {
      type: String,
      default: "auto",//zh-CN  简体中文
    },
  },
  data() {
    return {};
  },
  created() {},
  computed: {
    includedLanguages() {
      if (this.languages && this.languages.length) {
        let languagesList =
          this.languages.map((item) => {
            return item.code;
          }) || [];
        return languagesList.join(",");
      }
      return "";
    },
  },
  mounted() {
    window.googleTranslateElementInit = () => {
      //记录 谷歌翻译是否已经初始化
      window.hhhTransLateInit = true;
      console.log("window.google.translate", window.google.translate);
      // new window.google.translate.TranslateElement({ pageLanguage: this.defaultPageLanguageCode, autoDisplay: false }, "google_translate_element");
      new window.google.translate.TranslateElement(
        { pageLanguage: this.defaultPageLanguageCode, includedLanguages: this.includedLanguages, autoDisplay: true, layout: google.translate.TranslateElement.InlineLayout.SIMPLE },
        "google_translate_element"
      );
    };
    console.log("window.hhhTransLateInit", window.hhhTransLateInit);
    //如果谷歌翻译已经初始化 
    if (window.hhhTransLateInit) {
      // 重新渲染到 google_translate_element 上
_loadJs("https:\/\/translate.googleapis.com\/_\/translate_http\/_\/js\/k\x3dtranslate_http.tr.zh_CN.QLOO522nbPo.O\/d\x3d1\/exm\x3del_conf\/ed\x3d1\/rs\x3dAN8SPfrH_TG1Vgc2X6ozBFVgRhW67pLkSQ\/m\x3del_main");
    }
    // if (window.google.translate.TranslateElement) {
    //   new window.google.translate.TranslateElement({ includedLanguages: this.includedLanguages, autoDisplay: false, layout: google.translate.TranslateElement.InlineLayout.SIMPLE }, "google_translate_element");
    // }
    this.dynamicLoadJs("//translate.google.cn/translate_a/element.js?cb=googleTranslateElementInit");
  },
  methods: {
    // 动态加载js文件
    dynamicLoadJs(jsUrl, fn = () => {}, errorCallBack = () => {}, jsId = "") {
      const scriptList = document.querySelectorAll("script");
      console.log("scriptList", scriptList);
      const isLoad = [...scriptList].find((item) => {
        return item.getAttribute("src") == jsUrl;
      });
      console.log("isLoad", isLoad);
      if (!isLoad) {
        const _doc = document.querySelector("body");
        const script = document.createElement("script");

        script.onload = script.onreadystatechange = function() {
          console.log("this.readyState", this.readyState);
          //   加载成功
          if (!this.readyState || this.readyState === "loaded" || this.readyState === "complete") {
            fn && fn();
          }
          // 加载失败
          if (!this.readyState || ((this.readyState === "loaded" || this.readyState === "complete") && !window["_DumpException"])) {
            errorCallBack && errorCallBack();
          }
          script.onload = script.onreadystatechange = null;
        };
        script.setAttribute("type", "text/javascript");
        script.setAttribute("src", jsUrl);
        jsId && script.setAttribute("id", jsId);
        _doc.appendChild(script);
      }
    },
  },
};
</script>

<style>
body {
  top: 0 !important;
}
.skiptranslate iframe {
  display: none;
}

/* 去除查看原文 */
#goog-gt-tt {
  display: none !important;
}
/* 去除选择文字高亮 */
.goog-text-highlight{
  background-color: inherit !important;
  box-shadow: none !important;
}
#google_translate_element {
  /* width: 150px; */
  /* display: flex; */
  /* position: absolute;
  top: 0;
  right: 0;
  z-index: 2000;
  opacity: 0.7; */
}

#google_translate_element .goog-te-gadget {
  width: 100%;
  height: 100%;
}
#google_translate_element .goog-te-gadget .goog-te-gadget-simple {
  background-color: transparent;
  border: none;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
}
/* 去除重复的内容 */
/* #google_translate_element .goog-te-gadget .goog-te-gadget-simple span:nth-of-type(n + 2) {
  display: none;
}
#google_translate_element .goog-te-gadget .goog-te-gadget-simple img:nth-of-type(n + 2) {
  display: none;
} */
/* #google_translate_element .goog-te-menu-value:first-child {
  display: inline-block;
} */
#google_translate_element .goog-te-menu-value :nth-child(n + 2) {
  display: none;
}
#google_translate_element .goog-te-menu-value img {
  width: 1em !important;
  height: 1em !important;
}
/* .skiptranslate {
  display: none !important;
} */
</style>

使用

// 如果想全局先引入 谷歌的element.js文件 请在 index.html 添加以下script
//index.html
  <div id="app"></div>
  <script async src="//translate.google.cn/translate_a/element.js?cb=googleTranslateElementInit"></script>

//使用
<hhh-google-translate />
v-google-translate 组件
yarn add v-google-translate
npm i v-google-translate

使用

// main.js
import vGoogleTranslate from "v-google-translate";
Vue.use(vGoogleTranslate);

// xxx.vue
<template>
  <div>
  <v-google-translate />
  <div>
</template>

不过使用 npm 安装 可能会报错

gyp ERR! find Python 
gyp ERR! find VS msvs_version not set from command line or npm config

缺少python 环境 缺少c++环境
如果报错建议去github下载源码
具体参考 v-google-translate

这两个组件都可以通过 添加 notranslate 类名,这样谷歌翻译将不会翻译该元素内文字

<a :href="href" class="navbar-brand  notranslate">不翻译的字</a>
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: 在Vue3中,可以使用多种方法实现菜单的国际化。 一种常见的方法是使用Vue I18n插件来实现国际化。首先,需要安装并引入Vue I18n插件。然后,创建一个包含所有不同语言的语言文件,在这些文件中按照键值对的形式定义菜单的文本。在Vue组件中,通过调用I18n插件的翻译方法,根据当前语言来获取对应的菜单文本。 另一种方法是使用Vue的组件内部化(i18n)选项。首先,需要在Vue组件的选项中添加i18n对象,并在该对象中定义菜单的文本。在模板中,使用指令或插值的方式来引用菜单文本。Vue会根据当前语言选择适当的文本进行替换。 除了以上两种方法,还可以使用第三方库来实现国际化。例如,可以使用vue-i18n库或vue-multilanguage库来实现菜单的国际化。这些库提供了更多的功能和选项,方便管理和切换不同语言的菜单文本。 总结来说,Vue3中实现菜单的国际化可以通过使用Vue I18n插件、组件内部化(i18n)选项或第三方库来实现。具体选择哪种方法,可以根据项目的需求和复杂度来决定。 ### 回答2: 实现Vue3菜单的国际化有多种方式。以下是一种常见的方法: 1. 首先,在Vue3项目中安装并配置一个适合国际化的插件,比如vue-i18n。 2. 在项目中的主文件中引入vue-i18n,并在Vue实例中配置i18n插件,设置默认语言和翻译数据。 ```javascript import { createApp } from 'vue' import { createI18n } from 'vue-i18n' const i18n = createI18n({ locale: 'en', // 设置默认语言 messages: { en: { menu: { home: 'Home', about: 'About', contact: 'Contact' } }, zh: { menu: { home: '首页', about: '关于我们', contact: '联系我们' } } } }) createApp(App).use(i18n).mount('#app') ``` 3. 在菜单组件中使用vue-i18n的翻译功能来处理菜单文字。使用`$t`方法根据当前语言选择对应的翻译文字。 ```html <template> <div> <ul> <li>{{ $t('menu.home') }}</li> <li>{{ $t('menu.about') }}</li> <li>{{ $t('menu.contact') }}</li> </ul> </div> </template> ``` 4. 在页面中切换语言时,可以通过调用`$i18n.locale`方法来切换当前的语言。比如使用一个按钮来切换语言。 ```html <template> <div> <button @click="changeLanguage('zh')">中文</button> <button @click="changeLanguage('en')">English</button> <menu-component></menu-component> </div> </template> <script> export default { methods: { changeLanguage(language) { this.$i18n.locale = language; } } } </script> ``` 通过以上步骤,我们就可以实现Vue3菜单的国际化。用户可以点击按钮切换语言,菜单中的文字将会根据当前选择的语言进行相应的翻译。 ### 回答3: Vue3提供了多种实现菜单国际化的方法。 一种常用的方法是使用Vue-i18n插件。首先,安装并引入Vue-i18n插件。接下来,在项目中创建一个国际化配置文件,包含菜单的多语言文本。可以根据菜单的不同语言版本,在配置文件中建立对应的键值对。然后,在Vue实例中,实例化Vue-i18n插件,将配置文件作为参数传入。在菜单组件中,使用插件提供的翻译函数,根据当前语言选择对应的菜单文本。 另一种方法是使用Vue3的Composition API。在Vue3中,可以使用Vue的reactive功能和自定义函数来实现国际化。首先,在项目中创建一个国际化的数据文件,包含不同语言的菜单文本。然后,创建一个自定义函数,根据当前语言选择对应的菜单文本。在菜单组件中,使用reactive函数将国际化的数据文件转化为响应式数据,然后使用自定义函数获取当前语言对应的菜单文本。 除了以上方法,还可以使用第三方库来实现菜单的国际化,比如vue-i18next。这个库提供了更多的功能和选项,使菜单国际化实现更加灵活和方便。 总结来说,Vue3中可以使用Vue-i18n插件、Composition API和第三方库等方法来实现菜单的国际化。具体选择哪种方法,可以根据项目需求和个人喜好来决定。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值