1
0
mirror of https://github.com/sendevia/website.git synced 2026-03-05 23:32:45 +08:00

feat: initialize screen width store in components and refactor store logic

This commit is contained in:
2025-12-09 14:37:31 +08:00
parent 8beeb84e0a
commit b693666cae
4 changed files with 45 additions and 52 deletions

View File

@@ -130,6 +130,8 @@ const handleKeydown = (event: KeyboardEvent) => {
};
onMounted(() => {
screenWidthStore.init();
document.addEventListener("click", handleDocumentClick);
document.addEventListener("keydown", handleKeydown);
});

View File

@@ -1,5 +1,5 @@
<script setup lang="ts">
import { computed } from "vue";
import { computed, onMounted } from "vue";
import { useGlobalData } from "../composables/useGlobalData";
import { useScreenWidthStore } from "../stores/screenWidth";
import { useSearchStateStore } from "../stores/searchState";
@@ -14,18 +14,9 @@ const navSegment = computed(() => {
return Array.isArray(items) && items.length > 0 ? items : [];
});
/**
* 计算导航栏模式 (Rail / Bar)
*/
const navMode = computed(() => {
const currentWidth = screenWidthStore.screenWidth;
const breakpoint = screenWidthStore.breakpoint;
if (currentWidth <= 840) {
return "bar";
}
return currentWidth > breakpoint ? "rail" : "bar";
// 计算导航栏类名
const navClass = computed(() => {
return screenWidthStore.isAboveBreakpoint ? "rail" : "bar";
});
// 规范化路径
@@ -52,10 +43,14 @@ function isExternalLink(link: string): boolean {
const externalLinkPatterns = [/^https?:\/\//];
return externalLinkPatterns.some((pattern) => pattern.test(link));
}
onMounted(() => {
screenWidthStore.init();
});
</script>
<template>
<nav class="NavBar" :class="navMode">
<nav class="NavBar" :class="navClass">
<button class="fab" @mousedown.prevent @click.stop="toggleSearch">
<span>{{ searchStateStore.isSearchActive ? "close" : "search" }}</span>
</button>

View File

@@ -173,6 +173,8 @@ const resizeHandler = () => {
if (typeof window !== "undefined") {
onMounted(() => {
screenWidthStore.init();
toggleMonitoring(screenWidthStore.isAboveBreakpoint);
window.addEventListener("resize", resizeHandler);

View File

@@ -1,5 +1,5 @@
import { defineStore } from "pinia";
import { ref, watch } from "vue";
import { ref, watch, onUnmounted } from "vue";
/**
* 屏幕宽度响应式状态管理
@@ -12,59 +12,47 @@ export const useScreenWidthStore = defineStore("screenWidth", () => {
// 内部状态
let resizeHandler: (() => void) | null = null;
let fallbackHandler: (() => void) | null = null;
let isInitialized = false;
/**
* 检查是否在客户端环境
*/
function isClient() {
return typeof window !== "undefined";
}
/**
* 更新屏幕宽度状态
*/
function update() {
if (typeof window !== "undefined") {
screenWidth.value = window.innerWidth;
isAboveBreakpoint.value = screenWidth.value > breakpoint.value;
}
}
if (!isClient()) return;
/**
* Fallback 检查
*/
function runFallbackCheck() {
update();
screenWidth.value = window.innerWidth;
isAboveBreakpoint.value = screenWidth.value > breakpoint.value;
}
/**
* 初始化监听器
*/
function init() {
if (typeof window !== "undefined" && !isInitialized) {
if (!isClient() || isInitialized) return;
// 使用 requestAnimationFrame 确保 DOM 已准备好
requestAnimationFrame(() => {
update();
resizeHandler = () => update();
window.addEventListener("resize", resizeHandler);
if (document.readyState === "complete") {
runFallbackCheck();
} else {
fallbackHandler = () => runFallbackCheck();
window.addEventListener("load", fallbackHandler);
}
isInitialized = true;
}
});
}
/**
* 清理监听器
*/
function cleanup() {
if (typeof window !== "undefined") {
if (resizeHandler) {
window.removeEventListener("resize", resizeHandler);
resizeHandler = null;
}
if (fallbackHandler) {
window.removeEventListener("load", fallbackHandler);
fallbackHandler = null;
}
if (resizeHandler && isClient()) {
window.removeEventListener("resize", resizeHandler);
resizeHandler = null;
isInitialized = false;
}
}
@@ -75,17 +63,23 @@ export const useScreenWidthStore = defineStore("screenWidth", () => {
*/
function setBreakpoint(value: number) {
breakpoint.value = value;
update();
if (isClient()) {
update();
}
}
// 监听断点变化,自动更新状态
watch(breakpoint, () => {
update();
if (isClient()) {
update();
}
});
// 自动初始化
if (typeof window !== "undefined") {
init();
// 在组件卸载时自动清理
if (isClient()) {
onUnmounted(() => {
cleanup();
});
}
return {
@@ -95,9 +89,9 @@ export const useScreenWidthStore = defineStore("screenWidth", () => {
breakpoint,
// 方法
update,
init,
cleanup,
update,
setBreakpoint,
cleanup,
};
});