gc_i18n 1.0.9 → 1.1.0
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.
- package/lib/gc_i18n.css +1 -1
- package/lib/gc_i18n.js +1801 -1669
- package/lib/gc_i18n.umd.cjs +16 -16
- package/package.json +2 -1
- package/packages/components/config.vue +237 -77
- package/packages/index.js +129 -61
- package/packages/libs/http.js +1 -1
- package/packages/libs/i18nUtils.ts +53 -0
- package/packages/libs/service.js +2 -2
- package/src/main.js +2 -1
- package/src/view/BOATNOTICE.vue +51 -6
- package/src/view/Home.vue +4 -2
- package/vite.config.js +1 -1
- package/packages/components/language.vue +0 -93
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export function extractTranslationKeys(component: any): string[] {
|
|
2
|
+
const keys: string[] = [];
|
|
3
|
+
// 优化后的正则表达式,兼容 $t 和 _ctx.$t 的情况
|
|
4
|
+
const regex = /(?:\$t|_ctx\.\$t)\s*\(\s*(['"])([^'"]+?)\1/gs;
|
|
5
|
+
|
|
6
|
+
// 解析组件选项中的模板
|
|
7
|
+
if (component.template) {
|
|
8
|
+
let match;
|
|
9
|
+
while ((match = regex.exec(component.template)) !== null) {
|
|
10
|
+
// 提取第二个捕获组的内容,即引号内的值
|
|
11
|
+
keys.push(match[2]);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// 解析组件选项中的渲染函数
|
|
16
|
+
if (component.render) {
|
|
17
|
+
const renderCode = component.render.toString();
|
|
18
|
+
let match;
|
|
19
|
+
while ((match = regex.exec(renderCode)) !== null) {
|
|
20
|
+
keys.push(match[2]);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// 解析组件的 setup 函数或 methods 中的 JS 代码
|
|
25
|
+
if (component.setup) {
|
|
26
|
+
const setupCode = component.setup.toString();
|
|
27
|
+
let match;
|
|
28
|
+
while ((match = regex.exec(setupCode)) !== null) {
|
|
29
|
+
keys.push(match[2]);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (component.methods) {
|
|
34
|
+
for (const methodName in component.methods) {
|
|
35
|
+
const methodCode = component.methods[methodName].toString();
|
|
36
|
+
let match;
|
|
37
|
+
while ((match = regex.exec(methodCode)) !== null) {
|
|
38
|
+
keys.push(match[2]);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// 递归处理子组件
|
|
44
|
+
if (component.components) {
|
|
45
|
+
for (const childComponentName in component.components) {
|
|
46
|
+
const childComponent = component.components[childComponentName];
|
|
47
|
+
keys.push(...extractTranslationKeys(childComponent));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// 合并同名的 key,利用 Set 去重
|
|
52
|
+
return [...new Set(keys)];
|
|
53
|
+
}
|
package/packages/libs/service.js
CHANGED
package/src/main.js
CHANGED
|
@@ -7,11 +7,12 @@ import zh from "view-ui-plus/dist/locale/zh-CN";
|
|
|
7
7
|
const i18n = new gc_i18n({
|
|
8
8
|
appCode: "TEST",
|
|
9
9
|
router,
|
|
10
|
+
token:
|
|
11
|
+
"eyJhbGciOiJIUzUxMiJ9.eyJkZXZpY2VUeXBlIjoiQ09NUFVURVIiLCJtYWluQXBwQ29kZSI6IlNTTyIsIm9yZ0NvZGUiOiJHUkVFTkNMT1VEIiwidWNTZXJ2ZXJVcmwiOiJodHRwczovL3Rlc3QuaWhvdGVsLmNuL3VjLXdlYi8iLCJhcHBDb2RlIjoiU1NPIiwidXNlclR5cGUiOiJOT1JNQUwiLCJsb2dpbkF0IjoxNzQ0MTA0OTQ5MDAwLCJwcmluY2lwYWxVc2VyQ29kZSI6IkhRTCIsImV4cCI6MzI1MDM2NTEyMDAsInVzZXJDb2RlIjoiSFFMIiwic3NvIjoiU1NPX1NFUlZFUiJ9.ra6-Yz0FEZdLObSuR1UsP8v2f3TXUWw0NDBKYUSrR4gbFtlrtgQcyp78LF3rLJMIaGn7A_YmqrzxP1pW4-ZGyA",
|
|
10
12
|
messages: {
|
|
11
13
|
"zh-CN": { ...zh, test: "合计{0}条" }
|
|
12
14
|
}
|
|
13
15
|
});
|
|
14
|
-
console.log("i18n", i18n);
|
|
15
16
|
|
|
16
17
|
const app = createApp(App).use(router).use(i18n);
|
|
17
18
|
|
package/src/view/BOATNOTICE.vue
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { useI18n } from "vue-i18n";
|
|
3
3
|
const { locale, changeLocale } = useI18n();
|
|
4
|
-
|
|
4
|
+
import { ref } from "vue";
|
|
5
5
|
defineProps({
|
|
6
6
|
msg: String
|
|
7
7
|
});
|
|
@@ -19,6 +19,7 @@ const langs = [
|
|
|
19
19
|
code: "zh-TW"
|
|
20
20
|
}
|
|
21
21
|
];
|
|
22
|
+
const TEST = ref($t("gbfb"));
|
|
22
23
|
const total = [100];
|
|
23
24
|
const change = (lang) => {
|
|
24
25
|
changeLocale(lang);
|
|
@@ -40,17 +41,61 @@ const change = (lang) => {
|
|
|
40
41
|
</div>
|
|
41
42
|
|
|
42
43
|
<div>
|
|
43
|
-
<div
|
|
44
|
-
<div>{{ $t("test", total) }}</div>
|
|
44
|
+
<div>有变量的xxx:</div>
|
|
45
|
+
<div>{{ $t("test", total, "找不到test") }}</div>
|
|
45
46
|
</div>
|
|
46
47
|
<div>
|
|
47
48
|
<div>不带前缀:</div>
|
|
48
|
-
<div>{{ $t("
|
|
49
|
+
<div>{{ $t("xwlywz7", "找不到") }}</div>
|
|
49
50
|
<!-- <div>{{ $t("中文{0}", [{ comment: "找不到" }]) }}</div> -->
|
|
50
51
|
</div>
|
|
51
52
|
<div>
|
|
52
|
-
<div
|
|
53
|
-
<div>{{ $t("
|
|
53
|
+
<div>测试:</div>
|
|
54
|
+
<div>{{ $t("4j3dy86", "找不到") }}</div>
|
|
55
|
+
</div>
|
|
56
|
+
<div>
|
|
57
|
+
<div>测试:</div>
|
|
58
|
+
<div>{{ $t("4j3dy81", "找不到") }}</div>
|
|
59
|
+
</div>
|
|
60
|
+
<div>
|
|
61
|
+
<div>测试:</div>
|
|
62
|
+
<div>{{ $t("4j3dy82", "找不到") }}</div>
|
|
63
|
+
</div>
|
|
64
|
+
<div>
|
|
65
|
+
<div>测试:</div>
|
|
66
|
+
<div>{{ $t("4j3dy83", "找不到") }}</div>
|
|
67
|
+
</div>
|
|
68
|
+
<div>
|
|
69
|
+
<div>测试:</div>
|
|
70
|
+
<div>{{ $t("4j3dy85", "找不到") }}</div>
|
|
71
|
+
</div>
|
|
72
|
+
<div>
|
|
73
|
+
<div>测试:</div>
|
|
74
|
+
<div>{{ $t("4j3dy84", "找不到") }}</div>
|
|
75
|
+
</div>
|
|
76
|
+
<div>
|
|
77
|
+
<div>测试:</div>
|
|
78
|
+
<div>{{ $t("4j3dy87", "找不到") }}</div>
|
|
79
|
+
</div>
|
|
80
|
+
<div>
|
|
81
|
+
<div>测试:</div>
|
|
82
|
+
<div>{{ $t("4j3dy88", "找不到") }}</div>
|
|
83
|
+
</div>
|
|
84
|
+
<div>
|
|
85
|
+
<div>测试:</div>
|
|
86
|
+
<div>{{ $t("4j3dy86", "找不到") }}</div>
|
|
87
|
+
</div>
|
|
88
|
+
<div>
|
|
89
|
+
<div>测试:</div>
|
|
90
|
+
<div>{{ $t("4j3dy86", "找不到") }}</div>
|
|
91
|
+
</div>
|
|
92
|
+
<div>
|
|
93
|
+
<div>测试:</div>
|
|
94
|
+
<div>{{ $t("4j3dy86", "找不到") }}</div>
|
|
95
|
+
</div>
|
|
96
|
+
<div>
|
|
97
|
+
<div>测试:</div>
|
|
98
|
+
<div>{{ $t("4j3dy86", "找不到") }}</div>
|
|
54
99
|
</div>
|
|
55
100
|
<Page
|
|
56
101
|
:total="40"
|
package/src/view/Home.vue
CHANGED
|
@@ -3,11 +3,13 @@ import { useI18n } from "vue-i18n";
|
|
|
3
3
|
const { locale, changeLocal } = useI18n();
|
|
4
4
|
|
|
5
5
|
const change = (lang) => {
|
|
6
|
-
|
|
6
|
+
locale.value = lang;
|
|
7
7
|
};
|
|
8
8
|
</script>
|
|
9
9
|
|
|
10
10
|
<template>
|
|
11
11
|
{{ locale }}
|
|
12
|
-
|
|
12
|
+
{{ $t("home", "主页", "lang") }}
|
|
13
|
+
<button @click="change('en')">en</button>
|
|
14
|
+
<button @click="change('zh')">zh</button>
|
|
13
15
|
</template>
|
package/vite.config.js
CHANGED
|
@@ -38,7 +38,7 @@ export default defineConfig({
|
|
|
38
38
|
},
|
|
39
39
|
outDir: "lib"
|
|
40
40
|
// outDir:
|
|
41
|
-
// "/Users/huqiliang/Documents/
|
|
41
|
+
// "/Users/huqiliang/Documents/github/auto-i18n-translation-plugins/example/vue3/node_modules/gc_i18n/lib"
|
|
42
42
|
// outDir:
|
|
43
43
|
// "/Users/huqiliang/Documents/lvyun/travel-ship-standard-front/node_modules/gc_i18n/lib"
|
|
44
44
|
},
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { getLanguages } from "../libs/service";
|
|
3
|
-
import store from "store2";
|
|
4
|
-
import _ from "lodash-es";
|
|
5
|
-
import { useI18n } from "vue-i18n";
|
|
6
|
-
|
|
7
|
-
export default {
|
|
8
|
-
setup() {
|
|
9
|
-
const { changeLocal, locale } = useI18n();
|
|
10
|
-
return {
|
|
11
|
-
changeLocal,
|
|
12
|
-
locale
|
|
13
|
-
};
|
|
14
|
-
},
|
|
15
|
-
name: "LangChange",
|
|
16
|
-
data() {
|
|
17
|
-
return {
|
|
18
|
-
languages: []
|
|
19
|
-
};
|
|
20
|
-
},
|
|
21
|
-
props: {
|
|
22
|
-
token: String,
|
|
23
|
-
simple: {
|
|
24
|
-
type: Boolean,
|
|
25
|
-
default: false
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
methods: {
|
|
29
|
-
toggle() {
|
|
30
|
-
const langToggle = _.find(
|
|
31
|
-
this.languages,
|
|
32
|
-
(item) => item.code !== this.locale
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
this.changeLocal(langToggle.code);
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
async mounted() {
|
|
39
|
-
this.language = store.get("I18N_LANGUAGE") || navigator.language;
|
|
40
|
-
const res = await getLanguages(this.token);
|
|
41
|
-
if (res && res.result === 0) {
|
|
42
|
-
this.languages = res.retVal;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
</script>
|
|
47
|
-
<template>
|
|
48
|
-
<div
|
|
49
|
-
class="gc_i18n_language"
|
|
50
|
-
v-if="languages && languages.length > 0"
|
|
51
|
-
>
|
|
52
|
-
<div v-if="languages.length === 1">
|
|
53
|
-
<span>{{ languages[0].name }}</span>
|
|
54
|
-
</div>
|
|
55
|
-
<div
|
|
56
|
-
v-else-if="languages.length === 2"
|
|
57
|
-
class="two"
|
|
58
|
-
>
|
|
59
|
-
<span
|
|
60
|
-
class="item"
|
|
61
|
-
v-for="item in languages"
|
|
62
|
-
@click="toggle"
|
|
63
|
-
:class="item.code == locale ? 'active' : 'hide'"
|
|
64
|
-
>{{ item.name }}</span
|
|
65
|
-
>
|
|
66
|
-
</div>
|
|
67
|
-
<Select
|
|
68
|
-
:modelValue="locale"
|
|
69
|
-
@on-change="changeLocal"
|
|
70
|
-
v-else
|
|
71
|
-
>
|
|
72
|
-
<Option
|
|
73
|
-
:value="item.code"
|
|
74
|
-
:label="item.name"
|
|
75
|
-
v-for="item in languages"
|
|
76
|
-
>{{ item.name }}</Option
|
|
77
|
-
>
|
|
78
|
-
</Select>
|
|
79
|
-
</div>
|
|
80
|
-
</template>
|
|
81
|
-
|
|
82
|
-
<style lang="less" scoped>
|
|
83
|
-
.gc_i18n_language {
|
|
84
|
-
.two {
|
|
85
|
-
.item {
|
|
86
|
-
cursor: pointer;
|
|
87
|
-
}
|
|
88
|
-
.hide {
|
|
89
|
-
display: none;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
</style>
|