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>

猜你喜欢

转载自blog.csdn.net/weixin_43245095/article/details/126505068