Vben Admin 源码学习:项目初始化
0x00 前言
Vue-Vben-Admin  是一个免费开源的中后台模版。使用了最新的vue3,vite2,TypeScript等主流技术开发,开箱即用的中后台前端解决方案考。
本系列本着学习参考的目的,对项目代码进行深入分析 ,耐心读完,相信您会有所收获。
本系列需要一定的项目使用经验,建议先阅读项目的 中文文档 ,会对理解非常有帮助。
0x.01 目录说明
项目主要目录结构及说明,接下来将一一深入分析介绍。
.
├── build # 打包脚本相关
├── mock # mock文件夹
├── public # 公共静态资源目录
├── src # 主目录
│   ├── api # 接口文件
│   ├── assets # 资源文件
│   ├── components # 公共组件
│   ├── design # 样式文件
│   ├── directives # 指令
│   ├── enums # 枚举/常量
│   ├── hooks # hook
│   ├── layouts # 布局文件
│   ├── locales # 多语言
│   ├── logics # 逻辑
│   ├── main.ts # 主入口
│   ├── router # 路由配置
│   ├── settings # 项目配置
│   ├── store # 数据仓库
│   ├── utils # 工具类
│   └── views # 页面
├── test # 测试
├── types # 类型文件
├── vite.config.ts # vite配置文件
└── windi.config.ts # windcss配置文件
0x.02 系统主入口
文件 src/main.ts 作为系统主入口,主要进行项目初始化操作。
在入口文件中引入windicss,这样项目中就可以使用 [类实用程序] 或 [CSS 指令]。
同时引入项目中使用的通用样式,都存放于 src/design/ 下面,默认使用 less 作为预处理语言。
import 'virtual:windi-base.css';
import 'virtual:windi-components.css';
import '/@/design/index.less';
import 'virtual:windi-utilities.css';
// Register icon sprite
import 'virtual:svg-icons-register';
windcss 目前会造成本地开发内存溢出,所以后续可能会考虑切换到 TailwindCss 。
接下来执行 bootstrap 方法创建项目实列。
import App from './App.vue';
import { createApp } from 'vue';
import { initAppConfigStore } from '/@/logics/initAppConfig';
import { setupErrorHandle } from '/@/logics/error-handle';
import { router, setupRouter } from '/@/router';
import { setupRouterGuard } from '/@/router/guard';
import { setupStore } from '/@/store';
import { setupGlobDirectives } from '/@/directives';
import { setupI18n } from '/@/locales/setupI18n';
import { registerGlobComp } from '/@/components/registerGlobComp';
// 项目的初始化配置
async function bootstrap() {
  // 创建应用实例
  const app = createApp(App);
  // 配置存储使用Pinia
  setupStore(app);
  // 初始化内部系统配置
  initAppConfigStore();
  // 注册全局组件
  registerGlobComp(app);
  // 多语言配置
  await setupI18n(app);
  // 配置路由
  setupRouter(app);
  // 路由守卫、权限判断、初始化缓存数据
  setupRouterGuard(router);
  // 注册全局指令
  setupGlobDirectives(app);
  // 配置全局错误处理
  setupErrorHandle(app);
  ...    
  app.mount('#app');
}
bootstrap();
bootstrap() 执行时调用了很多方法用于初始化操作,包括配置存储、加载系统配置注册、注册全局组件、多语言配置、路由配置、路由守卫、权限过滤、注册全局指令等。接下来将快速概览下各方法:
setupStore
src\store\index.ts 文件中声明 setupStore 方法,用于将创建一个 pinia 根存储并注册到应用程序中。
...
import { createPinia } from 'pinia';
// 创建一个 pinia(根存储)
const store = createPinia();
export function setupStore(app: App<Element>) {
  // 注册到应用程序
  app.use(store);
}
initAppConfigStore
src\logics\initAppConfig.ts 文件中声明 initAppConfigStore 方法,用于加载并存储 国际化、主题风格、项目配置、页面加载、页面状态、顶栏配置、菜单配置等项目信息。
export function initAppConfigStore() {
  const localeStore = useLocaleStore(); // 多语言国际化
  const appStore = useAppStore(); // 应用状态(主题风格、项目配置、页面加载、页面状态等等)
  // 项目配置 (主题颜色、主题模式、顶栏配置、菜单配置)
  let projCfg: ProjectConfig = Persistent.getLocal(PROJ_CFG_KEY) as ProjectConfig;
  projCfg = deepMerge(projectSetting, projCfg || {});
  ...
  // 存储项目配置
  appStore.setProjectConfig(projCfg);
  // init dark mode  初始化暗黑模式
  updateDarkTheme(darkMode);
  if (darkMode === ThemeEnum.DARK) {
     ...
  } else {
    ...
  }
  // init store  初始化国际化多语言
  localeStore.initLocale();
  // 清理过期的缓存
  setTimeout(() => {
    clearObsoleteStorage();
  }, 16);
}
registerGlobComp
src\components\registerGlobComp.ts文件中声明 registerGlobComp 方法,全局注册 antdv的Input、Layout组件和手写的Button组件
import { Button } from './Button';
import { Input, Layout } from 'ant-design-vue';
export function registerGlobComp(app: App) {
  // 注册 antdv的Input、Layout组件和手写的Button组件
  app.use(Input).use(Button).use(Layout);
}
setupI18n
src\locales\setupI18n.ts 文件中声明 setupI18n 方法,初始化国际化插件 vue-i18n 实例并注册到应用程序中。
// 国际化插件 vue-i18n 配置项
async function createI18nOptions(): Promise<I18nOptions> {
  const localeStore = useLocaleStoreWithOut(); // 国际化本地存储
  const locale = localeStore.getLocale; // 语言环境/当前语言
  const defaultLocal = await import(`./lang/${locale}.ts`); // 从服务器端获取语言翻译文件
  const message = defaultLocal.default?.message ?? {}; // 本地化的语言环境信息
  ...
  return {
    legacy: false,
    locale, // 语言环境
    fallbackLocale: fallback, // 预设的语言环境
    // 本地化的语言环境信息
    messages: {
      [locale]: message,
    },
    availableLocales: availableLocales, // 以词法顺序排列的 messages 中的可用语言环境列表
    sync: true, // 是否将根级别语言环境与组件本地化语言环境同步。 如果为 false,则无论根级别语言环境如何,都要为每个组件语言环境进行本地化。
    silentTranslationWarn: true, // true - warning off  是否取消本地化失败时输出的警告。如果为 true,则禁止本地化失败警告。
    missingWarn: false,
    silentFallbackWarn: true, // 是否在回退到 fallbackLocale 或 root 时取消警告。如果为 true,则仅在根本没有可用的转换时生成警告,而不是在回退时。
  };
}
// 初始化国际化实例
export async function setupI18n(app: App) {
  // 获取国际化插件 vue-i18n 配置项
  const options = await createI18nOptions();
  i18n = createI18n(options) as I18n;
  app.use(i18n);
}
setupRouter
src\router\index.ts 文件中声明 setupRouter 方法,创建路由实例,加载初始路由列表,注册到应用程序中。
// app router  创建路由实例
export const router = createRouter({
  history: createWebHashHistory(import.meta.env.VITE_PUBLIC_PATH), // 基于 hash 的历史记录
  routes: basicRoutes as unknown as RouteRecordRaw[], // 添加到路由的初始路由列表
  scrollBehavior: () => ({ left: 0, top: 0 }), // 在页面之间导航时控制滚动的函数
});
// 注册路由
export function setupRouter(app: App<Element>) {
  app.use(router);
}
setupRouterGuard
src\router\guard\index.ts 文件中声明 setupRouterGuard 方法,创建了处理页面加载状态、路由切换、页面顶部进度条、权限验证、菜单及系统状态等守卫。
export function setupRouterGuard(router: Router) {
  createPageGuard(router); // 处理页面状态
  createPageLoadingGuard(router); // 处理页面加载状态
  createHttpGuard(router); // 路由切换时关闭当前页面完成请求
  createScrollGuard(router); // 路由切换回到顶部
  createMessageGuard(router); // 路由切换时关闭消息实例
  createProgressGuard(router); // 页面顶部进度条
  createPermissionGuard(router); // 路由切换时权限验证
  createParamMenuGuard(router); // 菜单守卫
  createStateGuard(router); // 系统状态守卫- 当用户未登录时,进入登录页面并清除存储中的认证信息
}
setupErrorHandle
src\logics\error-handle\index.ts 文件中声明 setupErrorHandle 方法,配置全局错误处理,用于监控Vue异常、脚本错误、promise 异常、 静态资源异常等。
/**
 * Configure global error handling  配置全局错误处理
 * @param app
 */
