@studio-kit/utils-browser 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/CHANGELOG.md +8 -0
- package/package.json +6 -3
- package/src/APP.js +159 -0
- package/src/DOM.js +100 -13
- package/src/Data.js +18 -2
- package/src/DateConfig.js +197 -0
- package/src/DateTime.js +2 -0
- package/src/Effect.js +4 -1
- package/src/EventBus.js +2 -0
- package/src/FIO.js +183 -3
- package/src/Geo.js +2 -0
- package/src/HTTP.js +20 -0
- package/src/Img.js +482 -0
- package/src/Message.js +7 -0
- package/src/Perf.js +3 -0
- package/src/Socket.js +263 -0
- package/src/Style.js +74 -3
- package/src/UserInput.js +0 -1
- package/src/cta.js +3 -2
- package/src/methods/dom.js +6 -10
- package/src/methods/loadLib.js +24 -2
- package/src/types/app.d.ts +67 -0
- package/src/vue2-plugin.js +2 -5
- package/src/methods/message.js +0 -5
package/src/Socket.js
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import ReconnectingWebSocket from 'reconnecting-websocket'
|
|
2
|
+
|
|
3
|
+
const WS_OPEN = 1
|
|
4
|
+
const WS_CLOSED = 3
|
|
5
|
+
const SEND_QUEUE_MAX = 50
|
|
6
|
+
|
|
7
|
+
export default class Socket {
|
|
8
|
+
static createClient({
|
|
9
|
+
url,
|
|
10
|
+
debug,
|
|
11
|
+
maxRetries = 10,
|
|
12
|
+
connectionTimeout = 1000,
|
|
13
|
+
eventMap = {},
|
|
14
|
+
parseMessage,
|
|
15
|
+
onOpen,
|
|
16
|
+
onClose,
|
|
17
|
+
onError,
|
|
18
|
+
} = {}) {
|
|
19
|
+
let closed = false
|
|
20
|
+
let ws = new ReconnectingWebSocket(url, null, {
|
|
21
|
+
connectionTimeout,
|
|
22
|
+
maxRetries,
|
|
23
|
+
debug,
|
|
24
|
+
})
|
|
25
|
+
const sendQueue = []
|
|
26
|
+
let openHandler = onOpen
|
|
27
|
+
let closeHandler = onClose
|
|
28
|
+
let errorHandler = onError
|
|
29
|
+
|
|
30
|
+
ws.onopen = () => {
|
|
31
|
+
if (closed) return
|
|
32
|
+
console.log('socket opened', url)
|
|
33
|
+
flushSendQueue()
|
|
34
|
+
openHandler?.()
|
|
35
|
+
}
|
|
36
|
+
ws.onclose = function () {
|
|
37
|
+
if (closed) return
|
|
38
|
+
console.log('socket closed', url)
|
|
39
|
+
closeHandler?.()
|
|
40
|
+
}
|
|
41
|
+
ws.onmessage = function (msg) {
|
|
42
|
+
dispatchMessage(msg)
|
|
43
|
+
}
|
|
44
|
+
ws.onerror = (err) => {
|
|
45
|
+
if (closed) return
|
|
46
|
+
if (debug !== false) console.error(err)
|
|
47
|
+
errorHandler?.(err)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const result = {
|
|
51
|
+
get url() {
|
|
52
|
+
return url
|
|
53
|
+
},
|
|
54
|
+
get readyState() {
|
|
55
|
+
if (closed || !ws) return WS_CLOSED
|
|
56
|
+
return ws.readyState
|
|
57
|
+
},
|
|
58
|
+
send({ data }) {
|
|
59
|
+
if (closed || !ws) {
|
|
60
|
+
console.warn('socket 已关闭,无法发送', url)
|
|
61
|
+
return result
|
|
62
|
+
}
|
|
63
|
+
const payload =
|
|
64
|
+
typeof data === 'object' && data !== null
|
|
65
|
+
? JSON.stringify(data)
|
|
66
|
+
: data
|
|
67
|
+
if (ws.readyState === WS_OPEN) {
|
|
68
|
+
ws.send(payload)
|
|
69
|
+
} else if (sendQueue.length >= SEND_QUEUE_MAX) {
|
|
70
|
+
console.warn('socket 发送队列已满,已丢弃消息', url)
|
|
71
|
+
} else {
|
|
72
|
+
sendQueue.push(payload)
|
|
73
|
+
}
|
|
74
|
+
return result
|
|
75
|
+
},
|
|
76
|
+
addEventListener({ messageKey, messageHandler }) {
|
|
77
|
+
if (closed) {
|
|
78
|
+
console.warn('socket 已关闭,无法监听', url)
|
|
79
|
+
return function unsubscribe() {}
|
|
80
|
+
}
|
|
81
|
+
assertHandler(messageHandler)
|
|
82
|
+
if (!eventMap[messageKey]) {
|
|
83
|
+
eventMap[messageKey] = []
|
|
84
|
+
}
|
|
85
|
+
if (!eventMap[messageKey].includes(messageHandler)) {
|
|
86
|
+
eventMap[messageKey].push(messageHandler)
|
|
87
|
+
}
|
|
88
|
+
return function unsubscribe() {
|
|
89
|
+
result.removeEventListener({ messageKey, messageHandler })
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
addEventListeners({ configs }) {
|
|
93
|
+
const list = configs || []
|
|
94
|
+
list.forEach((config) => {
|
|
95
|
+
result.addEventListener(config)
|
|
96
|
+
})
|
|
97
|
+
return function removeAll() {
|
|
98
|
+
list.forEach((config) => {
|
|
99
|
+
result.removeEventListener(config)
|
|
100
|
+
})
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
removeEventListener({ messageKey, messageHandler }) {
|
|
104
|
+
const handlers = eventMap[messageKey]
|
|
105
|
+
if (!handlers) return
|
|
106
|
+
const next = handlers.filter((fn) => fn !== messageHandler)
|
|
107
|
+
if (next.length) {
|
|
108
|
+
eventMap[messageKey] = next
|
|
109
|
+
} else {
|
|
110
|
+
delete eventMap[messageKey]
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
close() {
|
|
114
|
+
destroyClient()
|
|
115
|
+
},
|
|
116
|
+
destroy() {
|
|
117
|
+
destroyClient()
|
|
118
|
+
},
|
|
119
|
+
}
|
|
120
|
+
return result
|
|
121
|
+
|
|
122
|
+
function destroyClient() {
|
|
123
|
+
if (closed) return
|
|
124
|
+
closed = true
|
|
125
|
+
sendQueue.length = 0
|
|
126
|
+
Object.keys(eventMap).forEach((key) => {
|
|
127
|
+
delete eventMap[key]
|
|
128
|
+
})
|
|
129
|
+
openHandler = null
|
|
130
|
+
closeHandler = null
|
|
131
|
+
errorHandler = null
|
|
132
|
+
if (ws) {
|
|
133
|
+
ws.onopen = null
|
|
134
|
+
ws.onmessage = null
|
|
135
|
+
ws.onerror = null
|
|
136
|
+
ws.onclose = null
|
|
137
|
+
try {
|
|
138
|
+
ws.maxRetries = 0
|
|
139
|
+
ws.close()
|
|
140
|
+
} catch (_) {}
|
|
141
|
+
ws = null
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function flushSendQueue() {
|
|
146
|
+
if (closed || !ws) return
|
|
147
|
+
while (sendQueue.length && ws.readyState === WS_OPEN) {
|
|
148
|
+
ws.send(sendQueue.shift())
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function dispatchMessage(msg) {
|
|
153
|
+
if (closed) return
|
|
154
|
+
const { data } = msg
|
|
155
|
+
if (typeof data !== 'string') return
|
|
156
|
+
const raw = data.trim()
|
|
157
|
+
if (!raw.startsWith('{')) return
|
|
158
|
+
let parsed
|
|
159
|
+
try {
|
|
160
|
+
parsed = JSON.parse(raw)
|
|
161
|
+
} catch (err) {
|
|
162
|
+
console.error('socket JSON parse error', err)
|
|
163
|
+
return
|
|
164
|
+
}
|
|
165
|
+
const resolved = resolveMessage(parsed, raw)
|
|
166
|
+
if (!resolved) return
|
|
167
|
+
const { messageKey, body } = resolved
|
|
168
|
+
const handlers = eventMap[messageKey]
|
|
169
|
+
if (handlers?.length) {
|
|
170
|
+
handlers.slice().forEach((fn) => fn(body))
|
|
171
|
+
return
|
|
172
|
+
}
|
|
173
|
+
const fallback = eventMap['*']
|
|
174
|
+
if (fallback?.length) {
|
|
175
|
+
fallback.slice().forEach((fn) => fn(body))
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function resolveMessage(parsed, raw) {
|
|
180
|
+
if (typeof parseMessage === 'function') {
|
|
181
|
+
return parseMessage({ data: parsed, raw })
|
|
182
|
+
}
|
|
183
|
+
return {
|
|
184
|
+
messageKey: parsed.key ?? parsed.topic,
|
|
185
|
+
body: parsed.body ?? parsed.payload ?? parsed,
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
static create({ configs, isDev } = {}) {
|
|
191
|
+
const clientMap = {}
|
|
192
|
+
normalizeConfigs(configs).forEach((config) => {
|
|
193
|
+
const { key, devUrl, url } = config
|
|
194
|
+
const resolvedUrl = isDev && devUrl ? devUrl : url
|
|
195
|
+
if (!resolvedUrl) {
|
|
196
|
+
console.warn(`websocket 未配置 url,已跳过:${key}`)
|
|
197
|
+
return
|
|
198
|
+
}
|
|
199
|
+
clientMap[key] = Socket.createClient({
|
|
200
|
+
url: resolvedUrl,
|
|
201
|
+
debug: config.debug,
|
|
202
|
+
maxRetries: config.maxRetries,
|
|
203
|
+
connectionTimeout: config.connectionTimeout,
|
|
204
|
+
parseMessage: config.parseMessage,
|
|
205
|
+
onOpen: config.onOpen,
|
|
206
|
+
onClose: config.onClose,
|
|
207
|
+
onError: config.onError,
|
|
208
|
+
})
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
const hub = {
|
|
212
|
+
addEventListener({ socketKey, messageKey, messageHandler }) {
|
|
213
|
+
const client = getClient(socketKey)
|
|
214
|
+
return client.addEventListener({ messageKey, messageHandler })
|
|
215
|
+
},
|
|
216
|
+
removeEventListener({ socketKey, messageKey, messageHandler }) {
|
|
217
|
+
const client = getClient(socketKey)
|
|
218
|
+
client.removeEventListener({ messageKey, messageHandler })
|
|
219
|
+
},
|
|
220
|
+
send({ socketKey, data }) {
|
|
221
|
+
const client = getClient(socketKey)
|
|
222
|
+
return client.send({ data })
|
|
223
|
+
},
|
|
224
|
+
has({ socketKey }) {
|
|
225
|
+
return Boolean(clientMap[socketKey])
|
|
226
|
+
},
|
|
227
|
+
getClient({ socketKey }) {
|
|
228
|
+
return getClient(socketKey)
|
|
229
|
+
},
|
|
230
|
+
close({ socketKey }) {
|
|
231
|
+
const client = getClient(socketKey)
|
|
232
|
+
client.destroy()
|
|
233
|
+
delete clientMap[socketKey]
|
|
234
|
+
},
|
|
235
|
+
closeAll() {
|
|
236
|
+
Object.keys(clientMap).forEach((key) => {
|
|
237
|
+
clientMap[key].destroy()
|
|
238
|
+
delete clientMap[key]
|
|
239
|
+
})
|
|
240
|
+
},
|
|
241
|
+
}
|
|
242
|
+
return hub
|
|
243
|
+
|
|
244
|
+
function getClient(key) {
|
|
245
|
+
const client = clientMap[key]
|
|
246
|
+
if (!client) throw new Error(`对应 websocket client 不存在:${key}`)
|
|
247
|
+
return client
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function assertHandler(messageHandler) {
|
|
253
|
+
if (typeof messageHandler !== 'function') {
|
|
254
|
+
throw new TypeError('messageHandler 必须为函数')
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function normalizeConfigs(configs) {
|
|
259
|
+
if (!configs) return []
|
|
260
|
+
if (Array.isArray(configs)) return configs
|
|
261
|
+
if (typeof configs === 'object') return [configs]
|
|
262
|
+
return []
|
|
263
|
+
}
|
package/src/Style.js
CHANGED
|
@@ -1,12 +1,38 @@
|
|
|
1
1
|
import chroma from 'chroma-js';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import Data from './Data.js'
|
|
3
|
+
import CommonStyle from '@studio-kit/utils-common/Style.js'
|
|
4
|
+
export default class Style extends CommonStyle {
|
|
5
|
+
static getCssVar({ key, varKey }) {
|
|
6
|
+
if (!varKey) {
|
|
7
|
+
varKey = key
|
|
8
|
+
}
|
|
4
9
|
const root = document.documentElement;
|
|
5
10
|
const computedStyle = window.getComputedStyle(root);
|
|
6
11
|
// 获取CSS变量的值
|
|
7
12
|
const varValue = computedStyle.getPropertyValue(varKey);
|
|
8
13
|
return varValue
|
|
9
14
|
}
|
|
15
|
+
static setCssVar({ key, value }) {
|
|
16
|
+
// 获取:root元素(即document.documentElement)
|
|
17
|
+
const root = document.documentElement;
|
|
18
|
+
|
|
19
|
+
// 设置CSS变量
|
|
20
|
+
if (!/^\-\-/.test(key)) {
|
|
21
|
+
key = `--${key}`
|
|
22
|
+
}
|
|
23
|
+
root.style.setProperty(key, value);
|
|
24
|
+
}
|
|
25
|
+
static color(value) {
|
|
26
|
+
if (value) {
|
|
27
|
+
value = value.replace(/[\s\t\n]/g, '')
|
|
28
|
+
}
|
|
29
|
+
if (/^rgb/.test(value)) {
|
|
30
|
+
const numList = value.matchAll(/\d+/g)
|
|
31
|
+
value = [...numList];
|
|
32
|
+
console.log('value', value)
|
|
33
|
+
}
|
|
34
|
+
return chroma(value)
|
|
35
|
+
}
|
|
10
36
|
static getThemeImageFilter({ themeColor, imageColor = '#000000' }) {
|
|
11
37
|
const hue2 = this.createColor(themeColor).hsl()[0]
|
|
12
38
|
let hue1 = this.createColor(imageColor).hsl()[0]
|
|
@@ -18,4 +44,49 @@ export default class Style {
|
|
|
18
44
|
cssColorString = cssColorString.replace(/\s/g, '')
|
|
19
45
|
return chroma(cssColorString)
|
|
20
46
|
}
|
|
21
|
-
}
|
|
47
|
+
static setGlobalStyle({ cssText, id }) {
|
|
48
|
+
if (!id) {
|
|
49
|
+
id = 'style-' + Data.createId()
|
|
50
|
+
}
|
|
51
|
+
// 查找是否已存在相同id的style元素
|
|
52
|
+
let style = document.getElementById(id);
|
|
53
|
+
if (style) {
|
|
54
|
+
// 如果存在,直接替换内容
|
|
55
|
+
style.textContent = cssText;
|
|
56
|
+
} else {
|
|
57
|
+
// 如果不存在,创建新的style元素
|
|
58
|
+
style = document.createElement('style');
|
|
59
|
+
style.id = id;
|
|
60
|
+
style.textContent = cssText;
|
|
61
|
+
document.head.appendChild(style);
|
|
62
|
+
}
|
|
63
|
+
return style;
|
|
64
|
+
}
|
|
65
|
+
static getSize({ value }) {
|
|
66
|
+
if (Data.isNumberOrStringNumber(value)) {
|
|
67
|
+
return value + 'px'
|
|
68
|
+
} else {
|
|
69
|
+
return value
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
static measureText({ text, style, className }) {
|
|
73
|
+
const el = document.createElement('span')
|
|
74
|
+
el.textContent = text
|
|
75
|
+
el.style.position = 'absolute'
|
|
76
|
+
el.style.visibility = 'hidden'
|
|
77
|
+
el.style.whiteSpace = 'nowrap'
|
|
78
|
+
if (className) {
|
|
79
|
+
el.className = className
|
|
80
|
+
}
|
|
81
|
+
if (style) {
|
|
82
|
+
Object.assign(el.style, style)
|
|
83
|
+
}
|
|
84
|
+
document.body.appendChild(el)
|
|
85
|
+
const rect = el.getBoundingClientRect()
|
|
86
|
+
document.body.removeChild(el)
|
|
87
|
+
return {
|
|
88
|
+
width: rect.width,
|
|
89
|
+
height: rect.height
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
package/src/UserInput.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const defaultWindow = window
|
|
2
2
|
const useEventListener = (target, type, listener, options) => {
|
|
3
3
|
target = target || defaultWindow
|
|
4
|
-
console.log('target', target)
|
|
5
4
|
target.addEventListener(type, listener, options)
|
|
6
5
|
return () => target.removeEventListener(type, listener, options)
|
|
7
6
|
}
|
package/src/cta.js
CHANGED
|
@@ -138,7 +138,7 @@ function cta(trigger, target, options, callback) {
|
|
|
138
138
|
dummy.style.setProperty('position', (options.relativeToWindow ? 'fixed' : 'absolute'), 'important');
|
|
139
139
|
dummy.style.setProperty('-webkit-transform-origin', 'top left', 'important');
|
|
140
140
|
dummy.style.setProperty('transform-origin', 'top left', 'important');
|
|
141
|
-
dummy.style.setProperty('transition', options.duration + 's ease');
|
|
141
|
+
dummy.style.setProperty('transition', 'transform ' + options.duration + 's ease, background .3s ease-in');
|
|
142
142
|
|
|
143
143
|
// Set dummy element's dimensions to final state.
|
|
144
144
|
dummy.style.setProperty('width', targetBounds.width + 'px', 'important');
|
|
@@ -146,7 +146,8 @@ function cta(trigger, target, options, callback) {
|
|
|
146
146
|
dummy.style.setProperty('left', (targetBounds.left + (options.relativeToWindow ? 0 : window.pageXOffset)) + 'px', 'important');
|
|
147
147
|
dummy.style.setProperty('top', (targetBounds.top + (options.relativeToWindow ? 0 : window.pageYOffset)) + 'px', 'important');
|
|
148
148
|
dummy.style.setProperty('background', triggerBackground, 'important');
|
|
149
|
-
dummy.style.setProperty('z-index',
|
|
149
|
+
dummy.style.setProperty('z-index', 1e5, 'important');
|
|
150
|
+
dummy.style.setProperty('border-radius', getComputedStyle(trigger).borderRadius);
|
|
150
151
|
|
|
151
152
|
// Apply a reverse transform to bring back dummy element to the dimensions of the trigger/starting element.
|
|
152
153
|
// Credits: This technique is inspired by Paul Lewis: http://aerotwist.com/blog/flip-your-animations/ He is amazing!
|
package/src/methods/dom.js
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import DOM from '../DOM.js';
|
|
2
|
+
|
|
3
|
+
export function watchSizeChange(element, onChange, options) {
|
|
4
|
+
return DOM.watchSizeChange(element, onChange, options);
|
|
4
5
|
}
|
|
5
6
|
|
|
6
7
|
export function unwatchSizeChange(watcher, element) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (element) watcher.unobserve(element);
|
|
10
|
-
else watcher.disconnect();
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
}
|
|
8
|
+
return DOM.unwatchSizeChange(watcher, element);
|
|
9
|
+
}
|
package/src/methods/loadLib.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
const loadingMap = {};
|
|
2
2
|
const loadedMap = {};
|
|
3
3
|
export default function (src, key, type) {
|
|
4
|
-
if (key && window[key]) return Promise.resolve(window[
|
|
5
|
-
if (loadedMap[src]) return Promise.resolve();
|
|
4
|
+
if (key && window[key]) return Promise.resolve(window[key]);
|
|
6
5
|
if (loadingMap[src]) return loadingMap[src];
|
|
6
|
+
if (Object.prototype.hasOwnProperty.call(loadedMap, src)) {
|
|
7
|
+
const cached = loadedMap[src];
|
|
8
|
+
return Promise.resolve(cached === true ? undefined : cached);
|
|
9
|
+
}
|
|
7
10
|
if (/\.js$/.test(src) || type === 'js')
|
|
8
11
|
return loadingMap[src] = new Promise((resolve, reject) => {
|
|
9
12
|
const script = document.createElement('script');
|
|
@@ -38,4 +41,23 @@ export default function (src, key, type) {
|
|
|
38
41
|
document.head.appendChild(link);
|
|
39
42
|
});
|
|
40
43
|
}
|
|
44
|
+
if (/\.json$/.test(src) || type === 'json') {
|
|
45
|
+
return loadingMap[src] = fetch(src)
|
|
46
|
+
.then((res) => {
|
|
47
|
+
if (!res.ok) {
|
|
48
|
+
throw new Error(`加载json文件错误(src: ${src})(status: ${res.status})`);
|
|
49
|
+
}
|
|
50
|
+
return res.json();
|
|
51
|
+
})
|
|
52
|
+
.then((data) => {
|
|
53
|
+
delete loadingMap[src];
|
|
54
|
+
loadedMap[src] = data;
|
|
55
|
+
return data;
|
|
56
|
+
})
|
|
57
|
+
.catch((err) => {
|
|
58
|
+
delete loadingMap[src];
|
|
59
|
+
console.error(err);
|
|
60
|
+
throw err;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
41
63
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/** 标准弹窗相对触发元素或视口的位置 */
|
|
2
|
+
export type AppOpenStdWinPosition = 'center' | 'near-source';
|
|
3
|
+
|
|
4
|
+
/** 标准弹窗类型 */
|
|
5
|
+
export type AppOpenStdWinType = 'confirm';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Vue 内容组件:SFC 默认导出、全局组件名或懒加载函数。
|
|
9
|
+
* 未使用 `component` 时可改用 `pageKey`(运行时映射为 component)。
|
|
10
|
+
*/
|
|
11
|
+
export type AppOpenStdWinComponent =
|
|
12
|
+
| string
|
|
13
|
+
| Record<string, unknown>
|
|
14
|
+
| (() => Promise<unknown>);
|
|
15
|
+
|
|
16
|
+
/** 确认弹窗内组件实例($refs 上的窗口组件) */
|
|
17
|
+
export interface AppOpenStdWinConfirmComponent<TResult = unknown> {
|
|
18
|
+
getResult?: () => TResult;
|
|
19
|
+
data?: unknown;
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** `APP.openStdWin` 参数(经 $bus 传给 std-wins,`props` 会映射为 `componentProps`) */
|
|
24
|
+
export interface AppOpenStdWinParams<
|
|
25
|
+
TProps extends Record<string, unknown> = Record<string, unknown>,
|
|
26
|
+
TResult = unknown,
|
|
27
|
+
> {
|
|
28
|
+
/** 鼠标事件,用于 `near-source` 时取 `currentTarget` 作为锚点 */
|
|
29
|
+
mouseEvent?: MouseEvent;
|
|
30
|
+
/** 锚点元素;未传且提供 `mouseEvent` 时使用 `mouseEvent.currentTarget` */
|
|
31
|
+
sourceEl?: Element;
|
|
32
|
+
/** 窗口位置 */
|
|
33
|
+
position?: AppOpenStdWinPosition;
|
|
34
|
+
/** 窗口标题 */
|
|
35
|
+
title: string;
|
|
36
|
+
/** 宽度(px 数字或如 `'60%'` 的字符串) */
|
|
37
|
+
width?: number | string;
|
|
38
|
+
/** 高度 */
|
|
39
|
+
height?: number | string;
|
|
40
|
+
/** 内容组件 */
|
|
41
|
+
component?: AppOpenStdWinComponent;
|
|
42
|
+
/** 页面/全局组件 key,与 `component` 二选一 */
|
|
43
|
+
pageKey?: string;
|
|
44
|
+
/** 传给内容组件的 props */
|
|
45
|
+
props?: TProps;
|
|
46
|
+
/** 窗口类型 */
|
|
47
|
+
type?: AppOpenStdWinType;
|
|
48
|
+
/** 确定按钮文案 */
|
|
49
|
+
confirmText?: string;
|
|
50
|
+
/** 是否显示遮罩 */
|
|
51
|
+
hasMask?: boolean;
|
|
52
|
+
/** 窗口 id;已存在则 focus 而非新建 */
|
|
53
|
+
id?: string;
|
|
54
|
+
/** 确认回调;`close` 由调用方在逻辑结束后执行 */
|
|
55
|
+
afterConfirm?: (
|
|
56
|
+
compo: AppOpenStdWinConfirmComponent<TResult>,
|
|
57
|
+
close: () => void,
|
|
58
|
+
) => void | Promise<void>;
|
|
59
|
+
/** WinBox 挂载完成后的钩子 */
|
|
60
|
+
afterWinMounted?: (ctx: { winbox: unknown }) => void;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** @alias AppOpenStdWinParams */
|
|
64
|
+
export type StdAppOpenStdWinParams<
|
|
65
|
+
TProps extends Record<string, unknown> = Record<string, unknown>,
|
|
66
|
+
TResult = unknown,
|
|
67
|
+
> = AppOpenStdWinParams<TProps, TResult>;
|
package/src/vue2-plugin.js
CHANGED
|
@@ -7,10 +7,6 @@ import {
|
|
|
7
7
|
unwatchSizeChange,
|
|
8
8
|
} from './methods/dom'
|
|
9
9
|
|
|
10
|
-
import {
|
|
11
|
-
emitParentIframe
|
|
12
|
-
} from './methods/message'
|
|
13
|
-
|
|
14
10
|
import {
|
|
15
11
|
debounce
|
|
16
12
|
} from './methods/perfomance'
|
|
@@ -28,6 +24,7 @@ export default function (Vue, config = {}) {
|
|
|
28
24
|
debounce,
|
|
29
25
|
}
|
|
30
26
|
const { getUserInfo, clientType, isDev } = config
|
|
27
|
+
|
|
31
28
|
const $api = {
|
|
32
29
|
runtimeBaseURL: '/studio-server',
|
|
33
30
|
getUserInfo,
|
|
@@ -77,7 +74,7 @@ export default function (Vue, config = {}) {
|
|
|
77
74
|
})
|
|
78
75
|
}
|
|
79
76
|
})
|
|
80
|
-
Vue.prototype.$api = $api
|
|
77
|
+
Vue.prototype.$api = $api
|
|
81
78
|
Vue.prototype.$app = {
|
|
82
79
|
baseUrl: '/studio-server',
|
|
83
80
|
$compoPrefix: 'studio-',
|