mirror of https://github.com/halo-dev/halo
refactor: implementation of browser tab title (#5794)
#### What type of PR is this? /area ui /kind improvement /milestone 2.15.x #### What this PR does / why we need it: 重构 Console 和 UC 的浏览器标题切换。 1. 将代码逻辑封装为统一的 Hook。 2. 移除 index.html 默认的标题,防止加载中的时候显示不正确。 #### Which issue(s) this PR fixes: Fixes https://github.com/halo-dev/halo/issues/5752 #### Special notes for your reviewer: 测试各个页面的标题显示正常即可。 #### Does this PR introduce a user-facing change? ```release-note 重构 Console 和 UC 的浏览器标题切换。 ```pull/5796/head^2
parent
fbf2b06432
commit
a644c40cfd
|
@ -5,14 +5,11 @@ import { useRouteQuery } from "@vueuse/router";
|
||||||
import SignupForm from "@/components/signup/SignupForm.vue";
|
import SignupForm from "@/components/signup/SignupForm.vue";
|
||||||
import SocialAuthProviders from "@/components/login/SocialAuthProviders.vue";
|
import SocialAuthProviders from "@/components/login/SocialAuthProviders.vue";
|
||||||
import { useGlobalInfoFetch } from "@console/composables/use-global-info";
|
import { useGlobalInfoFetch } from "@console/composables/use-global-info";
|
||||||
import { useTitle } from "@vueuse/core";
|
|
||||||
import { useI18n } from "vue-i18n";
|
|
||||||
import { AppName } from "@/constants/app";
|
|
||||||
import MdiKeyboardBackspace from "~icons/mdi/keyboard-backspace";
|
import MdiKeyboardBackspace from "~icons/mdi/keyboard-backspace";
|
||||||
import LocaleChange from "@/components/common/LocaleChange.vue";
|
import LocaleChange from "@/components/common/LocaleChange.vue";
|
||||||
|
import { useAppTitle } from "@/composables/use-title";
|
||||||
|
|
||||||
const { globalInfo } = useGlobalInfoFetch();
|
const { globalInfo } = useGlobalInfoFetch();
|
||||||
const { t } = useI18n();
|
|
||||||
|
|
||||||
const SIGNUP_TYPE = "signup";
|
const SIGNUP_TYPE = "signup";
|
||||||
|
|
||||||
|
@ -32,14 +29,10 @@ function handleChangeType() {
|
||||||
|
|
||||||
const isLoginType = computed(() => type.value !== SIGNUP_TYPE);
|
const isLoginType = computed(() => type.value !== SIGNUP_TYPE);
|
||||||
|
|
||||||
useTitle(
|
useAppTitle(
|
||||||
computed(() => {
|
computed(
|
||||||
const siteTitle = globalInfo.value?.siteTitle || AppName;
|
() => `core.${type.value === SIGNUP_TYPE ? SIGNUP_TYPE : "login"}.title`
|
||||||
const routeTitle = t(
|
)
|
||||||
`core.${type.value === SIGNUP_TYPE ? SIGNUP_TYPE : "login"}.title`
|
|
||||||
);
|
|
||||||
return [routeTitle, siteTitle].join(" - ");
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
name="viewport"
|
name="viewport"
|
||||||
/>
|
/>
|
||||||
<meta content="noindex,nofollow" name="robots" />
|
<meta content="noindex,nofollow" name="robots" />
|
||||||
<title>Halo</title>
|
<title></title>
|
||||||
<link rel="icon" href="/favicon.ico" type="image/png" />
|
<link rel="icon" href="/favicon.ico" type="image/png" />
|
||||||
<link rel="icon" href="/favicon.ico" type="image/svg+xml" />
|
<link rel="icon" href="/favicon.ico" type="image/svg+xml" />
|
||||||
<meta name="msapplication-TileColor" content="#da532c" />
|
<meta name="msapplication-TileColor" content="#da532c" />
|
||||||
|
|
|
@ -1,32 +1,21 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { RouterView, useRoute } from "vue-router";
|
import { RouterView } from "vue-router";
|
||||||
import { computed, reactive, onMounted, inject } from "vue";
|
import { computed, inject, onMounted, reactive } from "vue";
|
||||||
import { useTitle } from "@vueuse/core";
|
|
||||||
import { useFavicon } from "@vueuse/core";
|
import { useFavicon } from "@vueuse/core";
|
||||||
import { useI18n } from "vue-i18n";
|
|
||||||
import {
|
import {
|
||||||
useOverlayScrollbars,
|
useOverlayScrollbars,
|
||||||
type UseOverlayScrollbarsParams,
|
type UseOverlayScrollbarsParams,
|
||||||
} from "overlayscrollbars-vue";
|
} from "overlayscrollbars-vue";
|
||||||
import type { FormKitConfig } from "@formkit/core";
|
import type { FormKitConfig } from "@formkit/core";
|
||||||
import { i18n } from "@/locales";
|
import { i18n } from "@/locales";
|
||||||
import { AppName } from "@/constants/app";
|
|
||||||
import { useGlobalInfoStore } from "@/stores/global-info";
|
import { useGlobalInfoStore } from "@/stores/global-info";
|
||||||
import { storeToRefs } from "pinia";
|
import { storeToRefs } from "pinia";
|
||||||
|
import { useAppTitle } from "@/composables/use-title";
|
||||||
|
|
||||||
const { t } = useI18n();
|
useAppTitle();
|
||||||
|
|
||||||
const { globalInfo } = storeToRefs(useGlobalInfoStore());
|
const { globalInfo } = storeToRefs(useGlobalInfoStore());
|
||||||
|
|
||||||
const route = useRoute();
|
|
||||||
useTitle(
|
|
||||||
computed(() => {
|
|
||||||
const { title: routeTitle } = route.meta;
|
|
||||||
const siteTitle = globalInfo.value?.siteTitle || AppName;
|
|
||||||
return [t(routeTitle || ""), siteTitle].filter(Boolean).join(" - ");
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// Favicon
|
// Favicon
|
||||||
const defaultFavicon = "/console/favicon.ico";
|
const defaultFavicon = "/console/favicon.ico";
|
||||||
const favicon = computed(() => {
|
const favicon = computed(() => {
|
||||||
|
@ -66,6 +55,7 @@ formkitConfig.locale = formkitLocales[i18n.global.locale.value] || "zh";
|
||||||
function setViewportProperty(doc: HTMLElement) {
|
function setViewportProperty(doc: HTMLElement) {
|
||||||
let prevClientHeight: number;
|
let prevClientHeight: number;
|
||||||
const customVar = "--vh";
|
const customVar = "--vh";
|
||||||
|
|
||||||
function handleResize() {
|
function handleResize() {
|
||||||
const clientHeight = doc.clientHeight;
|
const clientHeight = doc.clientHeight;
|
||||||
if (clientHeight === prevClientHeight) return;
|
if (clientHeight === prevClientHeight) return;
|
||||||
|
@ -74,9 +64,11 @@ function setViewportProperty(doc: HTMLElement) {
|
||||||
prevClientHeight = clientHeight;
|
prevClientHeight = clientHeight;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleResize();
|
handleResize();
|
||||||
return handleResize;
|
return handleResize;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener(
|
window.addEventListener(
|
||||||
"resize",
|
"resize",
|
||||||
setViewportProperty(document.documentElement)
|
setViewportProperty(document.documentElement)
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { storeToRefs } from "pinia";
|
||||||
|
import { useGlobalInfoStore } from "@/stores/global-info";
|
||||||
|
import { useRoute } from "vue-router";
|
||||||
|
import { useTitle } from "@vueuse/core";
|
||||||
|
import { computed, type Ref } from "vue";
|
||||||
|
import { AppName } from "@/constants/app";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
|
||||||
|
export function useAppTitle(baseTitle?: Ref<string>) {
|
||||||
|
const { globalInfo } = storeToRefs(useGlobalInfoStore());
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
const route = useRoute();
|
||||||
|
|
||||||
|
useTitle(
|
||||||
|
computed(() => {
|
||||||
|
const { title: routeTitle } = route.meta;
|
||||||
|
const siteTitle = globalInfo.value?.siteTitle || AppName;
|
||||||
|
return [t(baseTitle?.value || routeTitle || ""), siteTitle]
|
||||||
|
.filter(Boolean)
|
||||||
|
.join(" - ");
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in New Issue