feat: ✨ 布局,样式统一,集成依赖

This commit is contained in:
何嘉悦
2025-05-19 06:58:57 +08:00
parent b5cddb0041
commit c163da8e8a
37 changed files with 1429 additions and 300 deletions
+61
View File
@@ -0,0 +1,61 @@
import { COLLAPSE_THRESHOLD } from '@/config/index';
import { useWindowWidthObserver } from '@/hooks/useWindowWidthObserver';
import { useDesignStore } from '@/store/modules/design';
/**
* 侧边栏折叠切换逻辑组合式函数 方便多个页面调用
* @param threshold 折叠阈值(可选,默认使用全局配置)
*/
export function useCollapseToggle(threshold: number = COLLAPSE_THRESHOLD) {
const designStore = useDesignStore();
// 获取当前视口宽度是否大于阈值,但不做响应式处理,传入一个空函数执行
const { isAboveThreshold } = useWindowWidthObserver(threshold, () => {});
/** 核心折叠切换方法 */
const changeCollapse = () => {
// 切换最终折叠状态
designStore.setCollapseFinal(!designStore.isCollapse);
if (isAboveThreshold.value) {
// 宽屏逻辑
if (designStore.isCollapse) {
designStore.setCollapseType('alwaysCollapsed');
}
else {
designStore.setCollapseType(
designStore.collapseType === 'narrowExpandWideCollapse'
? 'alwaysExpanded'
: 'followSystem',
);
}
}
else {
// 窄屏逻辑
if (designStore.isCollapse) {
designStore.setCollapseType('followSystem');
}
else {
designStore.setCollapseType(
designStore.collapseType === 'alwaysCollapsed'
? 'narrowExpandWideCollapse'
: 'alwaysExpanded',
);
}
}
};
return {
changeCollapse,
};
}
// 使用示例与特性说明
// <script setup lang="ts">
// import { useCollapseToggle } from '@/composables/useCollapseToggle';
// import { COLLAPSE_THRESHOLD } from '@/config/index'; (可传,不传入全局配置走)
// const { changeCollapseIcon } = useCollapseToggle(designStore, COLLAPSE_THRESHOLD);
// </script>
// <template>
// <!-- 其他页面的按钮 -->
// <button @click="changeCollapseIcon">切换侧边栏</button>
// </template>
+36 -9
View File
@@ -1,15 +1,17 @@
import type { MaybeRef } from 'vue';
import { onBeforeUnmount, ref, unref, watch } from 'vue';
import { COLLAPSE_THRESHOLD, SIDE_BAR_WIDTH } from '@/config/index';
import { useDesignStore } from '@/store/modules/design';
/**
* 这里逻辑是研究豆包的折叠逻辑后,设计的折叠方法
* 基于ResizeObserver的窗口宽度监听hooks(高性能实时监控)
* @param threshold 宽度阈值(默认600px,支持响应式)
* @param onChange 自定义回调(传入则覆盖默认逻辑,参数:当前视口宽度是否超过阈值)
* @returns {object} 包含卸载监听的方法及当前状态
*/
export function useWindowWidthObserver(
threshold: MaybeRef<number> = 600,
threshold: MaybeRef<number> = COLLAPSE_THRESHOLD,
onChange?: (isAboveThreshold: boolean) => void,
) {
const designStore = useDesignStore();
@@ -20,15 +22,40 @@ export function useWindowWidthObserver(
// 默认逻辑:修改全局折叠状态
const updateCollapseState = (isAbove: boolean) => {
if (!isAbove) {
// 小于阈值时 且为展开状态时候
// 跟随用户当前的意愿
designStore.setCollapseFinal(designStore.isCollapseManual);
// 如果是开,则执行展开动画表示用户意愿
// 判断当前的折叠状态
switch (designStore.collapseType) {
case 'alwaysCollapsed':
designStore.setCollapseFinal(true);
break;
case 'followSystem':
designStore.setCollapseFinal(!isAbove);
designStore.setCollapseFinal(!isAbove);
break;
case 'alwaysExpanded':
designStore.setCollapseFinal(false);
if (isAbove) {
// 大于的时候执行关闭动画
console.log('执行关闭动画');
}
else {
// 小于的时候执行打开动画
console.log('小于的时候执行打开动画');
}
break;
case 'narrowExpandWideCollapse':
designStore.setCollapseFinal(isAbove);
designStore.setCollapseFinal(isAbove);
}
else if (!designStore.isCollapseFinal && isAbove) {
// 大于阈值时 且为收起状态时
designStore.setCollapseFinal(true);
console.log('最终的折叠状态:', designStore.isCollapse);
if (!designStore.isCollapse) {
document.documentElement.style.setProperty(
`--sidebar-left-container-default-width`,
`${SIDE_BAR_WIDTH}px`,
);
}
else {
document.documentElement.style.setProperty(`--sidebar-left-container-default-width`, ``);
}
};