export function setupErrorHandle(app: App) {
  const { useErrorHandle } = projectSetting;
  if (!useErrorHandle) {
    return;
  }
  // Vue exception monitoring; Vue异常监控
  app.config.errorHandler = vueErrorHandler;
  // script error   脚本错误监控
  window.onerror = scriptErrorHandler;
  //  promise exception  promise 异常监控
  registerPromiseErrorHandler();
  // Static resource exception  静态资源异常监控
  registerResourceErrorHandler();
}
本文主要概述了项目实例创建时初始化的流程,接下来我们将逐一分析每个模块的功能。
Vben Admin 源码学习:项目初始化的更多相关文章
- Vben Admin 源码学习:状态管理-角色权限
		前言 本文将对 Vue-Vben-Admin 角色权限的状态管理进行源码解读,耐心读完,相信您一定会有所收获! 更多系列文章详见专栏 Vben Admin 项目分析&实践 . 本文涉及到角 ... 
- Vben Admin 源码学习:状态管理-错误日志
		0x00 前言 本文将对 Vue-Vben-Admin 的状态管理实现源码进行分析解读,耐心读完,相信您一定会有所收获! 0x01 errorLog.ts 错误日志 文件 src\store\modu ... 
- 05.ElementUI源码学习:项目发布配置(github pages&npm package)
		0x00.前言 书接上文.项目第一个组件已经封装好,说明文档也已编写好.下面需要将说明文档发布到外网上,以此来展示和推广项目,使用 Github Pages功能实现.同时将组件发布之 npm 上,方便 ... 
