py-test-component 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ // ============================================
2
+ // py-test-component - TypeScript 类型定义
3
+ // ============================================
4
+
1
5
  declare module 'py-test-component' {
2
6
  export interface PyComponentStore {
3
7
  set(config: Record<string, any>): void;
@@ -35,6 +39,8 @@ declare module 'py-test-component/react' {
35
39
  export interface PyTableProps {
36
40
  /** 表格数据 */
37
41
  data?: Record<string, any>[];
42
+ /** 加载中的占位内容 */
43
+ loading?: ReactNode;
38
44
  /** 其他 HTML 属性 */
39
45
  [key: string]: any;
40
46
  }
@@ -42,29 +48,33 @@ declare module 'py-test-component/react' {
42
48
  export interface PyWeatherProps {
43
49
  /** 城市名称 */
44
50
  city?: string;
51
+ /** 加载中的占位内容 */
52
+ loading?: ReactNode;
45
53
  /** 其他 HTML 属性 */
46
54
  [key: string]: any;
47
55
  }
48
56
 
49
- export interface PyTableRef {
50
- /** 获取 DOM 元素 */
51
- getElement: () => HTMLElement | null;
52
- }
53
-
54
- export interface PyWeatherRef {
57
+ export interface PyComponentRef {
55
58
  /** 获取 DOM 元素 */
56
59
  getElement: () => HTMLElement | null;
60
+ /** 是否已加载完成 */
61
+ loaded: boolean;
62
+ /** 加载错误信息 */
63
+ error: Error | null;
57
64
  }
58
65
 
59
- /** 表格组件 */
60
- export const PyTable: ForwardRefExoticComponent<PyTableProps & RefAttributes<PyTableRef>>;
66
+ /** 表格组件 - React 版本 */
67
+ export const PyTable: ForwardRefExoticComponent<PyTableProps & RefAttributes<PyComponentRef>>;
61
68
 
62
- /** 天气组件 */
63
- export const PyWeather: ForwardRefExoticComponent<PyWeatherProps & RefAttributes<PyWeatherRef>>;
69
+ /** 天气组件 - React 版本 */
70
+ export const PyWeather: ForwardRefExoticComponent<PyWeatherProps & RefAttributes<PyComponentRef>>;
64
71
 
65
72
  /** 初始化组件库 */
66
- export function initPyComponent(config?: Record<string, any>): void;
73
+ export function initPyComponent(config?: Record<string, any>): Promise<any>;
67
74
 
68
75
  /** 获取全局 store */
69
76
  export function getStore(): Record<string, any> | null;
77
+
78
+ /** 预加载组件库(可提前调用以加速渲染) */
79
+ export function preloadPyComponent(): Promise<any>;
70
80
  }
package/package.json CHANGED
@@ -1,17 +1,26 @@
1
1
  {
2
2
  "name": "py-test-component",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Vue2 + ElementUI 组件库,支持 React 使用",
5
5
  "main": "dist/py-component.js",
6
6
  "module": "dist/py-component.esm.js",
7
7
  "types": "index.d.ts",
8
8
  "exports": {
9
9
  ".": {
10
+ "types": "./index.d.ts",
10
11
  "import": "./dist/py-component.esm.js",
11
12
  "require": "./dist/py-component.js"
12
13
  },
13
- "./vue": "./src/vue/index.js",
14
- "./react": "./src/react/index.js"
14
+ "./vue": {
15
+ "types": "./index.d.ts",
16
+ "import": "./src/vue/index.js",
17
+ "require": "./src/vue/index.js"
18
+ },
19
+ "./react": {
20
+ "types": "./index.d.ts",
21
+ "import": "./src/react/index.js",
22
+ "require": "./src/react/index.js"
23
+ }
15
24
  },
16
25
  "files": [
17
26
  "dist",
@@ -1,65 +1,116 @@
1
- import { createElement, useEffect, useRef, forwardRef, useImperativeHandle } from 'react';
1
+ import { createElement, useEffect, useRef, useState, forwardRef, useImperativeHandle } from 'react';
2
2
 
3
- // 加载脚本的 Promise(只加载一次)
3
+ // 加载状态管理
4
4
  let loadPromise = null;
5
+ let isLoaded = false;
5
6
 
7
+ /**
8
+ * 加载组件库核心逻辑
9
+ * 使用 ESM 动态导入,由构建工具处理路径解析
10
+ */
11
+ async function doLoad() {
12
+ if (typeof window === 'undefined') return null;
13
+ if (window.PyComponent) return window.PyComponent;
14
+
15
+ const module = await import('py-test-component');
16
+ const PyComponent = module.default || module;
17
+
18
+ if (PyComponent && typeof window !== 'undefined') {
19
+ window.PyComponent = PyComponent;
20
+ }
21
+
22
+ return PyComponent;
23
+ }
24
+
25
+ /**
26
+ * 获取或创建加载 Promise
27
+ */
6
28
  function loadPyComponent() {
7
29
  if (loadPromise) return loadPromise;
8
- if (typeof window === 'undefined') return Promise.resolve();
9
- if (window.PyComponent) return Promise.resolve(window.PyComponent);
10
-
11
- loadPromise = new Promise((resolve, reject) => {
12
- const script = document.createElement('script');
13
- script.src = '/py-component.js';
14
- script.async = true;
15
- script.onload = () => resolve(window.PyComponent);
16
- script.onerror = reject;
17
- document.body.appendChild(script);
30
+ if (isLoaded && window.PyComponent) {
31
+ return Promise.resolve(window.PyComponent);
32
+ }
33
+
34
+ loadPromise = doLoad().finally(() => {
35
+ isLoaded = true;
18
36
  });
19
37
 
20
38
  return loadPromise;
21
39
  }
22
40
 
41
+ /**
42
+ * 使用组件库的 Hook
43
+ */
44
+ function usePyComponent() {
45
+ const [loaded, setLoaded] = useState(isLoaded);
46
+ const [error, setError] = useState(null);
47
+
48
+ useEffect(() => {
49
+ if (isLoaded) {
50
+ setLoaded(true);
51
+ return;
52
+ }
53
+
54
+ loadPyComponent()
55
+ .then(() => setLoaded(true))
56
+ .catch((err) => {
57
+ console.error('[py-test-component] 加载失败:', err);
58
+ setError(err);
59
+ });
60
+ }, []);
61
+
62
+ return { loaded, error, PyComponent: typeof window !== 'undefined' ? window.PyComponent : null };
63
+ }
64
+
23
65
  // PyTable React 包装组件
24
- export const PyTable = forwardRef(function PyTable({ data, ...props }, ref) {
66
+ export const PyTable = forwardRef(function PyTable({ data, loading: propsLoading, ...props }, ref) {
25
67
  const elRef = useRef(null);
68
+ const { loaded, error } = usePyComponent();
26
69
 
27
70
  useImperativeHandle(ref, () => ({
28
- getElement: () => elRef.current
71
+ getElement: () => elRef.current,
72
+ loaded,
73
+ error
29
74
  }));
30
75
 
31
76
  useEffect(() => {
32
- loadPyComponent();
33
- }, []);
34
-
35
- useEffect(() => {
36
- if (elRef.current && data) {
77
+ if (elRef.current && data && loaded) {
37
78
  elRef.current.setAttribute('table-data', JSON.stringify(data));
38
79
  }
39
- }, [data]);
80
+ }, [data, loaded]);
81
+
82
+ if (!loaded && propsLoading) {
83
+ return createElement('div', { style: { padding: '20px', textAlign: 'center' } }, propsLoading);
84
+ }
40
85
 
41
86
  return createElement('py-table', { ref: elRef, ...props });
42
87
  });
43
88
 
44
89
  // PyWeather React 包装组件
45
- export const PyWeather = forwardRef(function PyWeather(props, ref) {
90
+ export const PyWeather = forwardRef(function PyWeather({ loading: propsLoading, ...props }, ref) {
46
91
  const elRef = useRef(null);
92
+ const { loaded, error } = usePyComponent();
47
93
 
48
94
  useImperativeHandle(ref, () => ({
49
- getElement: () => elRef.current
95
+ getElement: () => elRef.current,
96
+ loaded,
97
+ error
50
98
  }));
51
99
 
52
- useEffect(() => {
53
- loadPyComponent();
54
- }, []);
100
+ if (!loaded && propsLoading) {
101
+ return createElement('div', { style: { padding: '20px', textAlign: 'center' } }, propsLoading);
102
+ }
55
103
 
56
104
  return createElement('py-weather', { ref: elRef, ...props });
57
105
  });
58
106
 
59
107
  // 初始化函数
60
108
  export function initPyComponent(config) {
61
- loadPyComponent().then((PyComponent) => {
62
- PyComponent.init(config);
109
+ return loadPyComponent().then((PyComponent) => {
110
+ if (PyComponent?.init) {
111
+ PyComponent.init(config);
112
+ }
113
+ return PyComponent;
63
114
  });
64
115
  }
65
116
 
@@ -67,3 +118,8 @@ export function initPyComponent(config) {
67
118
  export function getStore() {
68
119
  return typeof window !== 'undefined' ? window.PyComponent?.store : null;
69
120
  }
121
+
122
+ // 预加载函数
123
+ export function preloadPyComponent() {
124
+ return loadPyComponent();
125
+ }