feat: optimize header and footer
This commit is contained in:
4
components.d.ts
vendored
4
components.d.ts
vendored
@@ -40,6 +40,8 @@ declare module 'vue' {
|
|||||||
ElButton: typeof import('element-plus/es')['ElButton']
|
ElButton: typeof import('element-plus/es')['ElButton']
|
||||||
FooterBar: typeof import('./src/components/layout/FooterBar.vue')['default']
|
FooterBar: typeof import('./src/components/layout/FooterBar.vue')['default']
|
||||||
FooterBarV2: typeof import('./src/components/layout/FooterBarV2.vue')['default']
|
FooterBarV2: typeof import('./src/components/layout/FooterBarV2.vue')['default']
|
||||||
|
FooterBarV2Placeholder: typeof import('./src/components/layout/FooterBarV2Placeholder.vue')['default']
|
||||||
|
FooterBarV2Space: typeof import('./src/components/layout/FooterBarV2Space.vue')['default']
|
||||||
LogoIcon: typeof import('./src/components/icon/LogoIcon.vue')['default']
|
LogoIcon: typeof import('./src/components/icon/LogoIcon.vue')['default']
|
||||||
NativeSelect: typeof import('./src/components/ui/native-select/NativeSelect.vue')['default']
|
NativeSelect: typeof import('./src/components/ui/native-select/NativeSelect.vue')['default']
|
||||||
NativeSelectOptGroup: typeof import('./src/components/ui/native-select/NativeSelectOptGroup.vue')['default']
|
NativeSelectOptGroup: typeof import('./src/components/ui/native-select/NativeSelectOptGroup.vue')['default']
|
||||||
@@ -86,6 +88,8 @@ declare global {
|
|||||||
const ElButton: typeof import('element-plus/es')['ElButton']
|
const ElButton: typeof import('element-plus/es')['ElButton']
|
||||||
const FooterBar: typeof import('./src/components/layout/FooterBar.vue')['default']
|
const FooterBar: typeof import('./src/components/layout/FooterBar.vue')['default']
|
||||||
const FooterBarV2: typeof import('./src/components/layout/FooterBarV2.vue')['default']
|
const FooterBarV2: typeof import('./src/components/layout/FooterBarV2.vue')['default']
|
||||||
|
const FooterBarV2Placeholder: typeof import('./src/components/layout/FooterBarV2Placeholder.vue')['default']
|
||||||
|
const FooterBarV2Space: typeof import('./src/components/layout/FooterBarV2Space.vue')['default']
|
||||||
const LogoIcon: typeof import('./src/components/icon/LogoIcon.vue')['default']
|
const LogoIcon: typeof import('./src/components/icon/LogoIcon.vue')['default']
|
||||||
const NativeSelect: typeof import('./src/components/ui/native-select/NativeSelect.vue')['default']
|
const NativeSelect: typeof import('./src/components/ui/native-select/NativeSelect.vue')['default']
|
||||||
const NativeSelectOptGroup: typeof import('./src/components/ui/native-select/NativeSelectOptGroup.vue')['default']
|
const NativeSelectOptGroup: typeof import('./src/components/ui/native-select/NativeSelectOptGroup.vue')['default']
|
||||||
|
|||||||
13
docs/cli-feature/scroll.md
Normal file
13
docs/cli-feature/scroll.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# 滚动
|
||||||
|
|
||||||
|
## 平滑滚动
|
||||||
|
|
||||||
|
Hucky 选择了 [Lenis](https://lenis.darkroom.engineering/) 为项目提供平滑滚动,您可以在 `App.vue` 中控制平滑滚动的开关。
|
||||||
|
|
||||||
|
## 滚动失效
|
||||||
|
|
||||||
|
如果您遇到了滚动失效的情况,这是因为 Lenis 和普通滚动冲突,您可以通过添加 `data-lenis-prevent` 属性来防止 lenis 平滑滚动。例如:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div data-lenis-prevent></div>
|
||||||
|
```
|
||||||
@@ -4,7 +4,11 @@ import { useLanguageStore } from "./stores/LanguageStore";
|
|||||||
import Lenis from "lenis";
|
import Lenis from "lenis";
|
||||||
|
|
||||||
// 开启 lenis 平滑滚动
|
// 开启 lenis 平滑滚动
|
||||||
const lenis = new Lenis();
|
const lenis = new Lenis({
|
||||||
|
// 通过添加 data-lenis-prevent 属性来防止 lenis 平滑滚动
|
||||||
|
prevent: (node) =>
|
||||||
|
node.tagName === "SELECT" || node.hasAttribute("data-lenis-prevent"),
|
||||||
|
});
|
||||||
|
|
||||||
function raf(time) {
|
function raf(time) {
|
||||||
lenis.raf(time);
|
lenis.raf(time);
|
||||||
|
|||||||
@@ -33,13 +33,10 @@ const onClickChangeLocal = (newLanguage: string) => {
|
|||||||
d="M12 21a9 9 0 1 0 0-18m0 18a9 9 0 1 1 0-18m0 18c2.761 0 3.941-5.163 3.941-9S14.761 3 12 3m0 18c-2.761 0-3.941-5.163-3.941-9S9.239 3 12 3M3.5 9h17m-17 6h17"
|
d="M12 21a9 9 0 1 0 0-18m0 18a9 9 0 1 1 0-18m0 18c2.761 0 3.941-5.163 3.941-9S14.761 3 12 3m0 18c-2.761 0-3.941-5.163-3.941-9S9.239 3 12 3M3.5 9h17m-17 6h17"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
<svg
|
<span class="text-base-content/70">{{ t("nav.locale") }}</span>
|
||||||
class="mt-px hidden size-2 fill-current opacity-60 sm:inline-block"
|
<span
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
class="icon-[material-symbols--keyboard-arrow-down-rounded] text-lg text-base-content/70"
|
||||||
viewBox="0 0 2048 2048"
|
/>
|
||||||
>
|
|
||||||
<path d="M1799 349l242 241-1017 1017L7 590l242-241 775 775 775-775z" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
|
|||||||
@@ -1,6 +1,17 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useGlobalThemeHook } from "@/hooks/globalThemeHook";
|
import { useGlobalThemeHook } from "@/hooks/globalThemeHook";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
|
import Lenis from "lenis";
|
||||||
|
|
||||||
|
// 开启 lenis 平滑滚动
|
||||||
|
const lenis = new Lenis();
|
||||||
|
|
||||||
|
function raf(time) {
|
||||||
|
lenis.raf(time);
|
||||||
|
requestAnimationFrame(raf);
|
||||||
|
}
|
||||||
|
|
||||||
|
requestAnimationFrame(raf);
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
@@ -20,17 +31,13 @@ const { changeGlobalTheme, curGlobalTheme, optionalThemes } =
|
|||||||
<div class="bg-secondary size-1 rounded-full" />
|
<div class="bg-secondary size-1 rounded-full" />
|
||||||
<div class="bg-accent size-1 rounded-full" />
|
<div class="bg-accent size-1 rounded-full" />
|
||||||
</div>
|
</div>
|
||||||
<svg
|
<span class="text-base-content/70">{{ t("nav.theme") }}</span>
|
||||||
class="mt-px hidden size-2 fill-current opacity-60 sm:inline-block"
|
<span
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
class="icon-[material-symbols--keyboard-arrow-down-rounded] text-lg text-base-content/70"
|
||||||
viewBox="0 0 2048 2048"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M1799 349l242 241-1017 1017L7 590l242-241 775 775 775-775z"
|
|
||||||
/>
|
/>
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
<ul
|
<ul
|
||||||
|
data-lenis-prevent
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
class="dropdown-content bg-base-300 rounded-box z-1 w-52 p-2 shadow-2xl max-h-84 overflow-auto mt-6"
|
class="dropdown-content bg-base-300 rounded-box z-1 w-52 p-2 shadow-2xl max-h-84 overflow-auto mt-6"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -25,15 +25,16 @@ const handleLogout = () => {
|
|||||||
<div
|
<div
|
||||||
v-if="!userStore.checkUserLogin()"
|
v-if="!userStore.checkUserLogin()"
|
||||||
role="button"
|
role="button"
|
||||||
class="btn btn-circle btn-sm btn-ghost px-3 w-16"
|
class="btn btn-sm btn-primary px-3"
|
||||||
@click="
|
@click="
|
||||||
renderAuthDialog('login');
|
renderAuthDialog('login');
|
||||||
closeDropdown();
|
closeDropdown();
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<span class="text-sm text-base-content/70">
|
<span>
|
||||||
{{ $t("nav.login") }}
|
{{ $t("nav.login") }}
|
||||||
</span>
|
</span>
|
||||||
|
<span class="icon-[material-symbols--login-rounded] text-sm" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
|
|||||||
@@ -14,25 +14,6 @@
|
|||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
>
|
>
|
||||||
<defs id="defs1" />
|
<defs id="defs1" />
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview1"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#000000"
|
|
||||||
borderopacity="0.25"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:zoom="2.6914062"
|
|
||||||
inkscape:cx="127.81422"
|
|
||||||
inkscape:cy="128"
|
|
||||||
inkscape:window-width="1600"
|
|
||||||
inkscape:window-height="928"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="g1"
|
|
||||||
/>
|
|
||||||
<g inkscape:groupmode="layer" inkscape:label="Image" id="g1">
|
<g inkscape:groupmode="layer" inkscape:label="Image" id="g1">
|
||||||
<path
|
<path
|
||||||
style="fill: #ff2842; stroke: none"
|
style="fill: #ff2842; stroke: none"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import RedBookIcon from "../icon/RedBookIcon.vue";
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<footer
|
<footer
|
||||||
class="fixed bottom-0 left-0 w-full z-[-1] pt-16 pb-10 px-6 md:px-12 lg:px-20 text-sm font-[LXGW] h-102"
|
class="fixed bottom-0 left-0 w-full z-1 pt-16 pb-10 px-6 md:px-12 lg:px-20 text-sm font-[LXGW] lg:h-102 md:h-122 h-154"
|
||||||
>
|
>
|
||||||
<!-- Background overlay -->
|
<!-- Background overlay -->
|
||||||
<div
|
<div
|
||||||
@@ -106,8 +106,8 @@ import RedBookIcon from "../icon/RedBookIcon.vue";
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Bottom legal line -->
|
<!-- Bottom legal line -->
|
||||||
<div class="mt-8 text-xs text-gray-500 text-center md:text-left">
|
<div class="mt-8 text-xs text-gray-500 text-left">
|
||||||
<div class="max-w-7xl mx-auto px-6 md:px-0">
|
<div class="max-w-7xl mx-auto">
|
||||||
Copyright © 2026 sunway.icu | 备案号:浙ICP备2023010223号 |
|
Copyright © 2026 sunway.icu | 备案号:浙ICP备2023010223号 |
|
||||||
增值电信业务经营许可证:浙B2-20110004
|
增值电信业务经营许可证:浙B2-20110004
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { throttle } from "radash";
|
|||||||
import { AnimatePresence, motion } from "motion-v";
|
import { AnimatePresence, motion } from "motion-v";
|
||||||
import { navigateTo } from "@/utils/navigator";
|
import { navigateTo } from "@/utils/navigator";
|
||||||
import UserAuthNavButton from "../button/UserAuthNavButton.vue";
|
import UserAuthNavButton from "../button/UserAuthNavButton.vue";
|
||||||
import LogoIcon from "../icon/LogoIcon.vue";
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
@@ -29,6 +28,25 @@ const navPageByResetScroll = (path: string) => {
|
|||||||
window.scrollTo({ top: 0, behavior: "smooth" });
|
window.scrollTo({ top: 0, behavior: "smooth" });
|
||||||
navigateTo(path);
|
navigateTo(path);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const menuItems = ref([
|
||||||
|
{
|
||||||
|
path: "/",
|
||||||
|
label: "nav.home",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/about",
|
||||||
|
label: "nav.about",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/demo",
|
||||||
|
label: "nav.demo",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/join",
|
||||||
|
label: "nav.join",
|
||||||
|
},
|
||||||
|
]);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -47,50 +65,29 @@ const navPageByResetScroll = (path: string) => {
|
|||||||
<div class="navbar-start">
|
<div class="navbar-start">
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<div tabindex="0" role="button" class="btn btn-ghost lg:hidden">
|
<div tabindex="0" role="button" class="btn btn-ghost lg:hidden">
|
||||||
<svg
|
<span class="icon-[material-symbols--menu-rounded] text-2xl" />
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
class="h-5 w-5"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke="currentColor"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
stroke-width="2"
|
|
||||||
d="M4 6h16M4 12h8m-8 6h16"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
<ul
|
<ul
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
class="menu dropdown-content bg-base-100 rounded-box z-1 mt-5 w-52 p-2 shadow"
|
class="menu dropdown-content bg-base-100 rounded-box z-1 mt-5 w-48 p-2 shadow"
|
||||||
>
|
>
|
||||||
<li>
|
<li v-for="item in menuItems" :key="item.path">
|
||||||
<a @click="navPageByResetScroll('/')">{{ t("nav.home") }}</a>
|
<a @click="navPageByResetScroll(item.path)">{{
|
||||||
</li>
|
t(item.label)
|
||||||
<li>
|
|
||||||
<a @click="navPageByResetScroll('/about')">{{
|
|
||||||
t("nav.about")
|
|
||||||
}}</a>
|
}}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<a class="btn btn-ghost text-xl">Hucky</a>
|
<a class="btn btn-ghost text-xl">Hucky</a>
|
||||||
</div>
|
<ul class="menu menu-horizontal pl-6 hidden lg:flex gap-3">
|
||||||
<div class="navbar-center hidden lg:flex">
|
<li v-for="item in menuItems" :key="item.path">
|
||||||
<ul class="menu menu-horizontal px-1">
|
<a @click="navPageByResetScroll(item.path)">{{
|
||||||
<li>
|
t(item.label)
|
||||||
<a @click="navPageByResetScroll('/')">{{ t("nav.home") }}</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a @click="navPageByResetScroll('/about')">{{
|
|
||||||
t("nav.about")
|
|
||||||
}}</a>
|
}}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-end">
|
<div class="navbar-end gap-2">
|
||||||
<ChangeThemeDropdownButton />
|
<ChangeThemeDropdownButton />
|
||||||
<ChangeLanguageDropdownButton />
|
<ChangeLanguageDropdownButton />
|
||||||
<UserAuthNavButton />
|
<UserAuthNavButton />
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ export const en_USMessages: messagesInterface = {
|
|||||||
nav: {
|
nav: {
|
||||||
home: "Home",
|
home: "Home",
|
||||||
about: "About",
|
about: "About",
|
||||||
|
demo: "Demo",
|
||||||
|
join: "Join",
|
||||||
theme: "Theme",
|
theme: "Theme",
|
||||||
locale: "Locale",
|
locale: "Locale",
|
||||||
login: "Login",
|
login: "Login",
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ export interface messagesInterface {
|
|||||||
nav: {
|
nav: {
|
||||||
home: string;
|
home: string;
|
||||||
about: string;
|
about: string;
|
||||||
|
demo: string;
|
||||||
|
join: string;
|
||||||
theme: string;
|
theme: string;
|
||||||
locale: string;
|
locale: string;
|
||||||
login: string;
|
login: string;
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ export const zh_CNMessages: messagesInterface = {
|
|||||||
nav: {
|
nav: {
|
||||||
home: "首页",
|
home: "首页",
|
||||||
about: "关于",
|
about: "关于",
|
||||||
|
demo: "演示",
|
||||||
|
join: "加入",
|
||||||
theme: "主题",
|
theme: "主题",
|
||||||
locale: "语言",
|
locale: "语言",
|
||||||
login: "登录",
|
login: "登录",
|
||||||
|
|||||||
20
src/pages/demo.vue
Normal file
20
src/pages/demo.vue
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import NavBar from "@/components/menu/NavBar.vue";
|
||||||
|
import FooterBarV2 from "@/components/layout/FooterBarV2.vue";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="lg:pb-102 md:pb-122 pb-154">
|
||||||
|
<!-- 这里开 relative 形成 stack context -->
|
||||||
|
<div class="bg-base-200 relative z-2">
|
||||||
|
<div class="h-screen flex flex-col">
|
||||||
|
<NavBar class="fixed top-0 left-0 z-10" />
|
||||||
|
<!-- 同高度占位颜色叠加 -->
|
||||||
|
<div class="h-16 bg-base-300" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<FooterBarV2 />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
@@ -39,8 +39,9 @@ const progress = ref([
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="lg:pb-102 md:pb-122 pb-154">
|
||||||
<div class="bg-base-200">
|
<!-- 这里开 relative 形成 stack context -->
|
||||||
|
<div class="bg-base-200 relative z-2">
|
||||||
<div class="h-screen flex flex-col">
|
<div class="h-screen flex flex-col">
|
||||||
<NavBar class="fixed top-0 left-0 z-10" />
|
<NavBar class="fixed top-0 left-0 z-10" />
|
||||||
<!-- 同高度占位颜色叠加 -->
|
<!-- 同高度占位颜色叠加 -->
|
||||||
@@ -91,7 +92,6 @@ const progress = ref([
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="h-102 bg-transparent z-5" />
|
|
||||||
<FooterBarV2 />
|
<FooterBarV2 />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
20
src/pages/join.vue
Normal file
20
src/pages/join.vue
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import NavBar from "@/components/menu/NavBar.vue";
|
||||||
|
import FooterBarV2 from "@/components/layout/FooterBarV2.vue";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="lg:pb-102 md:pb-122 pb-154">
|
||||||
|
<!-- 这里开 relative 形成 stack context -->
|
||||||
|
<div class="bg-base-200 relative z-2">
|
||||||
|
<div class="h-screen flex flex-col">
|
||||||
|
<NavBar class="fixed top-0 left-0 z-10" />
|
||||||
|
<!-- 同高度占位颜色叠加 -->
|
||||||
|
<div class="h-16 bg-base-300" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<FooterBarV2 />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
Reference in New Issue
Block a user