refactor(i18n): ♻️ 加强基础国际化

This commit is contained in:
cshaptx4869 2024-03-07 23:51:35 +08:00
parent 2c2d638379
commit 26b75db243
10 changed files with 135 additions and 58 deletions

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 1024 1024"><path fill="currentColor" d="M224 448a32 32 0 0 0-32 32v384a32 32 0 0 0 32 32h576a32 32 0 0 0 32-32V480a32 32 0 0 0-32-32zm0-64h576a96 96 0 0 1 96 96v384a96 96 0 0 1-96 96H224a96 96 0 0 1-96-96V480a96 96 0 0 1 96-96"/><path fill="currentColor" d="M512 544a32 32 0 0 1 32 32v192a32 32 0 1 1-64 0V576a32 32 0 0 1 32-32m192-160v-64a192 192 0 1 0-384 0v64zM512 64a256 256 0 0 1 256 256v128H256V320A256 256 0 0 1 512 64"/></svg>

After

Width:  |  Height:  |  Size: 512 B

View File

@ -26,15 +26,8 @@ const type = computed(() => {
});
const linkProps = (to: string) => {
if (isExternalLink.value) {
return {
href: to,
target: "_blank",
rel: "noopener noreferrer",
};
}
return {
to: to,
};
return isExternalLink.value
? { href: to, target: "_blank", rel: "noopener noreferrer" }
: { to };
};
</script>

View File

