Merge pull request #52 from cshaptx4869/patch-24
refactor(i18n): ♻️ 加强基础国际化
This commit is contained in:
commit
5381a620e4
|
|
@ -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 |
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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: "开启水印",
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue