py-test-components 1.0.0 → 1.0.2
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/CLAUDE.md +8 -0
- package/DEVELOPER.md +541 -0
- package/README.md +60 -214
- package/dist/py-component.esm.js +1 -1
- package/dist/py-component.esm.js.LICENSE.txt +0 -6
- package/dist/py-component.js +1 -1
- package/dist/py-component.js.LICENSE.txt +0 -6
- package/package.json +29 -42
- package/src/components/PyTable.vue +40 -280
- package/src/components/PyWeather.vue +48 -387
- package/src/index.js +20 -51
- package/src/react/index.js +60 -156
- package/src/store/index.js +17 -66
- package/src/utils/api.js +13 -101
- package/src/utils/request.js +10 -113
- package/src/vue/index.js +25 -32
- package/webpack.config.js +48 -0
- package//350/246/201/346/261/202.txt +17 -0
package/src/react/index.js
CHANGED
|
@@ -1,156 +1,60 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
// 加载组件库和 CSS
|
|
63
|
-
useEffect(() => {
|
|
64
|
-
injectElementUICSS();
|
|
65
|
-
|
|
66
|
-
// 动态加载组件库构建产物
|
|
67
|
-
import('../../dist/py-component.esm.js')
|
|
68
|
-
.then(() => {
|
|
69
|
-
setIsReady(true);
|
|
70
|
-
})
|
|
71
|
-
.catch(err => {
|
|
72
|
-
console.error(`[PyComponent] 加载失败:`, err);
|
|
73
|
-
});
|
|
74
|
-
}, []);
|
|
75
|
-
|
|
76
|
-
// 设置 propData 到 DOM property
|
|
77
|
-
useEffect(() => {
|
|
78
|
-
if (innerRef.current && isReady) {
|
|
79
|
-
innerRef.current[dataProp] = propData;
|
|
80
|
-
}
|
|
81
|
-
}, [propData, isReady, dataProp]);
|
|
82
|
-
|
|
83
|
-
// 绑定事件
|
|
84
|
-
useEffect(() => {
|
|
85
|
-
const el = innerRef.current;
|
|
86
|
-
if (!el || !isReady) return;
|
|
87
|
-
|
|
88
|
-
const events = {
|
|
89
|
-
'change': onChange,
|
|
90
|
-
'load': onLoad,
|
|
91
|
-
'error': onError,
|
|
92
|
-
'refresh': onRefresh,
|
|
93
|
-
'selection-change': onSelectionChange,
|
|
94
|
-
'edit': onEdit,
|
|
95
|
-
'delete': onDelete,
|
|
96
|
-
'size-change': onSizeChange,
|
|
97
|
-
'page-change': onPageChange
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
Object.entries(events).forEach(([eventName, handler]) => {
|
|
101
|
-
if (handler) {
|
|
102
|
-
el.addEventListener(eventName, handler);
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
return () => {
|
|
107
|
-
Object.entries(events).forEach(([eventName, handler]) => {
|
|
108
|
-
if (handler) {
|
|
109
|
-
el.removeEventListener(eventName, handler);
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
};
|
|
113
|
-
}, [isReady, onChange, onLoad, onError, onRefresh, onSelectionChange, onEdit, onDelete, onSizeChange, onPageChange]);
|
|
114
|
-
|
|
115
|
-
// 显示 loading 状态
|
|
116
|
-
if (!isReady) {
|
|
117
|
-
return loading || <div style={{ padding: 20, textAlign: 'center' }}>加载中...</div>;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return React.createElement(tagName, {
|
|
121
|
-
ref: innerRef,
|
|
122
|
-
...props
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// 创建组件
|
|
128
|
-
export const PyTable = wrapVueComponent('py-table', 'propData');
|
|
129
|
-
export const PyWeather = wrapVueComponent('py-weather', 'propData');
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* 初始化 Store
|
|
133
|
-
* @param {object} config - 配置对象
|
|
134
|
-
* @returns {Promise<void>}
|
|
135
|
-
*/
|
|
136
|
-
export function initStore(config) {
|
|
137
|
-
return new Promise((resolve, reject) => {
|
|
138
|
-
import('../../dist/py-component.esm.js')
|
|
139
|
-
.then((module) => {
|
|
140
|
-
const { initStore: init } = module;
|
|
141
|
-
if (init) {
|
|
142
|
-
init(config);
|
|
143
|
-
resolve();
|
|
144
|
-
} else {
|
|
145
|
-
reject(new Error('initStore 不存在'));
|
|
146
|
-
}
|
|
147
|
-
})
|
|
148
|
-
.catch(reject);
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export default {
|
|
153
|
-
PyTable,
|
|
154
|
-
PyWeather,
|
|
155
|
-
initStore
|
|
156
|
-
};
|
|
1
|
+
import { forwardRef, useEffect, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
const injected = { css: false };
|
|
4
|
+
|
|
5
|
+
function ensureCSS() {
|
|
6
|
+
if (injected.css) return;
|
|
7
|
+
const link = document.createElement('link');
|
|
8
|
+
link.rel = 'stylesheet';
|
|
9
|
+
link.href = 'https://unpkg.com/element-ui@2.15.14/lib/theme-chalk/index.css';
|
|
10
|
+
document.head.appendChild(link);
|
|
11
|
+
injected.css = true;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function wrapVueComponent(tagName) {
|
|
15
|
+
const Component = forwardRef(function WrappedComponent(
|
|
16
|
+
{ propData, loading, ...props },
|
|
17
|
+
ref
|
|
18
|
+
) {
|
|
19
|
+
const [mounted, setMounted] = useState(false);
|
|
20
|
+
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
ensureCSS();
|
|
23
|
+
setMounted(true);
|
|
24
|
+
}, []);
|
|
25
|
+
|
|
26
|
+
if (!mounted) {
|
|
27
|
+
return loading || null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const tag = document.createElement(tagName);
|
|
31
|
+
if (propData) {
|
|
32
|
+
tag.propData = propData;
|
|
33
|
+
}
|
|
34
|
+
Object.keys(props).forEach((key) => {
|
|
35
|
+
if (key.startsWith('on') && typeof props[key] === 'function') {
|
|
36
|
+
const eventName = key.slice(2).toLowerCase();
|
|
37
|
+
tag.addEventListener(eventName, props[key]);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
if (ref && typeof ref === 'object' && ref.current !== undefined) {
|
|
42
|
+
ref.current = tag;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return tag;
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
Component.displayName = tagName;
|
|
49
|
+
return Component;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const PyTable = wrapVueComponent('py-table');
|
|
53
|
+
export const PyWeather = wrapVueComponent('py-weather');
|
|
54
|
+
|
|
55
|
+
export async function initStore(config) {
|
|
56
|
+
if (typeof window !== 'undefined' && window.PyComponent?.initStore) {
|
|
57
|
+
window.PyComponent.initStore(config);
|
|
58
|
+
}
|
|
59
|
+
return Promise.resolve();
|
|
60
|
+
}
|
package/src/store/index.js
CHANGED
|
@@ -1,66 +1,17 @@
|
|
|
1
|
-
import Vue from 'vue';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
*/
|
|
19
|
-
get(key) {
|
|
20
|
-
return state[key];
|
|
21
|
-
},
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* 设置 store 中的值
|
|
25
|
-
* @param {string} key - 键名
|
|
26
|
-
* @param {any} value - 值
|
|
27
|
-
*/
|
|
28
|
-
set(key, value) {
|
|
29
|
-
state[key] = value;
|
|
30
|
-
},
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* 批量设置值
|
|
34
|
-
* @param {object} config - 配置对象
|
|
35
|
-
*/
|
|
36
|
-
setMultiple(config) {
|
|
37
|
-
Object.assign(state, config);
|
|
38
|
-
},
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* 订阅 store 变化(仅供内部使用)
|
|
42
|
-
* @param {function} callback - 回调函数
|
|
43
|
-
* @returns {function} 取消订阅函数
|
|
44
|
-
*/
|
|
45
|
-
subscribe(callback) {
|
|
46
|
-
// 使用 Vue watch 实现订阅
|
|
47
|
-
const unwatch = Vue.watch(
|
|
48
|
-
() => state,
|
|
49
|
-
(newVal, oldVal) => {
|
|
50
|
-
callback(newVal, oldVal);
|
|
51
|
-
},
|
|
52
|
-
{ deep: true }
|
|
53
|
-
);
|
|
54
|
-
return unwatch;
|
|
55
|
-
},
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* 获取整个 state(慎用,主要用于调试)
|
|
59
|
-
* @returns {object} state 对象
|
|
60
|
-
*/
|
|
61
|
-
getState() {
|
|
62
|
-
return state;
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
export default store;
|
|
1
|
+
import Vue from 'vue';
|
|
2
|
+
|
|
3
|
+
const state = Vue.observable({
|
|
4
|
+
apiKey: '',
|
|
5
|
+
baseUrl: '',
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
const store = {
|
|
9
|
+
get(key) {
|
|
10
|
+
return state[key];
|
|
11
|
+
},
|
|
12
|
+
set(key, value) {
|
|
13
|
+
state[key] = value;
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default store;
|
package/src/utils/api.js
CHANGED
|
@@ -1,101 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
return
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return store.get('apiKey') || '';
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// 构建带认证的请求头
|
|
18
|
-
function getAuthHeaders() {
|
|
19
|
-
const apiKey = getApiKey();
|
|
20
|
-
return apiKey ? { 'X-API-Key': apiKey } : {};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* 天气相关 API
|
|
25
|
-
*/
|
|
26
|
-
export const weatherApi = {
|
|
27
|
-
/**
|
|
28
|
-
* 获取天气信息
|
|
29
|
-
* @param {string} city - 城市名
|
|
30
|
-
* @returns {Promise} 天气数据
|
|
31
|
-
*/
|
|
32
|
-
getWeather(city) {
|
|
33
|
-
return get('/api/weather', { city }, {
|
|
34
|
-
baseURL: getBaseUrl(),
|
|
35
|
-
headers: getAuthHeaders()
|
|
36
|
-
});
|
|
37
|
-
},
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* 获取forecast
|
|
41
|
-
* @param {string} city - 城市名
|
|
42
|
-
* @returns {Promise} forecast数据
|
|
43
|
-
*/
|
|
44
|
-
getForecast(city) {
|
|
45
|
-
return get('/api/weather/forecast', { city }, {
|
|
46
|
-
baseURL: getBaseUrl(),
|
|
47
|
-
headers: getAuthHeaders()
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* 数据表格相关 API
|
|
54
|
-
*/
|
|
55
|
-
export const tableApi = {
|
|
56
|
-
/**
|
|
57
|
-
* 获取表格数据
|
|
58
|
-
* @param {object} params - 查询参数
|
|
59
|
-
* @returns {Promise} 表格数据
|
|
60
|
-
*/
|
|
61
|
-
getData(params = {}) {
|
|
62
|
-
return get('/api/table/data', params, {
|
|
63
|
-
baseURL: getBaseUrl(),
|
|
64
|
-
headers: getAuthHeaders()
|
|
65
|
-
});
|
|
66
|
-
},
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* 提交表格数据
|
|
70
|
-
* @param {object} data - 提交的数据
|
|
71
|
-
* @returns {Promise} 提交结果
|
|
72
|
-
*/
|
|
73
|
-
submitData(data) {
|
|
74
|
-
return post('/api/table/data', data, {
|
|
75
|
-
baseURL: getBaseUrl(),
|
|
76
|
-
headers: getAuthHeaders()
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* 用户相关 API
|
|
83
|
-
*/
|
|
84
|
-
export const userApi = {
|
|
85
|
-
/**
|
|
86
|
-
* 获取用户信息
|
|
87
|
-
* @returns {Promise} 用户数据
|
|
88
|
-
*/
|
|
89
|
-
getUserInfo() {
|
|
90
|
-
return get('/api/user/info', {}, {
|
|
91
|
-
baseURL: getBaseUrl(),
|
|
92
|
-
headers: getAuthHeaders()
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
export default {
|
|
98
|
-
weather: weatherApi,
|
|
99
|
-
table: tableApi,
|
|
100
|
-
user: userApi
|
|
101
|
-
};
|
|
1
|
+
import { post } from './request';
|
|
2
|
+
import store from '../store';
|
|
3
|
+
|
|
4
|
+
const DEFAULT_BASE_URL = 'https://api.example.com';
|
|
5
|
+
|
|
6
|
+
export function queryWeather(city) {
|
|
7
|
+
const baseUrl = store.get('baseUrl') || DEFAULT_BASE_URL;
|
|
8
|
+
const apiKey = store.get('apiKey');
|
|
9
|
+
return post(`${baseUrl}/weather/query`, {
|
|
10
|
+
city,
|
|
11
|
+
apiKey,
|
|
12
|
+
});
|
|
13
|
+
}
|
package/src/utils/request.js
CHANGED
|
@@ -1,113 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* 发起 HTTP 请求
|
|
16
|
-
* @param {string} url - 请求地址
|
|
17
|
-
* @param {object} options - 请求选项
|
|
18
|
-
* @returns {Promise} 响应结果
|
|
19
|
-
*/
|
|
20
|
-
export function request(url, options = {}) {
|
|
21
|
-
const config = {
|
|
22
|
-
...defaultConfig,
|
|
23
|
-
...options,
|
|
24
|
-
headers: {
|
|
25
|
-
...defaultConfig.headers,
|
|
26
|
-
...options.headers
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
// 处理 URL
|
|
31
|
-
const fullUrl = config.baseURL ? `${config.baseURL}${url}` : url;
|
|
32
|
-
|
|
33
|
-
// 创建 AbortController 用于超时控制
|
|
34
|
-
const controller = new AbortController();
|
|
35
|
-
const timeoutId = setTimeout(() => controller.abort(), config.timeout);
|
|
36
|
-
|
|
37
|
-
return fetch(fullUrl, {
|
|
38
|
-
...config,
|
|
39
|
-
signal: controller.signal
|
|
40
|
-
})
|
|
41
|
-
.then(response => {
|
|
42
|
-
clearTimeout(timeoutId);
|
|
43
|
-
|
|
44
|
-
if (!response.ok) {
|
|
45
|
-
throw new Error(`HTTP error! status: ${response.status}`);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// 根据返回类型解析数据
|
|
49
|
-
const contentType = response.headers.get('content-type');
|
|
50
|
-
if (contentType && contentType.includes('application/json')) {
|
|
51
|
-
return response.json();
|
|
52
|
-
}
|
|
53
|
-
return response.text();
|
|
54
|
-
})
|
|
55
|
-
.catch(error => {
|
|
56
|
-
clearTimeout(timeoutId);
|
|
57
|
-
|
|
58
|
-
if (error.name === 'AbortError') {
|
|
59
|
-
throw new Error('Request timeout');
|
|
60
|
-
}
|
|
61
|
-
throw error;
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* GET 请求
|
|
67
|
-
* @param {string} url - 请求地址
|
|
68
|
-
* @param {object} params - URL 参数
|
|
69
|
-
* @param {object} options - 其他选项
|
|
70
|
-
* @returns {Promise} 响应结果
|
|
71
|
-
*/
|
|
72
|
-
export function get(url, params = {}, options = {}) {
|
|
73
|
-
const queryString = Object.keys(params)
|
|
74
|
-
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
|
|
75
|
-
.join('&');
|
|
76
|
-
|
|
77
|
-
const fullUrl = queryString ? `${url}?${queryString}` : url;
|
|
78
|
-
|
|
79
|
-
return request(fullUrl, {
|
|
80
|
-
method: 'GET',
|
|
81
|
-
...options
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* POST 请求
|
|
87
|
-
* @param {string} url - 请求地址
|
|
88
|
-
* @param {object} data - 请求数据
|
|
89
|
-
* @param {object} options - 其他选项
|
|
90
|
-
* @returns {Promise} 响应结果
|
|
91
|
-
*/
|
|
92
|
-
export function post(url, data = {}, options = {}) {
|
|
93
|
-
return request(url, {
|
|
94
|
-
method: 'POST',
|
|
95
|
-
body: JSON.stringify(data),
|
|
96
|
-
...options
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* 设置默认配置
|
|
102
|
-
* @param {object} config - 配置对象
|
|
103
|
-
*/
|
|
104
|
-
export function setDefaultConfig(config) {
|
|
105
|
-
Object.assign(defaultConfig, config);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export default {
|
|
109
|
-
request,
|
|
110
|
-
get,
|
|
111
|
-
post,
|
|
112
|
-
setDefaultConfig
|
|
113
|
-
};
|
|
1
|
+
export function post(url, data, headers = {}) {
|
|
2
|
+
return fetch(url, {
|
|
3
|
+
method: 'POST',
|
|
4
|
+
headers: {
|
|
5
|
+
'Content-Type': 'application/json',
|
|
6
|
+
...headers,
|
|
7
|
+
},
|
|
8
|
+
body: JSON.stringify(data),
|
|
9
|
+
}).then((res) => res.json());
|
|
10
|
+
}
|
package/src/vue/index.js
CHANGED
|
@@ -1,32 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
function initStore(config) {
|
|
12
|
-
if (
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
// 默认导出
|
|
28
|
-
export default {
|
|
29
|
-
PyTable,
|
|
30
|
-
PyWeather,
|
|
31
|
-
initStore
|
|
32
|
-
};
|
|
1
|
+
import Vue from 'vue';
|
|
2
|
+
import ElementUI from 'element-ui';
|
|
3
|
+
import 'element-ui/lib/theme-chalk/index.css';
|
|
4
|
+
import store from '../store';
|
|
5
|
+
|
|
6
|
+
import PyTable from '../components/PyTable.vue';
|
|
7
|
+
import PyWeather from '../components/PyWeather.vue';
|
|
8
|
+
|
|
9
|
+
Vue.use(ElementUI);
|
|
10
|
+
|
|
11
|
+
function initStore(config) {
|
|
12
|
+
if (config) {
|
|
13
|
+
Object.keys(config).forEach((key) => {
|
|
14
|
+
store.set(key, config[key]);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export { PyTable, PyWeather, initStore };
|
|
20
|
+
|
|
21
|
+
export default {
|
|
22
|
+
PyTable,
|
|
23
|
+
PyWeather,
|
|
24
|
+
initStore,
|
|
25
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const { VueLoaderPlugin } = require('vue-loader');
|
|
3
|
+
|
|
4
|
+
const baseConfig = {
|
|
5
|
+
resolve: {
|
|
6
|
+
alias: {
|
|
7
|
+
'vue$': 'vue/dist/vue.esm.js',
|
|
8
|
+
},
|
|
9
|
+
},
|
|
10
|
+
module: {
|
|
11
|
+
rules: [
|
|
12
|
+
{ test: /\.vue$/, loader: 'vue-loader' },
|
|
13
|
+
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
|
|
14
|
+
],
|
|
15
|
+
},
|
|
16
|
+
plugins: [new VueLoaderPlugin()],
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// UMD build
|
|
20
|
+
const umdConfig = {
|
|
21
|
+
...baseConfig,
|
|
22
|
+
entry: './src/index.js',
|
|
23
|
+
output: {
|
|
24
|
+
filename: 'py-component.js',
|
|
25
|
+
path: path.resolve(__dirname, 'dist'),
|
|
26
|
+
library: 'PyComponent',
|
|
27
|
+
libraryTarget: 'umd',
|
|
28
|
+
globalObject: 'this',
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// ESM build
|
|
33
|
+
const esmConfig = {
|
|
34
|
+
...baseConfig,
|
|
35
|
+
entry: './src/index.js',
|
|
36
|
+
output: {
|
|
37
|
+
filename: 'py-component.esm.js',
|
|
38
|
+
path: path.resolve(__dirname, 'dist'),
|
|
39
|
+
library: {
|
|
40
|
+
type: 'module',
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
experiments: {
|
|
44
|
+
outputModule: true,
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
module.exports = [umdConfig, esmConfig];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
在当前文件夹下构建一个基于vue2+elementui的组件库,发布到npm仓库的名称为py-test-component
|
|
2
|
+
使用时,安装 nm install py-test-component
|
|
3
|
+
vue2工程可以使用该组件,通过import { PyTable, PyWeather, initStore } from 'py-test-component/vue';即可按需导入使用
|
|
4
|
+
react工程也能够使用该组件库,并且使用时不需要额外的适配成本(无需安装vue和elementUI),通过import { PyTable, PyWeather, initStore } from 'py-test-component/react';即可按需导入使用
|
|
5
|
+
每个组件都有一个
|
|
6
|
+
|
|
7
|
+
功能要求:
|
|
8
|
+
1、组件库包含两个组件:
|
|
9
|
+
一个表格展示组件PyTable(只有一个传入参数propData);
|
|
10
|
+
一个天气查询组件PyWheather(一个输入框输入城市、一个查询按钮发起查询、展示查询的天气情况)
|
|
11
|
+
2、创建一个request.js封装post方法,使得组件库能够自行发送请求不受外部工程影响,请求使用fetch实现
|
|
12
|
+
3、创建一个api.js,用来封装一些api请求,比如查询天气时的请求queryWheather,使用request.js里的post方法
|
|
13
|
+
4、组件库有自己的全局store机制,使用Vue.observable实现,只需要简单实现get和set方法,在组件内部可以随时访问,但是外部工程无法访问
|
|
14
|
+
5、在引用组件时暴露一个initStore()方法,外部工程可以传入一些参数,存储到组件库的全局store中
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
实现越简洁清晰越好,不要过度设计
|