@ -32,7 +32,7 @@ const pathCompile = (path: string) => {
return toPath(params);
};
const breadcrumbs = ref([] as Array<RouteLocationMatched>);
const breadcrumbs = ref<Array<RouteLocationMatched>>([]);
function getBreadcrumb() {
let matched = currentRoute.matched.filter(

View File

@ -6,13 +6,12 @@
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item
:disabled="appStore.language === 'zh-cn'"
command="zh-cn"
v-for="item in langOptions"
:key="item.value"
:disabled="appStore.language === item.value"
:command="item.value"
>
中文
</el-dropdown-item>
<el-dropdown-item :disabled="appStore.language === 'en'" command="en">
English
{{ item.label }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
@ -30,16 +29,18 @@ defineProps({
},
});
const langOptions = [
{ label: "中文", value: "zh-cn" },
{ label: "English", value: "en" },
];
const appStore = useAppStore();
const { locale } = useI18n();
const { locale, t } = useI18n();
function handleLanguageChange(lang: string) {
locale.value = lang;
appStore.changeLanguage(lang);
if (lang === "en") {
ElMessage.success("Switch Language Successful!");
} else {
ElMessage.success("切换语言成功!");
}
ElMessage.success(t("langSelect.message.success"));
}
</script>

View File

@ -20,15 +20,19 @@
<script setup lang="ts">
import { useAppStore } from "@/store/modules/app";
const sizeOptions = ref([
{ label: "默认", value: "default" },
{ label: "大型", value: "large" },
{ label: "小型", value: "small" },
]);
const { t } = useI18n();
const sizeOptions = computed(() => {
return [
{ label: t("sizeSelect.default"), value: "default" },
{ label: t("sizeSelect.large"), value: "large" },
{ label: t("sizeSelect.small"), value: "small" },
];
});
const appStore = useAppStore();
function handleSizeChange(size: string) {
appStore.changeSize(size);
ElMessage.success("切换布局大小成功");
ElMessage.success(t("sizeSelect.message.success"));
}
</script>

View File

@ -10,6 +10,18 @@ export default {
password: "Password",
login: "Login",
captchaCode: "Verify Code",
message: {
username: {
required: "Please enter Username",
},
password: {
required: "Please enter Password",
min: "The password can not be less than 6 digits",
},
captchaCode: {
required: "Please enter Verify Code",
},
},
},
// 导航栏国际化
navbar: {
@ -18,4 +30,29 @@ export default {
document: "Document",
gitee: "Gitee",
},
sizeSelect: {
tooltip: "Layout Size",
default: "Default",
large: "Large",
small: "Small",
message: {
success: "Switch Layout Size Successful!",
},
},
langSelect: {
message: {
success: "Switch Language Successful!",
},
},
settings: {
project: "Project Settings",
theme: "Theme",
interface: "Interface",
navigation: "Navigation",
themeColor: "Theme Color",
tagsView: "Tags View",
fixedHeader: "Fixed Header",
sidebarLogo: "Sidebar Logo",
watermark: "Watermark",
},
};

View File

@ -10,12 +10,49 @@ export default {
password: "密码",
login: "登 录",
captchaCode: "验证码",
message: {
username: {
required: "请输入用户名",
},
password: {
required: "请输入密码",
min: "密码不能少于6位",
},
captchaCode: {
required: "请输入验证码",
},
},
},
// 导航栏国际化
navbar: {
dashboard: "首页",
logout: "注销",
logout: "注销登出",
document: "项目文档",
gitee: "码云",
gitee: "项目地址",
},
sizeSelect: {
tooltip: "布局大小",
default: "默认",
large: "大型",
small: "小型",
message: {
success: "切换布局大小成功!",
},
},
langSelect: {
message: {
success: "切换语言成功!",
},
},
settings: {
project: "项目配置",
theme: "主题设置",
interface: "界面设置",
navigation: "导航设置",
themeColor: "主题颜色",
tagsView: "开启 Tags-View",
fixedHeader: "固定 Header",
sidebarLogo: "侧边栏 Logo",
watermark: "开启水印",
},
};

View File

@ -9,7 +9,11 @@
</div>
<!-- 布局大小 -->
<el-tooltip content="布局大小" effect="dark" placement="bottom">
<el-tooltip
:content="$t('sizeSelect.tooltip')"
effect="dark"
placement="bottom"
>
<size-select class="setting-item" />
</el-tooltip>
@ -32,13 +36,13 @@
target="_blank"
href="https://gitee.com/youlaiorg/vue3-element-admin"
>
<el-dropdown-item>项目地址</el-dropdown-item>
<el-dropdown-item>{{ $t("navbar.gitee") }}</el-dropdown-item>
</a>
<a target="_blank" href="https://juejin.cn/post/7228990409909108793">
<el-dropdown-item>项目文档</el-dropdown-item>
<el-dropdown-item>{{ $t("navbar.document") }}</el-dropdown-item>
</a>
<el-dropdown-item divided @click="logout">
注销登出
{{ $t("navbar.logout") }}
</el-dropdown-item>
</el-dropdown-menu>
</template>

View File

@ -1,6 +1,10 @@
<template>
<el-drawer v-model="settingsVisible" size="300" title="项目配置">
<el-divider>主题设置</el-divider>
<el-drawer
v-model="settingsVisible"
size="300"
:title="$t('settings.project')"
>
<el-divider>{{ $t("settings.theme") }}</el-divider>
<div class="flex-center">
<el-switch
@ -11,10 +15,10 @@
/>
</div>
<el-divider>界面设置</el-divider>
<el-divider>{{ $t("settings.interface") }}</el-divider>
<div class="settings-option">
<el-text>主题颜色</el-text>
<span class="text-xs">{{ $t("settings.themeColor") }}</span>
<ThemeColorPicker
v-model="settingsStore.themeColor"
@update:model-value="changeThemeColor"
@ -22,26 +26,26 @@
</div>
<div class="settings-option">
<el-text>开启 Tags-View</el-text>
<span class="text-xs">{{ $t("settings.tagsView") }}</span>
<el-switch v-model="settingsStore.tagsView" />
</div>
<div class="settings-option">
<el-text>固定 Header</el-text>
<span class="text-xs">{{ $t("settings.fixedHeader") }}</span>
<el-switch v-model="settingsStore.fixedHeader" />
</div>
<div class="settings-option">
<el-text>侧边栏 Logo</el-text>
<span class="text-xs">{{ $t("settings.sidebarLogo") }}</span>
<el-switch v-model="settingsStore.sidebarLogo" />
</div>
<div class="settings-option">
<el-text>开启水印</el-text>
<span class="text-xs">{{ $t("settings.watermark") }}</span>
<el-switch v-model="settingsStore.watermarkEnabled" />
</div>
<el-divider>导航设置</el-divider>
<el-divider>{{ $t("settings.navigation") }}</el-divider>
<LayoutSelect
v-model="settingsStore.layout"

View File

@ -47,7 +47,7 @@
>
<el-form-item prop="password">
<div class="flex-y-center w-full">
<el-icon class="mx-2"><Lock /></el-icon>
<svg-icon icon-class="lock" class="mx-2" />
<el-input
v-model="loginData.password"
:placeholder="$t('login.password')"
@ -114,7 +114,7 @@
</template>
<script setup lang="ts">
import { useSettingsStore, useUserStore, useAppStore } from "@/store";
import { useSettingsStore, useUserStore } from "@/store";
import { getCaptchaApi } from "@/api/auth";
import { LoginData } from "@/api/auth/types";
import { Sunny, Moon } from "@element-plus/icons-vue";
@ -126,7 +126,6 @@ import { ThemeEnum } from "@/enums/ThemeEnum";
// Stores
const userStore = useUserStore();
const settingsStore = useSettingsStore();
const appStore = useAppStore();
// Internationalization
const { t } = useI18n();
@ -146,34 +145,31 @@ const loginData = ref<LoginData>({
});
const loginRules = computed(() => {
const prefix = appStore.language === "en" ? "Please enter " : "请输入";
return {
username: [
{
required: true,
trigger: "blur",
message: `${prefix}${t("login.username")}`,
message: t("login.message.username.required"),
},
],
password: [
{
required: true,
trigger: "blur",
validator: (rule: any, value: any, callback: any) => {
if (value.length < 6) {
callback(new Error("The password can not be less than 6 digits"));
} else {
callback();
}
message: t("login.message.password.required"),
},
message: `${prefix}${t("login.password")}`,
{
min: 6,
message: t("login.message.password.min"),
trigger: "blur",
},
],
captchaCode: [
{
required: true,
trigger: "blur",
message: `${prefix}${t("login.captchaCode")}`,
message: t("login.message.captchaCode.required"),
},
],
};