- Vue源码学习02 初始化模块init.js
		接上篇,我们看到了VUE分了很多模块(initMixin()stateMixin()eventsMixin()lifecycleMixin()renderMixin()),通过使用Mixin模式,都是 ... 
- ibatis源码学习2_初始化和配置文件解析
		问题在详细介绍ibatis初始化过程之前,让我们先来思考几个问题. 1. ibatis初始化的目标是什么?上文中提到过,ibatis初始化的核心目标是构造SqlMapClientImpl对象,主要是其 ... 
- Python源码学习之初始化(三)-PyDictObject的初始化
		先来看它的定义 typedef struct _dictobject PyDictObject; struct _dictobject { PyObject_HEAD Py_ssize_t ma_fi ... 
- 【 js 基础 】【 源码学习 】源码设计 (持续更新)
		学习源码,除了学习对一些方法的更加聪明的代码实现,同时也要学习源码的设计,把握整体的架构.(推荐对源码有一定熟悉了之后,再看这篇文章) 目录结构:第一部分:zepto 设计分析第二部分:undersc ... 
- 【 js 基础 】【 源码学习 】源码设计 (更新了backbone分析)
		学习源码,除了学习对一些方法的更加聪明的代码实现,同时也要学习源码的设计,把握整体的架构.(推荐对源码有一定熟悉了之后,再看这篇文章) 目录结构:第一部分:zepto 设计分析 第二部分:unders ... 
- [tomcat7源码学习]初始化之catalina.home和catalina.base(转)
		我们在代码中为了获取某个配置文件路径下的文件经常会这么写 String tomcatPath = System.getProperty("catalina.home") + &qu ... 
随机推荐
- 使用Egret插件压缩代码包体积,减少请求数量的实战教程
			在白鹭引擎发布了5.2.7版本中新增加了命令行,增加自动合图插件TextureMergerPlugin功能.今天,我们以一个EUI案例来展示自动合图插件的具体使用方法和注意事项. 此外,我们在本文还融 ... 
- IDEA 生成返回值对象快捷键Ctrl+Alt+V失效
			在IDEA上运用快捷键返回对象(Ctrl+Alt+V)的时候一直无效,找了很久的问题,发现是有快捷键冲突,发现QQ音乐快捷键与IDEA冲突了,把那处改掉或者关闭即可. 所以边敲代码边听音乐也要注意一下 
- 牛客网-剑指Offer 二维数组中的查找
			题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数 ... 
- URLDNS反序列化链学习
			URLDNS URLDNS跟CommonsCollections比起来真是眉清目秀,该链主要用于验证漏洞,并不能执行命令,优点就是不依赖任何包. 1.利用链 * Gadget Chain: * Has ... 
- Netty初见-三大组件-简单使用
			Netty系列文章目录 Netty初见-三大组件-简单使用 文件编程-更新中---- 目录 Netty系列文章目录 三大组件 Channel与Buffer Selector 简单使用(ByteBuff ... 
- JAVA学习2——HelloWorld
			Java语言的诞生.版本以及工具:Java的安装开发环境以及环境变量的配置:第一个Java程序--HelloWorld 
- echarts饼图禁止鼠标悬浮高亮
			将高亮时的颜色和原本颜色手动设置成相同的值,把series.data里的itemStyle属性进行设置 代码如下: option = { color:['#3498db','#EEEEEE'], se ... 
- Java和JavaScript(函数)参数传递是按值传递还是按引用传递?
			结论:Java和JavaScript的所有(函数)参数传递都是按值传递! 1.什么是函数参数的传递是按引用传递? 什么是引用?这个概念多见于C++中,在C++中,引用解释为变量的别名. 1 #incl ... 
- 2021牛客暑期多校训练营3 J 思维
			传送门 J-Counting Triangles_2021牛客暑期多校训练营3 (nowcoder.com) 题目 Goodeat finds an undirected complete graph ... 
- 分享两个实用的shell脚本
			各位,早上好啊~ 发现许久没有分享过技术文章了,今天分享两个部署项目时候比较实用的shell脚本 一键部署shell脚本 由于个人部署,会习惯把jar放到lib目录下面,如果你没有这个习惯,可以适当做 ... 
