mirror of
https://github.com/sendevia/website.git
synced 2026-03-05 23:32:45 +08:00
refactor: improve code comments for better clarity and maintainability
This commit is contained in:
@@ -8,35 +8,34 @@ import { useScreenWidthStore } from "../stores/screenWidth";
|
||||
import { handleTabNavigation } from "../utils/tabNavigation";
|
||||
import { useRoute } from "vitepress";
|
||||
|
||||
// 初始化 store 实例
|
||||
/** 初始化 store 实例 */
|
||||
const searchStateStore = useSearchStateStore();
|
||||
const screenWidthStore = useScreenWidthStore();
|
||||
const postsStore = usePostStore();
|
||||
|
||||
// 从 posts store 中解构出 posts 响应式数据
|
||||
/** 解构出 posts 响应式数据 */
|
||||
const { posts } = storeToRefs(postsStore);
|
||||
|
||||
// 初始化路由实例
|
||||
/** 初始化路由实例 */
|
||||
const route = useRoute();
|
||||
|
||||
// DOM 元素引用
|
||||
/** DOM 元素引用 */
|
||||
const scrollTarget = ref<HTMLElement | null>(null); // 滚动容器的 DOM 引用
|
||||
const appbar = ref<HTMLElement | null>(null); // AppBar 自身的 DOM 引用
|
||||
const searchInput = ref<HTMLInputElement | null>(null); // 搜索输入框的 DOM 引用
|
||||
|
||||
// 本地响应式状态
|
||||
/** 本地响应式状态 */
|
||||
const query = ref(""); // 搜索输入框的绑定值
|
||||
const isHidden = ref(false); // 控制 AppBar 是否隐藏的状态
|
||||
|
||||
// 使用 useGlobalScroll
|
||||
const { scrollResult, isScrolled: globalIsScrolled } = useGlobalScroll({ threshold: 100 });
|
||||
const { y, directions } = scrollResult;
|
||||
|
||||
// 计算属性
|
||||
const isScrolled = computed(() => globalIsScrolled.value); // 使用 useGlobalScroll 的 isScrolled
|
||||
/** 计算属性 */
|
||||
const isScrolled = computed(() => globalIsScrolled.value);
|
||||
const isTabFocusable = computed(() => !screenWidthStore.isAboveBreakpoint); // 判断当前屏幕宽度下,元素是否应该可被 Tab 键聚焦
|
||||
|
||||
// 工具函数:获取滚动容器
|
||||
/** 获取滚动容器 */
|
||||
const getScrollContainer = () => document.querySelector<HTMLElement>(".content-flow");
|
||||
|
||||
/**
|
||||
@@ -148,7 +147,7 @@ watch(
|
||||
}
|
||||
);
|
||||
|
||||
// 检查是否在搜索激活状态
|
||||
/** 检查是否在搜索激活状态 */
|
||||
const isSearchActive = computed(() => searchStateStore.isSearchActive);
|
||||
|
||||
/**
|
||||
@@ -204,7 +203,7 @@ const handleKeydown = (event: KeyboardEvent) => {
|
||||
}
|
||||
};
|
||||
|
||||
// 监听路由变化,处理页面切换后的状态重置和滚动绑定
|
||||
/** 处理页面切换后的状态重置和滚动绑定 */
|
||||
watch(
|
||||
() => route.path,
|
||||
async () => {
|
||||
@@ -225,25 +224,25 @@ watch(
|
||||
}
|
||||
);
|
||||
|
||||
// 事件处理函数引用(用于清理)
|
||||
/** 事件处理函数引用 */
|
||||
const eventHandlers = {
|
||||
click: handleDocumentClick,
|
||||
keydown: handleKeydown,
|
||||
} as const;
|
||||
|
||||
// 添加事件监听器
|
||||
/** 添加事件监听器 */
|
||||
const addEventListeners = () => {
|
||||
document.addEventListener("click", eventHandlers.click);
|
||||
document.addEventListener("keydown", eventHandlers.keydown);
|
||||
};
|
||||
|
||||
// 移除事件监听器
|
||||
/** 移除事件监听器 */
|
||||
const removeEventListeners = () => {
|
||||
document.removeEventListener("click", eventHandlers.click);
|
||||
document.removeEventListener("keydown", eventHandlers.keydown);
|
||||
};
|
||||
|
||||
// 初始化函数
|
||||
/** 初始化函数 */
|
||||
const initializeAppBar = () => {
|
||||
screenWidthStore.init();
|
||||
|
||||
@@ -257,7 +256,7 @@ const initializeAppBar = () => {
|
||||
addEventListeners();
|
||||
};
|
||||
|
||||
// 清理函数
|
||||
/** 清理函数 */
|
||||
const cleanupAppBar = () => {
|
||||
// 移除事件监听器
|
||||
removeEventListeners();
|
||||
@@ -324,7 +323,6 @@ onUnmounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <p class="description" v-if="post.description">{{ post.description }}</p> -->
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -32,9 +32,7 @@ const remainingTime = ref(config.duration);
|
||||
const isFastForwarding = ref(false);
|
||||
const isAnimating = ref(false);
|
||||
|
||||
/**
|
||||
* 计算当前应该显示的文章印象图列表
|
||||
*/
|
||||
/** 计算当前应该显示的文章印象图列表 */
|
||||
const rawImgList = computed<string[]>(() => {
|
||||
const imp = frontmatter.value.impression;
|
||||
const list = Array.isArray(imp) ? imp : imp ? [imp] : [theme.value.defaultImpression];
|
||||
@@ -45,18 +43,14 @@ const totalCount = computed(() => rawImgList.value.length);
|
||||
const hasMultiple = computed(() => totalCount.value > 1);
|
||||
const animDuration = computed(() => (isFastForwarding.value ? config.animFast : config.animNormal));
|
||||
|
||||
/**
|
||||
* 计算环形进度条百分比
|
||||
*/
|
||||
/** 计算环形进度条百分比 */
|
||||
const progress = computed(() => {
|
||||
if (!hasMultiple.value) return 0;
|
||||
if (isFastForwarding.value) return 100;
|
||||
return ((config.duration - remainingTime.value) / config.duration) * 100;
|
||||
});
|
||||
|
||||
/**
|
||||
* 获取真实的索引(对总数取模)
|
||||
*/
|
||||
/** 获取真实的索引(对总数取模) */
|
||||
const currentRealIndex = computed(() => {
|
||||
if (totalCount.value === 0) return 0;
|
||||
return ((virtualIndex.value % totalCount.value) + totalCount.value) % totalCount.value;
|
||||
|
||||
@@ -3,9 +3,6 @@ import { ref, computed, onMounted, nextTick, watch } from "vue";
|
||||
import { useWindowSize, useEventListener, useVModel } from "@vueuse/core";
|
||||
import { handleTabNavigation } from "../utils/tabNavigation";
|
||||
|
||||
/**
|
||||
* 组件属性定义
|
||||
*/
|
||||
interface Props {
|
||||
images: string[];
|
||||
currentIndex: number;
|
||||
@@ -54,9 +51,7 @@ const currentImage = computed(() => props.images[activeIndex.value]);
|
||||
const hasPrevious = computed(() => activeIndex.value > 0);
|
||||
const hasNext = computed(() => activeIndex.value < props.images.length - 1);
|
||||
|
||||
/**
|
||||
* 计算图片从文章位置飞出的初始变换参数
|
||||
*/
|
||||
/** 计算图片从文章位置飞出的初始变换参数 */
|
||||
const calculateInitialTransform = () => {
|
||||
const { x, y, width, height } = props.originPosition;
|
||||
if (width > 0 && height > 0) {
|
||||
@@ -72,17 +67,13 @@ const calculateInitialTransform = () => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 重置缩放与平移位置
|
||||
*/
|
||||
/** 重置缩放与平移位置 */
|
||||
const resetZoom = () => {
|
||||
imageScale.value = 1;
|
||||
imagePosition.value = { x: 0, y: 0 };
|
||||
};
|
||||
|
||||
/**
|
||||
* 显示查看器,并记录当前焦点
|
||||
*/
|
||||
/** 显示查看器,并记录当前焦点 */
|
||||
const show = () => {
|
||||
// 立即记录当前活跃元素
|
||||
lastActiveElement.value = document.activeElement as HTMLElement;
|
||||
@@ -100,9 +91,7 @@ const show = () => {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 隐藏查看器,并还原焦点
|
||||
*/
|
||||
/** 隐藏查看器,并还原焦点 */
|
||||
const hide = () => {
|
||||
calculateInitialTransform();
|
||||
isAnimating.value = false;
|
||||
|
||||
@@ -129,7 +129,7 @@ function onAnimationEnd(el: EventTarget | null) {
|
||||
}
|
||||
}
|
||||
|
||||
// 监听状态变化,手动触发宽度计算
|
||||
/** 监听状态变化,触发宽度计算 */
|
||||
watch(
|
||||
() => [navStateStore.isNavExpanded],
|
||||
() => {
|
||||
|
||||
@@ -38,17 +38,13 @@ const articleId = computed(() => {
|
||||
|
||||
const shortLink = computed(() => (articleId.value ? `/p/${articleId.value}` : ""));
|
||||
|
||||
/**
|
||||
* 复制短链到剪贴板
|
||||
*/
|
||||
/** 复制短链到剪贴板 */
|
||||
const copyShortLink = async () => {
|
||||
if (!shortLink.value) return;
|
||||
await copyToClipboard(`${window.location.origin}${shortLink.value}`);
|
||||
};
|
||||
|
||||
/**
|
||||
* 收集页面中的 h1 和 h2 标题
|
||||
*/
|
||||
/** 收集页面中的 h1 和 h2 标题 */
|
||||
const collectHeadings = () => {
|
||||
if (!isClient()) return;
|
||||
const nodes = Array.from(document.querySelectorAll("h1[id], h2[id]")) as HTMLElement[];
|
||||
@@ -59,9 +55,7 @@ const collectHeadings = () => {
|
||||
}));
|
||||
};
|
||||
|
||||
/**
|
||||
* 更新指示器(高亮块)的位置和尺寸
|
||||
*/
|
||||
/** 更新指示器(高亮边框)的位置和尺寸 */
|
||||
const updateIndicator = () => {
|
||||
const container = pageIndicator.value;
|
||||
const id = headingsActiveId.value;
|
||||
|
||||
@@ -107,6 +107,5 @@ const next = computed(() => {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@use "sass:meta";
|
||||
/* 引用现有的导航组件样式 */
|
||||
@include meta.load-css("../styles/components/PrevNext");
|
||||
</style>
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
import { onMounted, onBeforeUnmount } from "vue";
|
||||
import { isClient } from "../utils/env";
|
||||
|
||||
/**
|
||||
* 元素宽度观察器配置
|
||||
*/
|
||||
/** 元素宽度观察器配置 */
|
||||
interface ElementWidthObserverConfig {
|
||||
/** CSS选择器 */
|
||||
selector: string;
|
||||
@@ -22,9 +20,7 @@ interface ElementWidthObserverConfig {
|
||||
ignoreParentLimit?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成有效的CSS变量名
|
||||
*/
|
||||
/** 生成有效的CSS变量名 */
|
||||
function generateVariableName(selector: string): string {
|
||||
// 移除特殊字符,用连字符连接
|
||||
let name = selector
|
||||
@@ -44,9 +40,7 @@ function generateVariableName(selector: string): string {
|
||||
return name + "-width";
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化宽度值,保留指定精度
|
||||
*/
|
||||
/** 格式化宽度值,保留指定精度 */
|
||||
function formatWidth(width: number, precision: number = 2): string {
|
||||
// 使用toFixed确保精度,但移除不必要的尾随零
|
||||
const fixed = width.toFixed(precision);
|
||||
@@ -54,9 +48,7 @@ function formatWidth(width: number, precision: number = 2): string {
|
||||
return parseFloat(fixed).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置元素宽度CSS变量到父级元素
|
||||
*/
|
||||
/** 设置元素宽度CSS变量到父级元素 */
|
||||
export function setupWidthObserver(config: ElementWidthObserverConfig, targetElements?: HTMLElement[]): () => void {
|
||||
const { selector, variableName, parentSelector, precision = 2, ignoreParentLimit = false } = config;
|
||||
|
||||
@@ -148,10 +140,3 @@ export function useElementWidthObserver(configs: ElementWidthObserverConfig[]) {
|
||||
cleanupFunctions.forEach((cleanup) => cleanup());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 简化的单元素宽度观察器
|
||||
*/
|
||||
export function useSingleElementWidthObserver(config: ElementWidthObserverConfig) {
|
||||
return useElementWidthObserver([config]);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 再包装的全局数据
|
||||
*/
|
||||
|
||||
import { useData } from "vitepress";
|
||||
|
||||
export function useGlobalData() {
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import { ref, computed, watch, onMounted, onUnmounted } from "vue";
|
||||
/**
|
||||
* 适用本项目的再包装 useScroll 工具函数
|
||||
*/
|
||||
|
||||
import { ref, computed, watch, onMounted } from "vue";
|
||||
import { useScroll } from "@vueuse/core";
|
||||
import { isClient } from "../utils/env";
|
||||
|
||||
// 全局状态
|
||||
/** 全局状态 */
|
||||
const globalThreshold = ref(80);
|
||||
const globalPrecision = ref(1);
|
||||
const globalTargetScrollable = ref(".content-flow");
|
||||
@@ -11,14 +15,21 @@ const globalIsScrolled = ref(false);
|
||||
const globalScrollPosition = ref(0);
|
||||
const globalScrollPercentage = ref(0);
|
||||
|
||||
// 检测可滚动容器
|
||||
/**
|
||||
* 容器能否滚动
|
||||
* @param el 容器
|
||||
*/
|
||||
function isScrollable(el: HTMLElement) {
|
||||
const style = window.getComputedStyle(el);
|
||||
const overflowY = style.overflowY;
|
||||
return overflowY === "auto" || overflowY === "scroll" || el.scrollHeight > el.clientHeight;
|
||||
}
|
||||
|
||||
// 检测容器
|
||||
/**
|
||||
* 检测容器
|
||||
* @param targetScrollable 目标容器
|
||||
* @returns 判断通过的滚动容器
|
||||
*/
|
||||
function detectContainer(targetScrollable: string) {
|
||||
if (!isClient()) return window;
|
||||
|
||||
@@ -27,7 +38,13 @@ function detectContainer(targetScrollable: string) {
|
||||
return window;
|
||||
}
|
||||
|
||||
// 计算滚动百分比
|
||||
/**
|
||||
* 计算滚动百分比
|
||||
* @param scrollTop 顶部距离
|
||||
* @param scrollContainer 滚动容器
|
||||
* @param precision 浮点精度
|
||||
* @returns 百分比
|
||||
*/
|
||||
function calculatePercentage(scrollTop: number, scrollContainer: HTMLElement | Window, precision: number): number {
|
||||
try {
|
||||
let scrollHeight: number, clientHeight: number;
|
||||
@@ -55,13 +72,14 @@ function calculatePercentage(scrollTop: number, scrollContainer: HTMLElement | W
|
||||
}
|
||||
}
|
||||
|
||||
// 更新全局状态
|
||||
/** 更新全局状态 */
|
||||
function updateGlobalState(y: number, container: HTMLElement | Window, threshold: number, precision: number) {
|
||||
globalScrollPosition.value = y;
|
||||
globalIsScrolled.value = y > threshold;
|
||||
globalScrollPercentage.value = calculatePercentage(y, container, precision);
|
||||
}
|
||||
|
||||
/** 导出 */
|
||||
export function useGlobalScroll(options?: { threshold?: number; container?: string; precision?: number }) {
|
||||
const localThreshold = options?.threshold ?? globalThreshold.value;
|
||||
const localPrecision = options?.precision ?? globalPrecision.value;
|
||||
@@ -155,7 +173,7 @@ export function useGlobalScroll(options?: { threshold?: number; container?: stri
|
||||
scrollPosition: computed(() => localScrollPosition.value),
|
||||
scrollPercentage: computed(() => localScrollPercentage.value),
|
||||
|
||||
// 原始 useScroll 结果(用于高级用途)
|
||||
// 原始 useScroll 结果
|
||||
scrollResult,
|
||||
|
||||
// 容器引用
|
||||
@@ -167,7 +185,7 @@ export function useGlobalScroll(options?: { threshold?: number; container?: stri
|
||||
};
|
||||
}
|
||||
|
||||
// 全局滚动状态
|
||||
/** 全局滚动状态 */
|
||||
export const globalScrollState = {
|
||||
isScrolled: computed(() => globalIsScrolled.value),
|
||||
threshold: computed(() => globalThreshold.value),
|
||||
|
||||
@@ -18,9 +18,7 @@ const lastUpdatedRawTime = computed(() =>
|
||||
lastUpdatedTime.value ? useDateFormat(lastUpdatedTime.value, "YYYY-MM-DD HH:mm:ss").value : ""
|
||||
);
|
||||
|
||||
/**
|
||||
* 相对时间显示配置
|
||||
*/
|
||||
/** 相对时间显示配置 */
|
||||
const timeAgo = useTimeAgo(
|
||||
computed(() => lastUpdatedTime.value || 0),
|
||||
{
|
||||
@@ -87,9 +85,7 @@ const openImageViewer = (index: number, event: MouseEvent) => {
|
||||
showImageViewer.value = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* 复制锚点链接到剪贴板
|
||||
*/
|
||||
/** 复制锚点链接到剪贴板 */
|
||||
const handleAnchorClick = (event: MouseEvent) => {
|
||||
const anchor = (event.target as HTMLElement).closest("a.title-anchor") as HTMLAnchorElement;
|
||||
if (!anchor) return;
|
||||
@@ -108,9 +104,7 @@ const handleAnchorClick = (event: MouseEvent) => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 处理列表 Bullet 旋转和有序列表对齐
|
||||
*/
|
||||
/** 处理列表 Bullet 旋转和有序列表对齐 */
|
||||
const enhanceDomStyles = () => {
|
||||
if (!articleContentRef.value) return;
|
||||
|
||||
@@ -132,9 +126,7 @@ const enhanceDomStyles = () => {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 绑定文章图片点击监听
|
||||
*/
|
||||
/** 绑定文章图片点击监听 */
|
||||
const bindImageEvents = () => {
|
||||
articleContentRef.value?.querySelectorAll("img").forEach((img, index) => {
|
||||
(img as HTMLElement).onclick = (e) => openImageViewer(index, e);
|
||||
|
||||
@@ -8,21 +8,15 @@ import { getFormattedRandomPhrase } from "../utils/phrases";
|
||||
import { useGlobalData } from "../composables/useGlobalData";
|
||||
import { usePostStore } from "../stores/posts";
|
||||
import { isClient } from "../utils/env";
|
||||
|
||||
// 导入布局组件
|
||||
import ArticleLayout from "./Article.vue";
|
||||
import NotFoundLayout from "./NotFound.vue";
|
||||
|
||||
/**
|
||||
* 全局数据与路由状态
|
||||
*/
|
||||
/** 全局数据与路由状态 */
|
||||
const { site, page, frontmatter, theme } = useGlobalData();
|
||||
const route = useRoute();
|
||||
const postStore = usePostStore();
|
||||
const isRedirecting = ref(false);
|
||||
const pageTitle = useTitle();
|
||||
|
||||
/** 随机问候语 */
|
||||
const randomGreeting = ref(getFormattedRandomPhrase());
|
||||
|
||||
/** 布局映射表 */
|
||||
@@ -118,9 +112,7 @@ if (isClient()) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 路由变化监听:处理短链重定向
|
||||
*/
|
||||
/** 处理短链重定向 */
|
||||
watch(
|
||||
() => route.path,
|
||||
(newPath) => {
|
||||
@@ -131,9 +123,7 @@ watch(
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
/**
|
||||
* 监听首页状态变化,进入首页时更新随机问候语
|
||||
*/
|
||||
/** 进入首页时更新随机问候语 */
|
||||
watch(
|
||||
() => frontmatter.value.home,
|
||||
(isHome) => {
|
||||
@@ -143,9 +133,7 @@ watch(
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* 过渡动画钩子:进入后更新色板
|
||||
*/
|
||||
/** 进入后更新色板 */
|
||||
function onAfterEnter() {
|
||||
if (!isRedirecting.value) updatePalette();
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/**
|
||||
* 侧边导航栏状态管理
|
||||
*/
|
||||
|
||||
import { defineStore } from "pinia";
|
||||
import { ref, watch } from "vue";
|
||||
import { isClient } from "../utils/env";
|
||||
import { getCookie, setCookie } from "../utils/cookie";
|
||||
import { useScreenWidthStore } from "./screenWidth";
|
||||
|
||||
/**
|
||||
* 侧边导航栏状态管理
|
||||
*/
|
||||
/** 导出 */
|
||||
export const useNavStateStore = defineStore("navState", () => {
|
||||
const isNavExpanded = ref<boolean>(false);
|
||||
const cookieName = "nav-expanded";
|
||||
const screenWidthStore = useScreenWidthStore();
|
||||
|
||||
/**
|
||||
* 初始从 Cookie 读取状态
|
||||
*/
|
||||
/** 初始从 Cookie 读取状态 */
|
||||
function init() {
|
||||
if (!isClient()) return;
|
||||
screenWidthStore.update();
|
||||
@@ -51,34 +51,26 @@ export const useNavStateStore = defineStore("navState", () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存状态到 Cookie
|
||||
*/
|
||||
/** 保存状态到 Cookie */
|
||||
function saveToCookie() {
|
||||
if (!isClient()) return;
|
||||
|
||||
setCookie(cookieName, isNavExpanded.value.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 展开导航栏
|
||||
*/
|
||||
/** 展开导航栏 */
|
||||
function expand() {
|
||||
if (screenWidthStore.isAboveBreakpoint) {
|
||||
isNavExpanded.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 折叠导航栏
|
||||
*/
|
||||
/** 折叠导航栏 */
|
||||
function collapse() {
|
||||
isNavExpanded.value = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换导航栏状态
|
||||
*/
|
||||
/** 切换导航栏状态 */
|
||||
function toggle() {
|
||||
if (isNavExpanded.value) {
|
||||
collapse();
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* 文章数据获取
|
||||
* 生成文章 ID,格式化头部数据
|
||||
*/
|
||||
|
||||
import { createContentLoader, type ContentData } from "vitepress";
|
||||
|
||||
export interface PostData {
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* 文章数据存储处理
|
||||
*/
|
||||
|
||||
import { defineStore } from "pinia";
|
||||
import { computed, ref } from "vue";
|
||||
import { data as postsData, type PostData } from "./posts.data";
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
/**
|
||||
* 屏幕宽度响应式状态管理
|
||||
*/
|
||||
|
||||
import { defineStore } from "pinia";
|
||||
import { ref, watch, onUnmounted } from "vue";
|
||||
import { isClient } from "../utils/env";
|
||||
|
||||
/**
|
||||
* 屏幕宽度响应式状态管理
|
||||
*/
|
||||
/** 导出 */
|
||||
export const useScreenWidthStore = defineStore("screenWidth", () => {
|
||||
// 响应式状态
|
||||
const screenWidth = ref<number>(0);
|
||||
@@ -15,9 +17,7 @@ export const useScreenWidthStore = defineStore("screenWidth", () => {
|
||||
let resizeHandler: (() => void) | null = null;
|
||||
let isInitialized = false;
|
||||
|
||||
/**
|
||||
* 更新屏幕宽度状态
|
||||
*/
|
||||
/** 更新屏幕宽度状态 */
|
||||
function update() {
|
||||
if (!isClient()) return;
|
||||
|
||||
@@ -25,9 +25,7 @@ export const useScreenWidthStore = defineStore("screenWidth", () => {
|
||||
isAboveBreakpoint.value = screenWidth.value > breakpoint.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化监听器
|
||||
*/
|
||||
/** 初始化监听器 */
|
||||
function init() {
|
||||
if (!isClient() || isInitialized) return;
|
||||
|
||||
@@ -43,9 +41,7 @@ export const useScreenWidthStore = defineStore("screenWidth", () => {
|
||||
isInitialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理监听器
|
||||
*/
|
||||
/** 清理监听器 */
|
||||
function cleanup() {
|
||||
if (resizeHandler && isClient()) {
|
||||
window.removeEventListener("resize", resizeHandler);
|
||||
|
||||
@@ -1,25 +1,23 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { ref, watch } from "vue";
|
||||
|
||||
/**
|
||||
* 搜索状态管理
|
||||
*/
|
||||
|
||||
import { defineStore } from "pinia";
|
||||
import { ref, watch } from "vue";
|
||||
|
||||
/** 导出 */
|
||||
export const useSearchStateStore = defineStore("searchState", () => {
|
||||
// 响应式状态
|
||||
const isSearchActive = ref<boolean>(false);
|
||||
const isSearchFocused = ref<boolean>(false);
|
||||
const isSearchTyping = ref<boolean>(false);
|
||||
|
||||
/**
|
||||
* 激活搜索
|
||||
*/
|
||||
/** 激活搜索 */
|
||||
function activate() {
|
||||
isSearchActive.value = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 停用搜索
|
||||
*/
|
||||
/** 停用搜索 */
|
||||
function deactivate() {
|
||||
isSearchActive.value = false;
|
||||
isSearchFocused.value = false;
|
||||
@@ -46,9 +44,7 @@ export const useSearchStateStore = defineStore("searchState", () => {
|
||||
isSearchTyping.value = typing;
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换搜索状态
|
||||
*/
|
||||
/** 切换搜索状态 */
|
||||
function toggle() {
|
||||
if (isSearchActive.value) {
|
||||
deactivate();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* 短语库 - 用于在主页显示随机问候语
|
||||
* 用于在主页显示随机问候语的短语库
|
||||
*/
|
||||
|
||||
export interface Phrase {
|
||||
@@ -23,9 +23,7 @@ export function getCurrentTimeOfDay(): "morning" | "afternoon" | "evening" {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 短语库 - 按时间段分类
|
||||
*/
|
||||
/** 按时间段分类 */
|
||||
export const phrasesByTime: Record<"morning" | "afternoon" | "evening" | "any", Phrase[]> = {
|
||||
morning: [
|
||||
{ text: "早上好!新的一天开始啦", timeOfDay: "morning" },
|
||||
|
||||
Reference in New Issue
Block a user