py-test-component 1.0.1 → 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 ADDED
@@ -0,0 +1,80 @@
1
+ // ============================================
2
+ // py-test-component - TypeScript 类型定义
3
+ // ============================================
4
+
5
+ declare module 'py-test-component' {
6
+ export interface PyComponentStore {
7
+ set(config: Record<string, any>): void;
8
+ get(key?: string): any;
9
+ }
10
+
11
+ export const store: PyComponentStore;
12
+ export function init(config?: Record<string, any>): void;
13
+
14
+ const _default: {
15
+ init: typeof init;
16
+ store: PyComponentStore;
17
+ };
18
+ export default _default;
19
+ }
20
+
21
+ declare module 'py-test-component/vue' {
22
+ import { Component } from 'vue';
23
+
24
+ /** 表格组件 - Vue 版本 */
25
+ export const PyTable: Component;
26
+ /** 天气组件 - Vue 版本 */
27
+ export const PyWeather: Component;
28
+
29
+ const _default: {
30
+ PyTable: typeof PyTable;
31
+ PyWeather: typeof PyWeather;
32
+ };
33
+ export default _default;
34
+ }
35
+
36
+ declare module 'py-test-component/react' {
37
+ import { ReactNode, Ref, ForwardRefExoticComponent, RefAttributes } from 'react';
38
+
39
+ export interface PyTableProps {
40
+ /** 表格数据 */
41
+ data?: Record<string, any>[];
42
+ /** 加载中的占位内容 */
43
+ loading?: ReactNode;
44
+ /** 其他 HTML 属性 */
45
+ [key: string]: any;
46
+ }
47
+
48
+ export interface PyWeatherProps {
49
+ /** 城市名称 */
50
+ city?: string;
51
+ /** 加载中的占位内容 */
52
+ loading?: ReactNode;
53
+ /** 其他 HTML 属性 */
54
+ [key: string]: any;
55
+ }
56
+
57
+ export interface PyComponentRef {
58
+ /** 获取 DOM 元素 */
59
+ getElement: () => HTMLElement | null;
60
+ /** 是否已加载完成 */
61
+ loaded: boolean;
62
+ /** 加载错误信息 */
63
+ error: Error | null;
64
+ }
65
+
66
+ /** 表格组件 - React 版本 */
67
+ export const PyTable: ForwardRefExoticComponent<PyTableProps & RefAttributes<PyComponentRef>>;
68
+
69
+ /** 天气组件 - React 版本 */
70
+ export const PyWeather: ForwardRefExoticComponent<PyWeatherProps & RefAttributes<PyComponentRef>>;
71
+
72
+ /** 初始化组件库 */
73
+ export function initPyComponent(config?: Record<string, any>): Promise<any>;
74
+
75
+ /** 获取全局 store */
76
+ export function getStore(): Record<string, any> | null;
77
+
78
+ /** 预加载组件库(可提前调用以加速渲染) */
79
+ export function preloadPyComponent(): Promise<any>;
80
+ }
package/package.json CHANGED
@@ -1,16 +1,32 @@
1
1
  {
2
2
  "name": "py-test-component",
3
- "version": "1.0.1",
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
+ "types": "index.d.ts",
7
8
  "exports": {
8
- ".": "./dist/py-component.js",
9
- "./react": "./src/react/index.js"
9
+ ".": {
10
+ "types": "./index.d.ts",
11
+ "import": "./dist/py-component.esm.js",
12
+ "require": "./dist/py-component.js"
13
+ },
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
+ }
10
24
  },
11
25
  "files": [
12
26
  "dist",
13
- "src/react"
27
+ "src/react",
28
+ "src/vue",
29
+ "index.d.ts"
14
30
  ],
15
31
  "scripts": {
16
32
  "build": "webpack --mode production",
@@ -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
+ }
@@ -0,0 +1,6 @@
1
+ // Vue 项目专用入口 - 直接导出 Vue 组件
2
+ import PyTable from '../components/PyTable.vue';
3
+ import PyWeather from '../components/PyWeather.vue';
4
+
5
+ export { PyTable, PyWeather };
6
+ export default { PyTable, PyWeather };