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
Ryan Wang 2024-04-25 11:43:10 +08:00 committed by GitHub
parent fbf2b06432
commit a644c40cfd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 37 additions and 28 deletions

View File

@ -5,14 +5,11 @@ import { useRouteQuery } from "@vueuse/router";
import SignupForm from "@/components/signup/SignupForm.vue";
import SocialAuthProviders from "@/components/login/SocialAuthProviders.vue";
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 LocaleChange from "@/components/common/LocaleChange.vue";
import { useAppTitle } from "@/composables/use-title";
const { globalInfo } = useGlobalInfoFetch();
const { t } = useI18n();
const SIGNUP_TYPE = "signup";
@ -32,14 +29,10 @@ function handleChangeType() {
const isLoginType = computed(() => type.value !== SIGNUP_TYPE);
useTitle(
computed(() => {
const siteTitle = globalInfo.value?.siteTitle || AppName;
const routeTitle = t(
`core.${type.value === SIGNUP_TYPE ? SIGNUP_TYPE : "login"}.title`
);
return [routeTitle, siteTitle].join(" - ");
})
useAppTitle(
computed(
() => `core.${type.value === SIGNUP_TYPE ? SIGNUP_TYPE : "login"}.title`
)
);
</script>
<template>

View File

@ -9,7 +9,7 @@
name="viewport"
/>
<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/svg+xml" />
<meta name="msapplication-TileColor" content="#da532c" />

View File

@ -1,32 +1,21 @@
<script lang="ts" setup>
import { RouterView, useRoute } from "vue-router";
import { computed, reactive, onMounted, inject } from "vue";
import { useTitle } from "@vueuse/core";
import { RouterView } from "vue-router";
import { computed, inject, onMounted, reactive } from "vue";
import { useFavicon } from "@vueuse/core";
import { useI18n } from "vue-i18n";
import {
useOverlayScrollbars,
type UseOverlayScrollbarsParams,
} from "overlayscrollbars-vue";
import type { FormKitConfig } from "@formkit/core";
import { i18n } from "@/locales";
import { AppName } from "@/constants/app";
import { useGlobalInfoStore } from "@/stores/global-info";
import { storeToRefs } from "pinia";
import { useAppTitle } from "@/composables/use-title";
const { t } = useI18n();
useAppTitle();
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
const defaultFavicon = "/console/favicon.ico";
const favicon = computed(() => {
@ -66,6 +55,7 @@ formkitConfig.locale = formkitLocales[i18n.global.locale.value] || "zh";
function setViewportProperty(doc: HTMLElement) {
let prevClientHeight: number;
const customVar = "--vh";
function handleResize() {
const clientHeight = doc.clientHeight;
if (clientHeight === prevClientHeight) return;
@ -74,9 +64,11 @@ function setViewportProperty(doc: HTMLElement) {
prevClientHeight = clientHeight;
});
}
handleResize();
return handleResize;
}
window.addEventListener(
"resize",
setViewportProperty(document.documentElement)

View File

@ -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(" - ");
})
);
}