i18n-jsautotranslate 3.18.72 → 3.18.74

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,14 +5,14 @@ http://translate.zvo.cn/4041.html
5
5
 
6
6
  ## 页面上出现语言切换的Select下拉切换菜单
7
7
 
8
- #### 效果
8
+ ### 效果
9
9
  见下图右上角的多语言切换
10
10
  ![](./resource/preview.png)
11
11
 
12
- #### 代码
12
+ ### 代码
13
13
 
14
14
  比如要在 index.vue 页面上显示切换语言的 select 下拉菜单,那么 index.vue 页面中,要进行的操作:
15
- 先在 index.vue 中,加入一行导入 ArcoDesign 的多语言切换Select
15
+ 先在 index.vue 中,加入一行导入此UI框架的多语言切换Select
16
16
  ````import LanguageSelect from 'i18n-jsautotranslate/ArcoDesign/Vue3/LanguageSelect.vue';````
17
17
  然后在要显示select菜单的位置,直接加入
18
18
  ````<LanguageSelect/>````
package/index.js CHANGED
@@ -14,7 +14,7 @@ var translate = {
14
14
  * 格式:major.minor.patch.date
15
15
  */
16
16
  // AUTO_VERSION_START
17
- version: '3.18.72.20251010',
17
+ version: '3.18.75.20251011',
18
18
  // AUTO_VERSION_END
19
19
  /*
20
20
  当前使用的版本,默认使用v2. 可使用 setUseVersion2();
@@ -97,6 +97,61 @@ var translate = {
97
97
 
98
98
  translate.selectLanguageTag.render();
99
99
  },
100
+ /*
101
+ 自定义语种 translate.selectLanguageTag.languages 的处理,进行按顺序筛选出来
102
+
103
+ @param languageList 当前支持的所有语种列表,传入格式如:
104
+ [
105
+ {id: 'english', name: 'English', serviceId: 'en'},
106
+ {id: 'korean', name: '한국어', serviceId: 'ko'},
107
+ ...
108
+ ]
109
+
110
+ 返回值是将当前翻译通道所支持的语种进行按顺序筛选完后的结果返回。
111
+ 比如
112
+ translate.selectLanguageTag.languages = 'english,chinese_simplified,korean';
113
+ 那么这里返回的便是
114
+
115
+ [
116
+ {id: 'english', name: 'English', serviceId: 'en'},
117
+ {id: 'chinese_simplified', name: '简体中文', serviceId: 'zh-CHS'},
118
+ {id: 'korean', name: '한국어', serviceId: 'ko'}
119
+ ]
120
+
121
+ 如果 translate.selectLanguageTag.languages 未设置,那么这里将返回当前支持的所有语种
122
+ */
123
+ customLanguagesHandle:function(languageList){
124
+ if(translate.selectLanguageTag.languages.length > 0){
125
+ //设置了自定义显示的语言,需要重新根据自定义的语言进行过滤,同时顺序也要保持跟它一致
126
+
127
+ //都转小写判断
128
+ var divLanguages = translate.selectLanguageTag.languages.toLowerCase();
129
+ var divArray = divLanguages.split(',');
130
+
131
+ //将支持的语种 languageList 转化为 map 形态
132
+ if(typeof(translate.selectLanguageTag.supportLanguageMap) == 'undefined'){
133
+ translate.selectLanguageTag.supportLanguageMap = new Map();
134
+ for(var si = 0; si<languageList.length; si++){
135
+ if(typeof(languageList[si]) != 'undefined' && typeof(languageList[si].id)){
136
+ translate.selectLanguageTag.supportLanguageMap.set(languageList[si].id, languageList[si]);
137
+ }
138
+ }
139
+ //console.log(translate.selectLanguageTag.supportLanguageMap)
140
+ }
141
+
142
+
143
+ //重新组合要显示的语种
144
+ var newLangs = [];
145
+ for(var i = 0; i<divArray.length; i++){
146
+ if(divArray[i].length > 0 && translate.selectLanguageTag.supportLanguageMap.get(divArray[i]) != null){
147
+ newLangs.push(translate.selectLanguageTag.supportLanguageMap.get(divArray[i]));
148
+ }
149
+ }
150
+ return newLangs;
151
+ }
152
+
153
+ return languageList;
154
+ },
100
155
 
101
156
  /*
102
157
  自定义切换语言的样式渲染 v3.2.4 增加
@@ -111,24 +166,13 @@ var translate = {
111
166
  selectLanguage.id = translate.selectLanguageTag.documentId+'SelectLanguage';
112
167
  selectLanguage.className = translate.selectLanguageTag.documentId+'SelectLanguage';
113
168
  var to = translate.language.getCurrent();
169
+
170
+
114
171
  for(var i = 0; i<languageList.length; i++){
115
172
  var option = document.createElement("option");
116
173
  option.setAttribute("value",languageList[i].id);
117
174
 
118
- //判断 selectLanguageTag.languages 中允许使用哪些
119
-
120
- if(translate.selectLanguageTag.languages.length > 0){
121
- //设置了自定义显示的语言
122
-
123
- //都转小写判断
124
- var langs_indexof = (','+translate.selectLanguageTag.languages+',').toLowerCase();
125
- //console.log(langs_indexof)
126
- if(langs_indexof.indexOf(','+languageList[i].id.toLowerCase()+',') < 0){
127
- //没发现,那不显示这个语种,调出
128
- continue
129
- }
130
- }
131
-
175
+
132
176
  /*判断默认要选中哪个语言*/
133
177
 
134
178
  if(to != null && typeof(to) != 'undefined' && to.length > 0){
@@ -197,11 +241,11 @@ var translate = {
197
241
  }
198
242
  //console.log(data.list);
199
243
  translate.request.api.language = data.list; //进行缓存,下一次切换语言渲染的时候直接从缓存取,就不用在通过网络加载了
200
- translate.selectLanguageTag.customUI(data.list);
244
+ translate.selectLanguageTag.customUI(translate.selectLanguageTag.customLanguagesHandle(data.list));
201
245
  }, null);
