前端:抽象了创建服务上下文
This commit is contained in:
parent
1385251318
commit
88bf3b5592
@ -8,8 +8,8 @@
|
|||||||
*/
|
*/
|
||||||
import { SerializeType } from "./generalRequirement";
|
import { SerializeType } from "./generalRequirement";
|
||||||
import { ExtensionProps } from "types/extensionRequirement";
|
import { ExtensionProps } from "types/extensionRequirement";
|
||||||
import { useExtention } from "hooks/extensionService";
|
|
||||||
import { ExtensionService } from "service/extensionService";
|
import { ExtensionService } from "service/extensionService";
|
||||||
|
import { useExtension } from "hooks/servicesProvider";
|
||||||
|
|
||||||
export interface PluginConfig {
|
export interface PluginConfig {
|
||||||
name: string; // 插件名称
|
name: string; // 插件名称
|
||||||
@ -46,25 +46,14 @@ export interface PluginConfiguration {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PluginDependencies {
|
|
||||||
plugins: string[]; // 依赖的插件列表(可选)
|
|
||||||
themes: string[]; // 依赖的主题列表(可选)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 插件属性接口
|
* 插件属性接口
|
||||||
*
|
*
|
||||||
* 该接口定义了插件的属性和行为。
|
* 该接口定义了插件的属性和行为。
|
||||||
*/
|
*/
|
||||||
export class usePluginProps implements ExtensionProps {
|
export class usePluginProps extends ExtensionProps {
|
||||||
private extensionService: ExtensionService = useExtention();
|
|
||||||
private dependencies: PluginDependencies;
|
|
||||||
|
|
||||||
constructor(dependencies: PluginDependencies) {
|
|
||||||
this.dependencies = dependencies;
|
|
||||||
}
|
|
||||||
|
|
||||||
action?: ((...args: any[]) => void); // 动作函数(可选)
|
|
||||||
component?: (...args: any[]) => React.FC; // 组件函数(可选)
|
|
||||||
text?: (...args: any[]) => string; // 文本生成函数(可选)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Meta, Outlet, Scripts, ScrollRestoration } from "@remix-run/react";
|
import { Meta, Outlet, Scripts, ScrollRestoration } from "@remix-run/react";
|
||||||
import type { LoaderFunction } from "@remix-run/node";
|
import type { LoaderFunction } from "@remix-run/node";
|
||||||
import { useLoaderData } from "@remix-run/react";
|
import { useLoaderData } from "@remix-run/react";
|
||||||
import { ThemeProvider } from "hooks/themeContext";
|
|
||||||
import { createContext, useContext, ReactNode } from 'react';
|
import { createContext, useContext, ReactNode } from 'react';
|
||||||
|
import { ServiceProvider } from "hooks/servicesProvider";
|
||||||
import "./tailwind.css";
|
import "./tailwind.css";
|
||||||
|
|
||||||
export function Layout({ children }: { children: React.ReactNode }) {
|
export function Layout({ children }: { children: React.ReactNode }) {
|
||||||
@ -17,9 +17,9 @@ export function Layout({ children }: { children: React.ReactNode }) {
|
|||||||
<Meta />
|
<Meta />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<ThemeProvider>
|
<ServiceProvider>
|
||||||
{children}
|
{children}
|
||||||
</ThemeProvider>
|
</ServiceProvider>
|
||||||
<ScrollRestoration />
|
<ScrollRestoration />
|
||||||
<Scripts />
|
<Scripts />
|
||||||
</body>
|
</body>
|
||||||
|
@ -1,55 +1,50 @@
|
|||||||
// File path: /hooks/createServiceContext.tsx
|
// File path: /hooks/createServiceContext.tsx
|
||||||
|
|
||||||
import { createContext, ReactNode, useContext } from "react";
|
import { createContext, useContext, ReactNode, FC } from 'react';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建一个服务上下文,用于提供和使用服务实例。
|
* 创建服务上下文的返回类型
|
||||||
*
|
|
||||||
* @param name - 服务的名称,用于错误提示。
|
|
||||||
* @param getInstance - 一个函数,用于获取服务实例。
|
|
||||||
* @returns 返回一个包含 Provider 组件和 useService 钩子的对象。
|
|
||||||
*/
|
*/
|
||||||
interface ServiceContextResult<T> {
|
type ServiceContextReturn<N extends string,T> = {
|
||||||
Provider: React.FC<{ children: ReactNode }>; // 提供服务实例的组件
|
[K in `${N}Provider`]: FC<{ children: ReactNode }>;
|
||||||
useService: () => T; // 获取服务实例的钩子
|
} & {
|
||||||
}
|
[K in `use${N}`]: () => T;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建服务上下文的函数。
|
* 创建服务上下文和相关钩子的工厂函数
|
||||||
*
|
*
|
||||||
* @param name - 服务的名称,用于错误提示。
|
* @param serviceName - 服务名称,用于错误信息
|
||||||
* @param getInstance - 获取服务实例的函数。
|
* @param ServiceClass - 服务类(包含静态 getInstance 方法)
|
||||||
* @returns 包含 Provider 组件和 useService 钩子的对象。
|
|
||||||
*/
|
*/
|
||||||
export function createServiceContext<T>(
|
export function createServiceContext<T, N extends string>(
|
||||||
name: string,
|
serviceName: N,
|
||||||
getInstance: () => T
|
getServiceInstance: () => T
|
||||||
): ServiceContextResult<T> {
|
): ServiceContextReturn<N,T> {
|
||||||
// 创建一个上下文,初始值为 undefined。
|
|
||||||
const ServiceContext = createContext<T | undefined>(undefined);
|
const ServiceContext = createContext<T | undefined>(undefined);
|
||||||
|
|
||||||
// Provider 组件,用于提供服务实例给子组件
|
/**
|
||||||
const Provider = ({ children }: { children: ReactNode }) => {
|
* 服务提供者组件
|
||||||
const service = getInstance();
|
*/
|
||||||
|
const Provider: FC<{ children: ReactNode }> = ({ children }) => (
|
||||||
|
<ServiceContext.Provider value={getServiceInstance()}>
|
||||||
|
{children}
|
||||||
|
</ServiceContext.Provider>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
/**
|
||||||
<ServiceContext.Provider value={service}>
|
* 自定义钩子,用于获取服务实例
|
||||||
{children}
|
*/
|
||||||
</ServiceContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取服务实例的钩子
|
|
||||||
const useService = (): T => {
|
const useService = (): T => {
|
||||||
const context = useContext(ServiceContext);
|
const context = useContext(ServiceContext);
|
||||||
if (context === undefined) {
|
if (context === undefined) {
|
||||||
throw new Error(`use${name} must be used within a ${name}Provider`);
|
throw new Error(`use${serviceName} must be used within a ${serviceName}Provider`);
|
||||||
}
|
}
|
||||||
return context;
|
return context;
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
Provider,
|
[`${serviceName}Provider`]: Provider,
|
||||||
useService,
|
[`use${serviceName}`]: useService,
|
||||||
};
|
} as ServiceContextReturn<N,T>;
|
||||||
}
|
}
|
@ -1,41 +0,0 @@
|
|||||||
// File path: /d:/data/echoes/frontend/hooks/extensionService.tsx
|
|
||||||
/**
|
|
||||||
* 扩展服务上下文提供者和自定义 Hook。
|
|
||||||
*
|
|
||||||
* 该文件包含扩展服务的上下文提供者组件和用于访问该上下文的自定义 Hook。
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { createContext, useContext, ReactNode } from 'react';
|
|
||||||
import { ExtensionService } from 'service/extensionService';
|
|
||||||
|
|
||||||
// 创建扩展服务上下文
|
|
||||||
const ExtensionContext = createContext<ExtensionService | undefined>(undefined);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 扩展提供者组件,用于提供扩展服务的上下文。
|
|
||||||
*
|
|
||||||
* @param children - 要渲染的子组件。
|
|
||||||
*/
|
|
||||||
export function ExtensionProvider({ children }: { children: ReactNode }) {
|
|
||||||
const extensionService = ExtensionService.getInstance(); // 获取扩展服务实例
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ExtensionContext.Provider value={extensionService}>
|
|
||||||
{children}
|
|
||||||
</ExtensionContext.Provider>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 自定义 Hook,用于访问扩展服务上下文。
|
|
||||||
*
|
|
||||||
* @returns {ExtensionService} - 返回扩展服务实例。
|
|
||||||
* @throws {Error} - 如果在未被 ExtensionProvider 包裹的组件中调用,将抛出错误。
|
|
||||||
*/
|
|
||||||
export function useExtention(): ExtensionService {
|
|
||||||
const context = useContext(ExtensionContext); // 获取扩展服务上下文
|
|
||||||
if (context === undefined) {
|
|
||||||
throw new Error('useTheme must be used within a ThemeProvider'); // 抛出错误
|
|
||||||
}
|
|
||||||
return context; // 返回扩展服务实例
|
|
||||||
}
|
|
22
frontend/hooks/servicesProvider.tsx
Normal file
22
frontend/hooks/servicesProvider.tsx
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { ExtensionService } from 'service/extensionService';
|
||||||
|
import { ThemeService } from 'service/themeService';
|
||||||
|
import { createServiceContext } from './createServiceContext';
|
||||||
|
import { ReactNode } from 'react';
|
||||||
|
|
||||||
|
export const {
|
||||||
|
ExtensionProvider,
|
||||||
|
useExtension
|
||||||
|
} = createServiceContext('Extension', () => ExtensionService.getInstance());
|
||||||
|
|
||||||
|
export const {
|
||||||
|
ThemeProvider,
|
||||||
|
useTheme
|
||||||
|
} = createServiceContext("Theme", () => ThemeService.getInstance());
|
||||||
|
|
||||||
|
export const ServiceProvider = ({ children }: { children: ReactNode })=>(
|
||||||
|
<ExtensionProvider>
|
||||||
|
<ThemeProvider>
|
||||||
|
{children}
|
||||||
|
</ThemeProvider>
|
||||||
|
</ExtensionProvider>
|
||||||
|
);
|
@ -1,36 +0,0 @@
|
|||||||
// File path: /hooks/themeContext.tsx
|
|
||||||
|
|
||||||
import { createContext, useContext, ReactNode } from 'react';
|
|
||||||
import { ThemeService } from 'service/themeService';
|
|
||||||
|
|
||||||
const ThemeContext = createContext<ThemeService | undefined>(undefined);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ThemeProvider 组件用于提供主题上下文给其子组件。
|
|
||||||
* 它使用 ThemeService 的单例实例来管理主题相关的状态和功能。
|
|
||||||
*
|
|
||||||
* @param children - 要渲染的子组件。
|
|
||||||
*/
|
|
||||||
export function ThemeProvider({ children }: { children: ReactNode }) {
|
|
||||||
const themeService = ThemeService.getInstance();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ThemeContext.Provider value={themeService}>
|
|
||||||
{children}
|
|
||||||
</ThemeContext.Provider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* useTheme 钩子用于访问主题上下文。
|
|
||||||
*
|
|
||||||
* @returns ThemeService - 返回主题服务的实例。
|
|
||||||
* @throws Error - 如果在 ThemeProvider 之外使用,将抛出错误。
|
|
||||||
*/
|
|
||||||
export function useTheme(): ThemeService {
|
|
||||||
const context = useContext(ThemeContext);
|
|
||||||
if (context === undefined) {
|
|
||||||
throw new Error('useTheme must be used within a ThemeProvider');
|
|
||||||
}
|
|
||||||
return context;
|
|
||||||
}
|
|
@ -88,7 +88,7 @@ export class ExtensionService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//获取指定配置文件
|
//获取指定配置文件
|
||||||
getConfiguration(pluginName: string): PluginConfiguration | undefined {
|
private getConfiguration(pluginName: string): PluginConfiguration | undefined {
|
||||||
return this.configuration.get(pluginName);
|
return this.configuration.get(pluginName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user