Skip to content

布局

布局

Teek 的布局组件有顶部栏、菜单栏、标签栏、内容区,位于 src/layout/components 下的 headermenutab-navpage-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-configlayout 配置默认布局:

ts
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 配置默认标签栏:

ts
export const defaultServiceConfig: ServiceConfig = {
  layout: {
    tabNavMode: TabNavModeEnum.Simple,
  },
};

页面切换

点击页面右上角的 头像,然后点击 我的设置,在 基础配置 区域看到 标签页风格 进行选择。

页面刷新

方法一

如果您想在执行完某些操作(增删改)之后刷新页面,Teek 已经通过 provide 往 views 目录下的组件注入一个函数,您只需要通过 inject 接收,然后调用即可。

相关实现代码:src/layout/components/page-content/index.vue

ts
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 值

ts
import { RefreshPageKey } from "@/common/config";

const refreshPage = inject(RefreshPageKey);

refreshPage?.(false);
nextTick(() => {
  refreshPage?.(true);
});

先传入 false,在 nextTick 生命周期再传入 true 来实现刷新。

传入参数的方式适用于您想在刷新前做些事情,在您没有第二次传入 true 时,页面是不会重新加载的。

不传参数

您可以直接调用该函数,如果不传入参数,则函数内部自动实现刷新功能

ts
import { RefreshPageKey } from "@/common/config";

const refreshPage = inject(RefreshPageKey);

refreshPage?.();

方法二

Teek 内置重定向组件 redirect.vue,位于 /src/layout/redirect.vue,并且该组件已经在 staticRoutes 进行加载注入,所以你只需要了解如何使用该组件跳转即可。

方法非常简单,利用编程式路由跳转:

ts
const router = useRouter();

router.push("/redirect/home");
// or
router.replace("/redirect/home");

这样将会跳转到 /home 的路由,/redirect 是重定向必须的前缀路径,后面携带的地址就是路由对应的 path。

所以实现页面刷新,只需要在重定向到自己的 path。

ts
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

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:错误日志 Store
  • message.ts:消息中心 Store
  • websocket.ts:Websocket 连接信息 Store

事件总栈

Vue3 已经去掉事件总栈,所以无法使用事件总栈来给不同组件传递事件。

Teek 提供了 mittBus 来实现事件总栈。

在某个组件里注册一个事件到事件总栈:

ts
import { mittBus } from "@/common/utils";

mittBus.on("openThemeDrawer", (value: boolean) => (drawerVisible.value = value));

在任意组件中触发该事件:

ts
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 进行配置:

ts
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 配置内容:

ts
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 内置部分数据的缓存功能:

ts
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.jsonversion 就可以触发版本升级功能:

json
{
  "version": "1.0.0" // => "1.0.1"
}