布局
布局
Teek 的布局组件有顶部栏、菜单栏、标签栏、内容区,位于 src/layout/components
下的 header
、menu
、tab-nav
、page-content
里。
内容区(page-content
)专门加载路由组件,路由组件在 src/views
下。
布局支持 6 种形式动态切换,分别为
- 纵向布局:
src/layout/layout-vertical
- 经典布局:
src/layout/layout-classic
- 横向布局:
src/layout/layout-horizontal
- 分栏布局:
src/layout/layout-columns
- 混合布局:
src/layout/layout-mixins
- 嵌入布局:
src/layout/layout-iframe
Teek 使用了 components
内置组件来实现 6 中布局的动态切换,具体请看 src/layout/index.vue
内容。
默认布局
可以在 src/common/config/service/base-config
的 layout
配置默认布局:
export const defaultServiceConfig: ServiceConfig = {
layout: {
layoutMode: LayoutModeEnum.Vertical,
},
};
页面切换
虽然设置了默认布局,但是可以手动在页面上切换布局。
点击页面右上角的 头像
,然后点击 我的设置
,即可看到 6 个布局的预览图,点击进行切换布局。
提示
Teek 内置配置缓存功能,因此下次进来的布局会是切换后的布局,如果想还原默认配置,则在 我的设置
最下方点击 还原默认配置
按钮。
标签栏
标签页支持 3 种形式:
- 经典风格:保留 Teek Design Vue2 的经典标签栏
- 简洁风格:基于经典标签栏进行二次样式优化,当前是 Teek 的默认标签栏
- 元素风格:使用
ElementPlus
提供的el-tabs
组件实现
标签栏采用了 components
内置组件来动态切换,具体请看 src/layout/components/page-content
的实现。
默认布局
可以在 src/common/config/service/base-config
的 themeConfig 配置默认标签栏:
export const defaultServiceConfig: ServiceConfig = {
layout: {
tabNavMode: TabNavModeEnum.Simple,
},
};
页面切换
点击页面右上角的 头像
,然后点击 我的设置
,在 基础配置
区域看到 标签页风格 进行选择。
页面刷新
方法一
如果您想在执行完某些操作(增删改)之后刷新页面,Teek 已经通过 provide 往 views 目录下的组件注入一个函数,您只需要通过 inject
接收,然后调用即可。
相关实现代码:src/layout/components/page-content/index.vue
import { RefreshPageKey } from "@/common/config";
const isRefreshRoute = ref(true);
/**
* 刷新当前页面函数
*/
const refreshPage = (value?: boolean) => {
if (value !== undefined) return (isRefreshRoute.value = value);
isRefreshRoute.value = false;
nextTick(() => (isRefreshRoute.value = true));
};
/**
* 往所有路径组件提供刷新当前页面函数
*/
provide(RefreshPageKey, refreshPage);
使用的方式有两种:
传入 boolean 参数
提供 inject
接收的是一个函数,如果您调用该函数时,可以传入参数,参数类型为 boolean 值
import { RefreshPageKey } from "@/common/config";
const refreshPage = inject(RefreshPageKey);
refreshPage?.(false);
nextTick(() => {
refreshPage?.(true);
});
先传入 false
,在 nextTick
生命周期再传入 true
来实现刷新。
传入参数的方式适用于您想在刷新前做些事情,在您没有第二次传入 true 时,页面是不会重新加载的。
不传参数
您可以直接调用该函数,如果不传入参数,则函数内部自动实现刷新功能
import { RefreshPageKey } from "@/common/config";
const refreshPage = inject(RefreshPageKey);
refreshPage?.();
方法二
Teek 内置重定向组件 redirect.vue
,位于 /src/layout/redirect.vue
,并且该组件已经在 staticRoutes 进行加载注入,所以你只需要了解如何使用该组件跳转即可。
方法非常简单,利用编程式路由跳转:
const router = useRouter();
router.push("/redirect/home");
// or
router.replace("/redirect/home");
这样将会跳转到 /home
的路由,/redirect
是重定向必须的前缀路径,后面携带的地址就是路由对应的 path。
所以实现页面刷新,只需要在重定向到自己的 path。
const router = useRouter();
const route = useRoute();
router.push("/redirect" + route.path);
// or
router.replace("/redirect" + route.fullPath);
具体是 route.path
还是 route.fullPath
,根据你的需求来实现,最终都会刷新当前页面。
方法三
第三种方法其实就是第一种方法的简化版,在第一种方法里,我们需要引入 RefreshPageKey
来 inject 获取函数,当长时间不用的时候,我们很难想起来有一个叫 RefreshPageKey
的 Symbol。
因此 Teek 封装了一个 use-common
的可组合式函数(composables),位于:src/composables/core/use-common.ts
。
import { useCommon } from "@/composables";
const { refreshPage } = useCommon();
// 传入 boolean 值
refreshPage?.(false);
nextTick(() => {
refreshPage?.(true);
});
// 直接调用
refreshPage?.();
状态管理 Pinia
状态管理文件存储了 Teek 的共享数据,位于 src/pinia/stores
下:
layout.ts
:布局信息 Store,存储标签栏数据、路由缓存数据、布局信息、多语言信息route.ts
:路由权限 Store,存储加载的路由信息,Teek 用该数据生成了菜单栏settings.ts
:可配置 Store,在右上角 我的设置 里修改后,会保存在 Store 中,并同步到浏览器缓存user.ts
:用户信息 Store,存储用户登录的信息errorLog.ts
:错误日志 Storemessage.ts
:消息中心 Storewebsocket.ts
:Websocket 连接信息 Store
事件总栈
Vue3 已经去掉事件总栈,所以无法使用事件总栈来给不同组件传递事件。
Teek 提供了 mittBus 来实现事件总栈。
在某个组件里注册一个事件到事件总栈:
import { mittBus } from "@/common/utils";
mittBus.on("openThemeDrawer", (value: boolean) => (drawerVisible.value = value));
在任意组件中触发该事件:
import { mittBus } from "@/common/utils";
const openSettingsDrawer = () => {
mittBus.emit("openThemeDrawer", true);
};
错误日志
Teek 内置错误日志,当项目抛出 Error 的时候,Teek 会将其捕获,然后放到日志组件里,您可以在页面的右上角看到一个「虫子」的图标,点击后会跳转到日志页面,查看错误的信息。
「虫子」的图标只有在出现抛出至少 1 个 Error 的时候才会出现,默认是不出现的,如果你想直接访问,则访问项目根路径 + /error-log
。
Teek 默认不捕获错误,如果你想在本地环境、测试环境、生产环境开启/关闭,则在 src/common/config/service/base-config.ts
文件的 layoutConfig 里,对 errorLog
进行配置:
export const defaultServiceConfig: ServiceConfig = {
layout: {
errorLog: {
showInHeader: true, // 错误日志是否在顶部出现图标,提供可点击进入的入口
printConsole: true, // 是否打印错误日志到控制台
env: ["development", "test", "production"], // 错误日志触发的环境,这里依次对应本地环境、测试环境、生产环境
},
},
};
提示
如果 printConsole
为 false,在浏览器开发者工具的 console
控制台将会无法看到错误信息。
错误日志功能的出现是为了让用户更直观的看到错误信息,从而快速截图,告知相关开发者解决问题。
如果不开启错误日志功能,当用户使用过程中出现 Error,非开发用户无法快速查看 Error 信息,而开发者只能根据用户提供的步骤进行复现,或者远程操控用户电脑看 console
控制台的错误,这是非常不方便的。
工具类
Teek 提供了一些通用的工具类函数,位于 src/common/utils
下。
可组合式函数
Teek 提供了一些通用的可组合式函数,位于 src/composables
下。
进度条
Teek 使用 nprogress 插件来实现页面加载过程的进度条显示,如果你不喜欢 Teek 默认的进度条样式,则可以在 src/common/utils/core/plugins/nprogress.ts
文件里进行修改。
下面是 Teek 默认的 nprogress 配置内容:
import NProgress from "nprogress";
import "nprogress/nprogress.css";
NProgress.configure({
easing: "ease", // 动画方式
speed: 500, // 递增进度条的速度
showSpinner: true, // 是否显示加载 ico
trickleSpeed: 200, // 自动递增间隔
minimum: 0.3, // 初始化时的最小百分比
});
export default NProgress;
export { NProgress };
版本升级
Teek 内置部分数据的缓存功能:
export interface KeyConfig {
/** 缓存 key 前缀 */
cacheKeyPrefix: string;
/** 缓存标签页的 key */
tabNavCacheKey: string;
/** 缓存版本号的 key */
versionCacheKey: string;
/** 当 URL 携带参数时,标签页会出现多个重复且名字一样的 tab,该配置可指定忽略哪些参数生成新的 tab,如果为 * 则忽略所有参数 */
tabExcludesUrlKey: string[];
/** 缓存路由的 key */
cacheDynamicRoutesKey: string;
/** 是否在升级时清理所有缓存,默认 false */
cleanCacheWhenUpgrade: boolean;
}
Teek 将这些键值缓存在 localstorage
里。
Teek 经历过很多这些缓存导致问题的场景,比如 Teek 发布了一个新版,修改了内容是配置、项目,但是因为用户的浏览器已经缓存了这些旧版内容,而新版用旧版的缓存导致出现了很多问题,因此 Teek 内置 版本升级 功能。
发布一个新的版本时:
- 当
cleanCacheWhenUpgrade
为 true 时,Teek 会清理所有缓存,重置为默认缓存 - 当
cleanCacheWhenUpgrade
为 false 时,Teek 首先会将上一个版本的缓存原封不动迁移到当前版本
那么如何让 Teek 知道更新了一个新版本呢?
只需要修改 package.json
的 version
就可以触发版本升级功能:
{
"version": "1.0.0" // => "1.0.1"
}