202
246
  }else if(typeof(translate.request.api.language) == 'object'){
203
247
  //无网络环境下,自定义显示语种
204
- translate.selectLanguageTag.customUI(translate.request.api.language);
248
+ translate.selectLanguageTag.customUI(translate.selectLanguageTag.customLanguagesHandle(translate.request.api.language));
205
249
  }
206
250
  }
207
251
  },
@@ -7249,10 +7293,8 @@ var translate = {
7249
7293
  //客户端方式的edge提供机器翻译服务
7250
7294
  edge:{
7251
7295
  api:{ //edge浏览器的翻译功能
7252
- auth:'https://edge.microsoft.com/translate/auth', //auth授权拉取
7253
- translate:'https://api.cognitive.microsofttranslator.com/translate?from={from}&to={to}&api-version=3.0&includeSentenceLength=true' //翻译接口
7296
+ translate:'https://edge.microsoft.com/translate/translatetext?from={from}&to={to}&isEnterpriseClient=false' //翻译接口
7254
7297
  },
7255
-
7256
7298
  language:{
7257
7299
 
7258
7300
  json:[{"id":"ukrainian","name":"Україна","serviceId":"uk"},{"id":"norwegian","name":"Norge","serviceId":"no"},{"id":"welsh","name":"Iaith Weleg","serviceId":"cy"},{"id":"dutch","name":"nederlands","serviceId":"nl"},{"id":"japanese","name":"日本語","serviceId":"ja"},{"id":"filipino","name":"Pilipino","serviceId":"fil"},{"id":"english","name":"English","serviceId":"en"},{"id":"lao","name":"ກະຣຸນາ","serviceId":"lo"},{"id":"telugu","name":"తెలుగుName","serviceId":"te"},{"id":"romanian","name":"Română","serviceId":"ro"},{"id":"nepali","name":"नेपालीName","serviceId":"ne"},{"id":"french","name":"Français","serviceId":"fr"},{"id":"haitian_creole","name":"Kreyòl ayisyen","serviceId":"ht"},{"id":"czech","name":"český","serviceId":"cs"},{"id":"swedish","name":"Svenska","serviceId":"sv"},{"id":"russian","name":"Русский язык","serviceId":"ru"},{"id":"malagasy","name":"Malagasy","serviceId":"mg"},{"id":"burmese","name":"ဗာရမ်","serviceId":"my"},{"id":"pashto","name":"پښتوName","serviceId":"ps"},{"id":"thai","name":"คนไทย","serviceId":"th"},{"id":"armenian","name":"Արմենյան","serviceId":"hy"},{"id":"chinese_simplified","name":"简体中文","serviceId":"zh-CHS"},{"id":"persian","name":"Persian","serviceId":"fa"},{"id":"chinese_traditional","name":"繁體中文","serviceId":"zh-CHT"},{"id":"kurdish","name":"Kurdî","serviceId":"ku"},{"id":"turkish","name":"Türkçe","serviceId":"tr"},{"id":"hindi","name":"हिन्दी","serviceId":"hi"},{"id":"bulgarian","name":"български","serviceId":"bg"},{"id":"malay","name":"Malay","serviceId":"ms"},{"id":"swahili","name":"Kiswahili","serviceId":"sw"},{"id":"oriya","name":"ଓଡିଆ","serviceId":"or"},{"id":"icelandic","name":"ÍslandName","serviceId":"is"},{"id":"irish","name":"Íris","serviceId":"ga"},{"id":"khmer","name":"ភាសា​ខ្មែរName","serviceId":"km"},{"id":"gujarati","name":"ગુજરાતી","serviceId":"gu"},{"id":"slovak","name":"Slovenská","serviceId":"sk"},{"id":"kannada","name":"ಕನ್ನಡ್Name","serviceId":"kn"},{"id":"hebrew","name":"היברית","serviceId":"he"},{"id":"hungarian","name":"magyar","serviceId":"hu"},{"id":"marathi","name":"मराठीName","serviceId":"mr"},{"id":"tamil","name":"தாமில்","serviceId":"ta"},{"id":"estonian","name":"eesti keel","serviceId":"et"},{"id":"malayalam","name":"മലമാലം","serviceId":"ml"},{"id":"inuktitut","name":"ᐃᓄᒃᑎᑐᑦ","serviceId":"iu"},{"id":"arabic","name":"بالعربية","serviceId":"ar"},{"id":"deutsch","name":"Deutsch","serviceId":"de"},{"id":"slovene","name":"slovenščina","serviceId":"sl"},{"id":"bengali","name":"বেঙ্গালী","serviceId":"bn"},{"id":"urdu","name":"اوردو","serviceId":"ur"},{"id":"azerbaijani","name":"azerbaijani","serviceId":"az"},{"id":"portuguese","name":"português","serviceId":"pt"},{"id":"samoan","name":"lifiava","serviceId":"sm"},{"id":"afrikaans","name":"afrikaans","serviceId":"af"},{"id":"tongan","name":"汤加语","serviceId":"to"},{"id":"greek","name":"ελληνικά","serviceId":"el"},{"id":"indonesian","name":"IndonesiaName","serviceId":"id"},{"id":"spanish","name":"Español","serviceId":"es"},{"id":"danish","name":"dansk","serviceId":"da"},{"id":"amharic","name":"amharic","serviceId":"am"},{"id":"punjabi","name":"ਪੰਜਾਬੀName","serviceId":"pa"},{"id":"albanian","name":"albanian","serviceId":"sq"},{"id":"lithuanian","name":"Lietuva","serviceId":"lt"},{"id":"italian","name":"italiano","serviceId":"it"},{"id":"vietnamese","name":"Tiếng Việt","serviceId":"vi"},{"id":"korean","name":"한국어","serviceId":"ko"},{"id":"maltese","name":"Malti","serviceId":"mt"},{"id":"finnish","name":"suomi","serviceId":"fi"},{"id":"catalan","name":"català","serviceId":"ca"},{"id":"croatian","name":"hrvatski","serviceId":"hr"},{"id":"bosnian","name":"bosnian","serviceId":"bs-Latn"},{"id":"polish","name":"Polski","serviceId":"pl"},{"id":"latvian","name":"latviešu","serviceId":"lv"},{"id":"maori","name":"Maori","serviceId":"mi"}],
@@ -7282,105 +7324,102 @@ var translate = {
7282
7324
  translate:function(path, data, func, abnormalFunc){
7283
7325
  var textArray = JSON.parse(decodeURIComponent(data.text));
7284
7326
  let translateTextArray = translate.util.split(textArray, 40000, 900);
7327
+
7328
+
7329
+ var appendXhrData = {
7330
+ "from":data.from+'',
7331
+ "to":data.to,
7332
+ "text":data.text
7333
+ };
7334
+ var from = data.from;
7335
+ if(from != 'auto'){
7336
+ if(from == 'romance'){
7337
+ //这里额外加了一个罗曼语族(romance)会自动认为是法语(fr)
7338
+ from = 'fr';
7339
+ }else{
7340
+ from = translate.service.edge.language.getMap()[data.from];
7341
+ }
7342
+ }
7285
7343
 
7286
- translate.request.send(translate.service.edge.api.auth, {},{}, function(auth){
7287
- var appendXhrData = {
7288
- "from":data.from+'',
7289
- "to":data.to,
7290
- "text":data.text
7291
- };
7292
- var from = data.from;
7293
- if(from != 'auto'){
7294
- if(from == 'romance'){
7295
- //这里额外加了一个罗曼语族(romance)会自动认为是法语(fr)
7296
- from = 'fr';
7297
- }else{
7298
- from = translate.service.edge.language.getMap()[data.from];
7299
- }
7344
+ var to = translate.service.edge.language.getMap()[data.to];
7345
+ var transUrl = translate.service.edge.api.translate.replace('{from}',from).replace('{to}',to);
7346
+
7347
+ //如果翻译量大,要拆分成多次翻译请求
7348
+ for(var tai = 0; tai<translateTextArray.length; tai++){
7349
+ /*
7350
+ var json = [];
7351
+ for(var i = 0; i<translateTextArray[tai].length; i++){
7352
+ json.push({"Text":translateTextArray[tai][i]});
7300
7353
  }
7301
-
7302
- var to = translate.service.edge.language.getMap()[data.to];
7303
- var transUrl = translate.service.edge.api.translate.replace('{from}',from).replace('{to}',to);
7304
-
7305
- //如果翻译量大,要拆分成多次翻译请求
7306
- for(var tai = 0; tai<translateTextArray.length; tai++){
7307
- var json = [];
7308
- for(var i = 0; i<translateTextArray[tai].length; i++){
7309
- json.push({"Text":translateTextArray[tai][i]});
7310
- }
7354
+ */
7311
7355
 
7312
- translate.request.send(transUrl, JSON.stringify(json), appendXhrData, function(result){
7313
- var d = {};
7314
- d.info = 'SUCCESS';
7315
- d.result = 1;
7316
- d.from = data.from;
7317
- d.to = data.to;
7318
- d.text = [];
7319
- for(var t = 0; t < result.length; t++){
7320
- d.text.push(result[t].translations[0].text);
7321
- }
7322
-
7356
+ translate.request.send(transUrl, JSON.stringify(translateTextArray[tai]), appendXhrData, function(result){
7357
+ var d = {};
7358
+ d.info = 'SUCCESS';
7359
+ d.result = 1;
7360
+ d.from = data.from;
7361
+ d.to = data.to;
7362
+ d.text = [];
7363
+ for(var t = 0; t < result.length; t++){
7364
+ d.text.push(result[t].translations[0].text);
7365
+ }
7366
+
7323
7367
 
7324
- //判断当前翻译是否又被拆分过,比如一次超过5万字符的话就要拆分成多次请求了
7325
- if(translateTextArray.length > 1){
7326
- //这一次翻译呗拆分了多次请求,那么要进行补全数组,使数组个数能一致
7368
+ //判断当前翻译是否又被拆分过,比如一次超过5万字符的话就要拆分成多次请求了
7369
+ if(translateTextArray.length > 1){
7370
+ //这一次翻译呗拆分了多次请求,那么要进行补全数组,使数组个数能一致
7327
7371
 
7328
- /*
7372
+ /*
7329
7373
 
7330
- 注意这里根据数组的长度来判断当前属于第几个数组,
7331
- 有几率会是拆分的数组,其中有两组的长度是一样的,
7332
- 这样的话是有问题的,只不过几率很小,就先这样了
7333
- 但终归还是留了个坑 -- 记录
7374
+ 注意这里根据数组的长度来判断当前属于第几个数组,
7375
+ 有几率会是拆分的数组,其中有两组的长度是一样的,
7376
+ 这样的话是有问题的,只不过几率很小,就先这样了
7377
+ 但终归还是留了个坑 -- 记录
7334
7378
 
7335
- */
7379
+ */
7336
7380
 
7337
- var currentIndex = -1; //当前翻译请求属于被拆分的第几个的数组下标,从0开始的
7338
- for(var cri = 0; cri < translateTextArray.length; cri++){
7339
- if(translateTextArray[cri].length - d.text.length == 0){
7340
- currentIndex = cri;
7341
- break;
7342
- }
7381
+ var currentIndex = -1; //当前翻译请求属于被拆分的第几个的数组下标,从0开始的
7382
+ for(var cri = 0; cri < translateTextArray.length; cri++){
7383
+ if(translateTextArray[cri].length - d.text.length == 0){
7384
+ currentIndex = cri;
7385
+ break;
7343
7386
  }
7387
+ }
7344
7388
 
7345
- //进行对前后进行补齐数组
7346
- if(currentIndex < 0){
7347
- translate.log('------ERROR--------');
7348
- translate.log('翻译内容过多,进行拆分,但拆分判断出现异常,currentIndex:-1 请联系 http://translate.zvo.cn/43006.html 说明');
7349
- }
7350
- //前插入空数组填充
7351
- for(var addbeforei = 0; addbeforei<currentIndex; addbeforei++){
7352
- var beforeItemArrayLength = translateTextArray[addbeforei].length;
7353
- //console.log('beforeItemArrayLength:'+beforeItemArrayLength);
7354
- for(var bi = 0; bi < beforeItemArrayLength; bi++){
7355
- d.text.unshift(null);
7356
- }
7389
+ //进行对前后进行补齐数组
7390
+ if(currentIndex < 0){
7391
+ translate.log('------ERROR--------');
7392
+ translate.log('翻译内容过多,进行拆分,但拆分判断出现异常,currentIndex:-1 请联系 http://translate.zvo.cn/43006.html 说明');
7393
+ }
7394
+ //前插入空数组填充
7395
+ for(var addbeforei = 0; addbeforei<currentIndex; addbeforei++){
7396
+ var beforeItemArrayLength = translateTextArray[addbeforei].length;
7397
+ //console.log('beforeItemArrayLength:'+beforeItemArrayLength);
7398
+ for(var bi = 0; bi < beforeItemArrayLength; bi++){
7399
+ d.text.unshift(null);
7357
7400
  }
7358
- //后插入空数组填充
7359
- for(var addafteri = translateTextArray.length-1; addafteri>currentIndex; addafteri--){
7360
- var afterItemArrayLength = translateTextArray[addafteri].length;
7361
- for(var bi = 0; bi < afterItemArrayLength; bi++){
7362
- d.text.push(null);
7363
- }
7401
+ }
7402
+ //后插入空数组填充
7403
+ for(var addafteri = translateTextArray.length-1; addafteri>currentIndex; addafteri--){
7404
+ var afterItemArrayLength = translateTextArray[addafteri].length;
7405
+ for(var bi = 0; bi < afterItemArrayLength; bi++){
7406
+ d.text.push(null);
7364
7407
  }
7365
-
7366
7408
  }
7367
7409
 
7368
- func(d);
7369
- }, 'post', true, {'Authorization':'Bearer '+auth, 'Content-Type':'application/json'}, abnormalFunc, true);
7410
+ }
7370
7411
 
7371
-
7372
- }
7373
- //console.log('translateResultArray')
7374
- //console.log(translateResultArray);
7412
+ func(d);
7413
+ }, 'post', true, {
7414
+ 'Content-Type':'application/json'
7415
+ }, abnormalFunc, true);
7375
7416
 
7376
7417
 
7377
- }, 'get', true, {'content-type':'application/x-www-form-urlencoded'}, function(xhr){
7378
- translate.log('---------error--------');
7379
- translate.log('edge translate service error, http code : '+xhr.status + ', response text : '+xhr.responseText);
7380
- }, true);
7418
+ }
7381
7419
 
7382
7420
 
7383
7421
 
7422
+
7384
7423
 
7385
7424
 
7386
7425
  }
@@ -7923,7 +7962,6 @@ var translate = {
7923
7962
  params = params + index + '=' + data[index];
7924
7963
  }
7925
7964
  }
7926
-
7927
7965
  if(url.indexOf('https://') == 0 || url.indexOf('http://') == 0){
7928
7966
  //采用的url绝对路径
7929
7967
  }else{
@@ -8302,13 +8340,12 @@ var translate = {
8302
8340
  }
8303
8341
  }
8304
8342
  //client.edge 判断 translate.service.edge可能会被精简translate.js定制时给直接干掉,所以提前加个判断
8305
- if(typeof(translate.service.edge) != 'undefined' && url.indexOf(translate.service.edge.api.auth) > -1){
8306
- ignoreUrl = true;
8307
- }
8308
- if(url.indexOf('.microsofttranslator.com/translate') > -1){
8309
- ignoreUrl = true;
8343
+ if(typeof(translate.service.edge) != 'undefined'){
8344
+ if(url.indexOf('edge.microsoft.com/translate/translatetext') > -1){
8345
+ ignoreUrl = true;
8346
+ }
8310
8347
  }
8311
-
8348
+
8312
8349
  if(ignoreUrl){
8313
8350
  //console.log('忽略:'+url);
8314
8351
  continue;
@@ -0,0 +1,145 @@
1
+ <template>
2
+ <div class="LanguageSelect ignore">
3
+ <!-- 使用作用域插槽,将组件内部的数据和方法传递给父组件 -->
4
+ <slot
5
+ :LanguageSelectLanguageList="LanguageSelectLanguageList"
6
+ :LanguageSelectOnChange="LanguageSelectOnChange"
7
+ :LanguageSelectRenderLabel="LanguageSelectRenderLabel"
8
+ >
9
+ <!-- 默认的n-select实现 -->
10
+ <n-select
11
+ v-model:value="language"
12
+ @update:value="LanguageSelectOnChange"
13
+ placeholder="Please select language"
14
+ :options="LanguageSelectLanguageList"
15
+ label-field="name"
16
+ value-field="id"
17
+ class="ignore"
18
+ :render-label="LanguageSelectRenderLabel"
19
+ />
20
+ </slot>
21
+ </div>
22
+ </template>
23
+
24
+ <script setup lang="ts">
25
+ import { ref, onMounted, defineProps } from 'vue';
26
+ import { h } from 'vue';
27
+ import { NSelect } from 'naive-ui';
28
+
29
+ // 定义语言选项类型
30
+ interface LanguageOption {
31
+ id: string;
32
+ name: string;
33
+ }
34
+
35
+
36
+ // 选中的语言ID(双向绑定值)
37
+ const language = ref<string | null>(null);
38
+
39
+ // 语言选项列表
40
+ const LanguageSelectLanguageList = ref<LanguageOption[]>([]);
41
+
42
+ // 处理语言选择变化
43
+ const LanguageSelectOnChange = (value: string) => {
44
+ language.value = value;
45
+ window.translate.selectLanguageTag.selectOnChange({
46
+ target: {
47
+ value: value
48
+ }
49
+ });
50
+ };
51
+
52
+ // 自定义渲染标签函数
53
+ const LanguageSelectRenderLabel = (option: LanguageOption) => {
54
+ const { name } = option;
55
+ return h('span', { class: 'ignore' }, name);
56
+ };
57
+
58
+ onMounted(() => {
59
+ // 保留原有的初始化逻辑
60
+ if (typeof (translate) == 'object' && typeof (translate.vue3) == 'object' && typeof (translate.vue3.isUse) == 'boolean' && translate.vue3.isUse == true) {
61
+ // 正常,需要的,需要加载多语言切换Select
62
+ } else {
63
+ // 不需要显示
64
+ return;
65
+ }
66
+
67
+ translate.time.log(translate.vue3.isUse);
68
+
69
+ // 重写渲染语言下拉列表出现时的函数
70
+ translate.selectLanguageTag.render = function () {
71
+ if (translate.selectLanguageTag.alreadyRender) {
72
+ return;
73
+ }
74
+ translate.selectLanguageTag.alreadyRender = true;
75
+
76
+ // 判断如果不显示select选择语言,直接就隐藏掉
77
+ if (!translate.selectLanguageTag.show) {
78
+ return;
79
+ }
80
+
81
+ // 从服务器加载支持的语言库
82
+ if (typeof (translate.request.api.language) == 'string' && translate.request.api.language.length > 0) {
83
+ // 从接口加载语种
84
+ translate.request.post(translate.request.api.language, {}, function (data) {
85
+ if (data.result == 0) {
86
+ console.log('load language list error : ' + data.info);
87
+ return;
88
+ }
89
+ translate.request.api.language = data.list; // 进行缓存
90
+ translate.selectLanguageTag.customUI(data.list);
91
+ }, null);
92
+ } else if (typeof (translate.request.api.language) == 'object') {
93
+ // 无网络环境下,自定义显示语种
94
+ translate.selectLanguageTag.customUI(translate.request.api.language);
95
+ }
96
+
97
+ // 显示切换语言
98
+ const TranslateJsSelectLanguages = document.getElementsByClassName('LanguageSelect');
99
+ for (let li = 0; li < TranslateJsSelectLanguages.length; li++) {
100
+ TranslateJsSelectLanguages[li].style.display = 'block';
101
+ }
102
+ }
103
+
104
+ // 处理语言列表数据
105
+ translate.selectLanguageTag.customUI = function (externalLanguageList) {
106
+ // 整理允许显示的语种
107
+ const allowLanguageList: LanguageOption[] = [];
108
+
109
+ // 判断 selectLanguageTag.languages 中允许使用哪些
110
+ if (translate.selectLanguageTag.languages.length > 0) {
111
+ // 设置了自定义显示的语言
112
+ // 都转小写判断
113
+ const langs_indexof = (',' + translate.selectLanguageTag.languages + ',').toLowerCase();
114
+
115
+ for (let i = 0; i < externalLanguageList.length; i++) {
116
+ if (langs_indexof.indexOf(',' + externalLanguageList[i].id.toLowerCase() + ',') < 0) {
117
+ // 没发现,那不显示这个语种,调出
118
+ continue;
119
+ }
120
+ allowLanguageList.push(externalLanguageList[i]);
121
+ }
122
+
123
+ } else {
124
+ // 显示所有
125
+ allowLanguageList.push(...externalLanguageList);
126
+ }
127
+ // 赋予带渲染到界面的语言列表数据
128
+ LanguageSelectLanguageList.value = allowLanguageList;
129
+
130
+ // 显示上一次切换后的语种
131
+ language.value = translate.language.getCurrent();
132
+ }
133
+
134
+ // 渲染语言下拉列表出现
135
+ translate.selectLanguageTag.refreshRender();
136
+ });
137
+ </script>
138
+
139
+ <style scoped>
140
+ /* 避免被遮挡无法操作,设置z-index较高 */
141
+ .LanguageSelect {
142
+ z-index: 2147483583;
143
+ display: none;
144
+ }
145
+ </style>
@@ -0,0 +1,126 @@
1
+ # Naive UI
2
+
3
+ ## 接入 vue3 方式使用 translate.js
4
+ http://translate.zvo.cn/4041.html
5
+
6
+ ## 页面上出现语言切换的Select下拉切换菜单
7
+
8
+ ### 效果
9
+ 见下图右上角的多语言切换
10
+ ![](./resource/preview.png)
11
+
12
+ ### 代码
13
+
14
+ 比如要在 index.vue 页面上显示切换语言的 select 下拉菜单,那么 index.vue 页面中,要进行的操作:
15
+ 先在 index.vue 中,加入一行,导入此UI框架的多语言切换Select
16
+ ````import LanguageSelect from 'i18n-jsautotranslate/naiveUI/LanguageSelect.vue';````
17
+ 然后在要显示select菜单的位置,直接加入
18
+ ````<LanguageSelect/>````
19
+ 即可。
20
+ 最后,可以使用css样式来进行自定义美化,比如要将这个语言切换放到页面的右上角:
21
+ ````
22
+ /* 多语言切换Select */
23
+ .LanguageSelect {
24
+ position: fixed;
25
+ top: 20px;
26
+ right: 80px;
27
+ }
28
+ ````
29
+ 注意,这个多语言切换的 select ,它的class 名字为 LanguageSelect
30
+
31
+ 完整的示例代码如下:
32
+ ````
33
+ <template>
34
+ <div class="login">
35
+ <h3 class="login-logo">
36
+ Logo
37
+ </h3>
38
+
39
+ <!-- 多语言切换的 Select 下拉选择 -->
40
+ <LanguageSelect/>
41
+ </div>
42
+ </template>
43
+
44
+ <script setup>
45
+ import { computed, ref } from 'vue'
46
+ import LanguageSelect from 'i18n-jsautotranslate/naiveUI/LanguageSelect.vue';
47
+ </script>
48
+
49
+ <style scoped>
50
+ .LanguageSelect {
51
+ position: fixed;
52
+ top: 20px;
53
+ right: 80px;
54
+ }
55
+ </style>
56
+ ````
57
+
58
+ ### 自定义切换语言的html代码
59
+ 修改
60
+ ````
61
+ <LanguageSelect/>
62
+ ````
63
+ 为:
64
+ ````
65
+ <script setup>
66
+ //获取该用户之前是否有切换过语言,获取其最后一次切换的是什么语种,详细参考: http://translate.zvo.cn/4074.html
67
+ const language = window.translate.language.getCurrent();
68
+ </script>
69
+ <LanguageSelect>
70
+ <template #default="{ LanguageSelectLanguageList, LanguageSelectOnChange, LanguageSelectRenderLabel }">
71
+ <n-select
72
+ v-model:value="language"
73
+ @update:value="LanguageSelectOnChange"
74
+ :options="LanguageSelectLanguageList"
75
+ label-field="name"
76
+ value-field="id"
77
+ class="ignore"
78
+ placeholder="请选择语言"
79
+ :render-label="LanguageSelectRenderLabel"
80
+ />
81
+ </template>
82
+ </LanguageSelect>
83
+ ````
84
+
85
+ 完整的示例代码如下:
86
+ ````
87
+ <template>
88
+ <div class="login">
89
+ <h3 class="login-logo">
90
+ Logo
91
+ </h3>
92
+
93
+ <!-- 多语言切换的 Select 下拉选择 -->
94
+ <LanguageSelect>
95
+ <template #default="{ LanguageSelectLanguageList, LanguageSelectOnChange, LanguageSelectRenderLabel }">
96
+ <n-select
97
+ v-model:value="language"
98
+ @update:value="LanguageSelectOnChange"
99
+ :options="LanguageSelectLanguageList"
100
+ label-field="name"
101
+ value-field="id"
102
+ class="ignore"
103
+ placeholder="请选择语言"
104
+ :render-label="LanguageSelectRenderLabel"
105
+ />
106
+ </template>
107
+ </LanguageSelect>
108
+ </div>
109
+ </template>
110
+
111
+ <script setup>
112
+ import { computed, ref } from 'vue'
113
+ import LanguageSelect from 'i18n-jsautotranslate/naiveUI/LanguageSelect.vue';
114
+
115
+ //获取该用户之前是否有切换过语言,获取其最后一次切换的是什么语种,详细参考: http://translate.zvo.cn/4074.html
116
+ const language = window.translate.language.getCurrent();
117
+ </script>
118
+
119
+ <style scoped>
120
+ .LanguageSelect {
121
+ position: fixed;
122
+ top: 20px;
123
+ right: 80px;
124
+ }
125
+ </style>
126
+ ````
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "i18n-jsautotranslate",
3
- "version": "3.18.72",
3
+ "version": "3.18.74",
4
4
  "description": "Two lines of js realize automatic html translation. No need to change the page, no language configuration file, no API key, SEO friendly!",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -14,8 +14,9 @@
14
14
  ],
15
15
  "files": [
16
16
  "index.js",
17
- "ArcoDesign/**",
18
- "vue/**"
17
+ "ArcoDesign/Vue3/LanguageSelect.vue",
18
+ "vue/**",
19
+ "naiveUI/LanguageSelect.vue"
19
20
  ],
20
21
  "homepage": "https://github.com/xnx3/translate#readme",
21
22
  "bugs": {
@@ -0,0 +1,45 @@
1
+ VUE3 中 使用 translate.j
2
+
3
+ ## [修改] package.json 文件
4
+ dependencies 中增加
5
+ ````
6
+ "i18n-jsautotranslate": "^3.18.73",
7
+ ````
8
+
9
+ ## [新增] translate.js (或ts) 文件
10
+ 比如,在你项目的 utils 目录(或其他什么目录都行)下,新增 translate.js (或.ts 只是后缀自己改一下就行) 文件。
11
+ 此文件源码: [Github](https://raw.githubusercontent.com/xnx3/translate/refs/heads/master/extend/vue/vue3/translate.ts) | [Gitee](https://gitee.com/mail_osc/translate/blob/master/extend/vue/vue3/translate.ts)
12
+ 这个文件也是你当前项目对翻译进行各种自定义微调所在。
13
+ 有什么要设置的,比如设置使用你私有部署的翻译服务器提供翻译服务、设置哪些文字不进行翻译、设置自定义术语 ……等等
14
+
15
+ ## [修改] main.js (或ts) 文件
16
+ 首先导入 上一步新建的文件,也就是新增一行 import :
17
+ ````
18
+ import {translateJsVueUseModel} from './utils/translate' // 多语言切换, 导入translate插件
19
+ ````
20
+
21
+ 然后在 ````const app = createApp(App)```` 跟 ````app.mount('#app')```` 的中间,新增 ````app.use(translateJsVueUseModel);````
22
+
23
+ 改好的 main.js 文件如下图所示:
24
+ ````
25
+ import { createApp } from 'vue'
26
+ import App from './App.vue'
27
+ import router from './router'
28
+ import {translateJsVueUseModel} from './utils/translate' // 多语言切换, 导入translate插件
29
+
30
+ const app = createApp(App);
31
+ app.use(router);
32
+ app.use(translateJsVueUseModel); //注释掉,即可停用多语言切换能力
33
+ app.mount('#app');
34
+ ````
35
+
36
+ ## 页面上出现语言切换的Select下拉切换菜单
37
+ 这里,我们针对部分UI框架,进行了适配,你可以直接快速使用
38
+ * ArcoDesign - [Github](https://github.com/xnx3/translate/tree/master/extend/ArcoDesign/Vue3) | [Gitee](https://gitee.com/mail_osc/translate/tree/master/extend/ArcoDesign/Vue3)
39
+ * naiveUI - [Github](https://github.com/xnx3/translate/tree/master/extend/naiveUI) | [Gitee](https://gitee.com/mail_osc/translate/tree/master/extend/naiveUI)
40
+
41
+ 如果你使用的别的UI框架,可以 [联系我](4030.html) 沟通,目前正在增加其他主流UI框架的,没准你要的就恰好有了,或者直接针对你当前使用的进行新适配。
42
+
43
+
44
+ ## 注意
45
+ 比如你vue页面中有个按钮,点击后触发切换为某种语言,正常使用是 `translate.changeLanguage('english');` 而在vue代码中如果提示 `translate 不存在` ,那么你触发时前面额外加个windows.即可 : `window.translate.changeLanguage('english');`