shuidi.sharepublic.sdk 0.1.0
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/package.json +16 -0
- package/sharepublicsdk.js +160 -0
package/package.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "shuidi.sharepublic.sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "SDK for initializing shared public components into a container",
|
|
5
|
+
"main": "sharepublicsdk.js",
|
|
6
|
+
"browser": "sharepublicsdk.js",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"sharepublic",
|
|
9
|
+
"components",
|
|
10
|
+
"sdk",
|
|
11
|
+
"iframe"
|
|
12
|
+
],
|
|
13
|
+
"license": "MIT"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// SharePublic SDK
|
|
2
|
+
;(function (global) {
|
|
3
|
+
'use strict'
|
|
4
|
+
|
|
5
|
+
const BASE_URL = 'http://127.0.0.1:9001'
|
|
6
|
+
|
|
7
|
+
function init(options) {
|
|
8
|
+
const { containerId, componentId, token, props = {}, baseUrl = BASE_URL } = options || {}
|
|
9
|
+
|
|
10
|
+
if (!componentId) throw new Error('缺少 componentId')
|
|
11
|
+
|
|
12
|
+
const container = typeof containerId === 'string'
|
|
13
|
+
? document.getElementById(containerId)
|
|
14
|
+
: containerId
|
|
15
|
+
if (!container) throw new Error('找不到容器:' + containerId)
|
|
16
|
+
|
|
17
|
+
const url = baseUrl.replace(/\/+$/, '') + '/api/v1/components/' + componentId
|
|
18
|
+
|
|
19
|
+
return fetch(url)
|
|
20
|
+
.then(r => {
|
|
21
|
+
if (!r.ok) throw new Error('获取组件失败')
|
|
22
|
+
return r.json()
|
|
23
|
+
})
|
|
24
|
+
.then(component => {
|
|
25
|
+
if (component.component_type !== 'iframe' || !component.iframe_url) {
|
|
26
|
+
throw new Error('不支持的组件类型')
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// 将 props 编码成 URL 参数
|
|
30
|
+
const queryParams = []
|
|
31
|
+
|
|
32
|
+
// 处理 props,将对象和数组序列化为 JSON 字符串
|
|
33
|
+
if (props && typeof props === 'object') {
|
|
34
|
+
Object.keys(props).forEach(key => {
|
|
35
|
+
const value = props[key]
|
|
36
|
+
if (value !== undefined && value !== null) {
|
|
37
|
+
// 如果是对象或数组,序列化为 JSON 字符串
|
|
38
|
+
const encodedValue = typeof value === 'object'
|
|
39
|
+
? encodeURIComponent(JSON.stringify(value))
|
|
40
|
+
: encodeURIComponent(String(value))
|
|
41
|
+
queryParams.push(encodeURIComponent(key) + '=' + encodedValue)
|
|
42
|
+
}
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 添加 token
|
|
47
|
+
if (token) {
|
|
48
|
+
queryParams.push('token=' + encodeURIComponent(token))
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// 构建完整的 iframe URL
|
|
52
|
+
const qs = queryParams.join('&')
|
|
53
|
+
const separator = component.iframe_url.includes('?') ? '&' : '?'
|
|
54
|
+
const src = component.iframe_url + (qs ? separator + qs : '')
|
|
55
|
+
|
|
56
|
+
container.innerHTML = ''
|
|
57
|
+
const iframe = document.createElement('iframe')
|
|
58
|
+
iframe.src = src
|
|
59
|
+
iframe.width = '100%'
|
|
60
|
+
iframe.height = '100%'
|
|
61
|
+
iframe.style.border = 'none'
|
|
62
|
+
iframe.setAttribute('frameborder', '0')
|
|
63
|
+
container.appendChild(iframe)
|
|
64
|
+
|
|
65
|
+
// 创建组件实例对象,提供调用方法的功能
|
|
66
|
+
const componentInstance = {
|
|
67
|
+
iframe: iframe,
|
|
68
|
+
componentId: componentId,
|
|
69
|
+
methods: component.methods || {},
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* 调用组件的公共方法
|
|
73
|
+
* @param {string} methodName - 方法名
|
|
74
|
+
* @param {object} params - 方法参数对象
|
|
75
|
+
* @returns {Promise} - 返回 Promise,如果组件有响应则 resolve
|
|
76
|
+
*/
|
|
77
|
+
callMethod: function(methodName, params = {}) {
|
|
78
|
+
if (!methodName || typeof methodName !== 'string') {
|
|
79
|
+
return Promise.reject(new Error('方法名必须是字符串'))
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// 检查方法是否存在
|
|
83
|
+
if (!this.methods[methodName]) {
|
|
84
|
+
return Promise.reject(new Error(`方法 "${methodName}" 不存在`))
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// 通过 postMessage 向 iframe 发送消息
|
|
88
|
+
const message = {
|
|
89
|
+
type: 'callMethod',
|
|
90
|
+
method: methodName,
|
|
91
|
+
params: params
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// 发送消息到 iframe
|
|
95
|
+
if (iframe.contentWindow) {
|
|
96
|
+
iframe.contentWindow.postMessage(message, '*')
|
|
97
|
+
|
|
98
|
+
// 返回 Promise,可以用于处理响应(如果组件有响应的话)
|
|
99
|
+
return Promise.resolve({
|
|
100
|
+
method: methodName,
|
|
101
|
+
params: params,
|
|
102
|
+
sent: true
|
|
103
|
+
})
|
|
104
|
+
} else {
|
|
105
|
+
return Promise.reject(new Error('iframe 尚未加载完成'))
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* 监听来自组件的消息(事件)
|
|
111
|
+
* @param {string} eventName - 事件名
|
|
112
|
+
* @param {function} callback - 回调函数
|
|
113
|
+
*/
|
|
114
|
+
on: function(eventName, callback) {
|
|
115
|
+
if (typeof callback !== 'function') {
|
|
116
|
+
throw new Error('回调函数必须是函数')
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const messageHandler = (event) => {
|
|
120
|
+
// 验证消息来源(可选,根据实际需求调整)
|
|
121
|
+
if (event.data && event.data.type === 'event' && event.data.event === eventName) {
|
|
122
|
+
callback(event.data.params || {})
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
window.addEventListener('message', messageHandler)
|
|
127
|
+
|
|
128
|
+
// 返回取消监听的函数
|
|
129
|
+
return () => {
|
|
130
|
+
window.removeEventListener('message', messageHandler)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// 等待 iframe 加载完成后返回组件实例
|
|
136
|
+
return new Promise((resolve, reject) => {
|
|
137
|
+
iframe.onload = () => {
|
|
138
|
+
resolve(componentInstance)
|
|
139
|
+
}
|
|
140
|
+
iframe.onerror = () => {
|
|
141
|
+
reject(new Error('iframe 加载失败'))
|
|
142
|
+
}
|
|
143
|
+
// 如果 iframe 已经加载完成
|
|
144
|
+
if (iframe.contentDocument && iframe.contentDocument.readyState === 'complete') {
|
|
145
|
+
resolve(componentInstance)
|
|
146
|
+
}
|
|
147
|
+
})
|
|
148
|
+
})
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const api = { init }
|
|
152
|
+
|
|
153
|
+
if (typeof module !== 'undefined' && module.exports) {
|
|
154
|
+
module.exports = api
|
|
155
|
+
} else if (typeof define === 'function' && define.amd) {
|
|
156
|
+
define([], () => api)
|
|
157
|
+
} else {
|
|
158
|
+
global.SharePublicSDK = api
|
|
159
|
+
}
|
|
160
|
+
})(typeof window !== 'undefined' ? window : this)
|