User页面的增删改查;开发模式接口地址使用本地魔方,端口7166;yarn.lock锁定版本;gitignore忽略编辑器目录及临时目录
Yann authored at 2025-06-22 23:27:02
4.92 KiB
cube-front
/**
 * Vue 应用初始化模块
 *
 * 这个模块负责创建和配置 Vue 应用实例,包括:
 * - 创建应用实例和根组件
 * - 注册全局插件(路由、状态管理、国际化、UI库)
 * - 提供默认的依赖注入值
 * - 支持外部配置和依赖注入覆盖
 * - 挂载应用到 DOM
 *
 * @example 基本使用
 * ```typescript
 * import { initApp } from './core/initApp';
 *
 * // 使用默认配置初始化应用
 * initApp();
 * ```
 *
 * @example 使用自定义配置
 * ```typescript
 * import { initApp } from './core/initApp';
 * import CustomLayout from './CustomLayout.vue';
 * import { LayoutKey } from './core/composables/useProvideInject';
 *
 * initApp((app, { provide, hasProvided }) => {
 *   // 检查是否已经提供了布局
 *   if (!hasProvided(LayoutKey)) {
 *     provide(app, LayoutKey, CustomLayout);
 *   }
 *
 *   // 或者强制覆盖默认布局
 *   provide(app, LayoutKey, CustomLayout, { override: true });
 * });
 * ```
 */
import { type App as App2 } from 'vue';
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css';
import App from './App.vue';
import router from './router';
import i18n from './i18n';
import './global.css';
import MainLayout from './layouts/MainLayout/index.vue';
import { appProvide, hasProvided, LayoutKey, getProvidedKeys } from './composables/useProvideInject';


/**
 * 应用配置选项接口
 *
 * 定义了可以通过配置函数传递的选项类型。
 * 这个接口可以扩展以支持更多的配置选项。
 */
export interface AppConfigOptions {
  /** 自定义布局组件 */
  Layout?: unknown;
  /** 自定义主题配置 */
  Theme?: unknown;
  /** 其他自定义配置项 */
  [key: string]: unknown;
}

/**
 * 高级配置函数类型
 *
 * 这个函数类型定义了在应用初始化过程中可以执行的配置操作。
 * 配置函数会在插件安装完成后、应用挂载前执行。
 *
 * @param app - Vue 应用实例
 * @param utils - 提供的工具函数集合
 * @param utils.provide - 安全的依赖注入提供函数
 * @param utils.hasProvided - 检查某个键是否已经被提供的函数
 * @param utils.getProvidedKeys - 获取所有已提供键的函数
 */
export type ConfigureFunction = (app: App2<Element>, utils: {
  provide: typeof appProvide;
  hasProvided: typeof hasProvided;
  getProvidedKeys: typeof getProvidedKeys;
}) => void;

/**
 * 初始化 Vue 应用
 *
 * 这个函数创建并配置一个完整的 Vue 应用实例。它按照以下顺序执行:
 * 1. 创建 Vue 应用实例
 * 2. 安装核心插件(路由、状态管理、国际化、UI库)
 * 3. 执行外部配置函数(允许外部覆盖内部配置)
 * 4. 提供默认的依赖注入值(如果外部没有提供的话)
 * 5. 挂载应用到 DOM
 * 6. 暴露全局调试接口
 *
 * @param configure - 可选的配置函数,在插件安装后、应用挂载前执行
 *
 * @example 基本初始化
 * ```typescript
 * // 使用默认配置初始化应用
 * initApp();
 * ```
 *
 * @example 自定义布局
 * ```typescript
 * import CustomLayout from './layouts/CustomLayout.vue';
 *
 * initApp((app, { provide, hasProvided }) => {
 *   // 提供自定义布局,优先于默认布局
 *   provide(app, LayoutKey, CustomLayout, { override: true });
 * });
 * ```
 *
 * @example 条件性配置
 * ```typescript
 * initApp((app, { provide, hasProvided, getProvidedKeys }) => {
 *   // 检查是否已经提供了布局
 *   if (!hasProvided(LayoutKey)) {
 *     provide(app, LayoutKey, MyCustomLayout);
 *   }
 *
 *   // 调试:打印所有已提供的键
 *   console.log('已提供的依赖:', getProvidedKeys());
 * });
 * ```
 *
 * @example 提供多个依赖
 * ```typescript
 * initApp((app, { provide }) => {
 *   // 提供自定义主题
 *   provide(app, ThemeKey, {
 *     primaryColor: '#007fff',
 *     backgroundColor: '#f5f5f5'
 *   });
 *
 *   // 提供应用配置
 *   provide(app, ConfigKey, {
 *     apiUrl: 'https://api.example.com',
 *     version: '1.0.0'
 *   });
 * });
 * ```
 */
export const initApp = async (configure?: ConfigureFunction) => {

  const pinia = createPinia();

  const app = createApp(App);

  // 安装核心插件
  app.use(router);
  app.use(pinia);
  app.use(i18n); // 添加 i18n 插件
  app.use(ElementPlus);

  // 执行外部配置函数,允许外部覆盖内部配置
  // 这里外部可以提供自定义的依赖注入值,优先于默认值
  await configure?.(app, {
    provide: appProvide,
    hasProvided,
    getProvidedKeys
  });

  // 提供默认的依赖注入值
  // 只有在外部没有提供的情况下才提供默认值
  if (!hasProvided(LayoutKey)) {
    appProvide(app, LayoutKey, MainLayout, { track: true });
  }

  app.mount('#app');

  // 全局暴露路由和状态管理实例,方便调试和外部访问
  // 在生产环境中可以考虑移除这些全局暴露
  window.router = router;
  window.store = pinia;
};