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:
@@ -130,6 +130,8 @@ const handleKeydown = (event: KeyboardEvent) => {
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
screenWidthStore.init();
|
||||
|
||||
document.addEventListener("click", handleDocumentClick);
|
||||
document.addEventListener("keydown", handleKeydown);
|
||||
});
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -173,6 +173,8 @@ const resizeHandler = () => {
|
||||
|
||||
if (typeof window !== "undefined") {
|
||||
onMounted(() => {
|
||||
screenWidthStore.init();
|
||||
|
||||
toggleMonitoring(screenWidthStore.isAboveBreakpoint);
|
||||
|
||||
window.addEventListener("resize", resizeHandler);
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user