wui-components-v2 1.0.13 → 1.0.14
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/api/core/index.ts +74 -0
- package/api/index.ts +2 -13
- package/api/login.ts +51 -0
- package/api/menu.ts +7 -0
- package/components/demo-block/demo-block.vue +66 -0
- package/components/global-loading/GlobalLoading.md +366 -0
- package/components/global-loading/global-loading.vue +55 -0
- package/components/global-message/GlobalMessage.md +570 -0
- package/components/global-message/global-message.vue +64 -0
- package/components/global-toast/GlobalToast.md +261 -0
- package/components/global-toast/global-toast.vue +56 -0
- package/components/login/login.vue +22 -0
- package/components/login-form/login-form.vue +106 -0
- package/components/menus/menus.vue +180 -0
- package/components/privacy-popup/privacy-popup.vue +178 -0
- package/components/{system-settings.vue → system-settings/system-settings.vue} +3 -2
- package/composables/types/user.ts +5 -0
- package/composables/useGlobalLoading.ts +46 -0
- package/composables/useGlobalMessage.ts +54 -0
- package/composables/useGlobalToast.ts +62 -0
- package/composables/useTheme.ts +1 -1
- package/composables/useUser.ts +21 -0
- package/index.ts +3 -2
- package/package.json +6 -1
- package/store/userStore.ts +22 -0
- package/utils/index.ts +9 -0
- package/utils/rsaEncrypt.ts +10 -0
- package/api/core/handlers.ts +0 -106
- package/api/core/instance.ts +0 -60
- package/api/core/middleware.ts +0 -92
|
@@ -0,0 +1,570 @@
|
|
|
1
|
+
# GlobalMessage 全局弹窗组件
|
|
2
|
+
|
|
3
|
+
## 概述
|
|
4
|
+
|
|
5
|
+
GlobalMessage 是基于 `wot-design-uni` 的 `wd-message-box` 组件封装的全局弹窗组件,通过 Pinia 状态管理实现全局调用,用于显示提醒、确认、输入等交互场景。
|
|
6
|
+
|
|
7
|
+
## 组件特性
|
|
8
|
+
|
|
9
|
+
- 基于 `wd-message-box` 组件封装
|
|
10
|
+
- 支持提醒(alert)、确认(confirm)、输入(prompt)三种类型
|
|
11
|
+
- 支持成功/失败回调处理
|
|
12
|
+
- 自动页面路径检测,确保在正确页面显示
|
|
13
|
+
- 虚拟节点设计,不在 DOM 中创建额外层级
|
|
14
|
+
- 支持 Promise 链式调用
|
|
15
|
+
|
|
16
|
+
## 安装使用
|
|
17
|
+
|
|
18
|
+
### 1. 注册全局组件
|
|
19
|
+
|
|
20
|
+
在 `App.vue` 或根组件中注册:
|
|
21
|
+
|
|
22
|
+
```vue
|
|
23
|
+
<template>
|
|
24
|
+
<div>
|
|
25
|
+
<!-- 其他内容 -->
|
|
26
|
+
<GlobalMessage />
|
|
27
|
+
</div>
|
|
28
|
+
</template>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 2. 在组件中使用
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import { useGlobalMessage } from '@/composables/useGlobalMessage'
|
|
35
|
+
|
|
36
|
+
const message = useGlobalMessage()
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## API 文档
|
|
40
|
+
|
|
41
|
+
### 基础用法
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
// 通用弹窗
|
|
45
|
+
message.show({
|
|
46
|
+
title: '提示',
|
|
47
|
+
message: '这是一条消息'
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
// 字符串参数
|
|
51
|
+
message.show('简单提示')
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 方法说明
|
|
55
|
+
|
|
56
|
+
#### show(option)
|
|
57
|
+
显示通用弹窗
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
message.show({
|
|
61
|
+
title: '标题',
|
|
62
|
+
message: '内容',
|
|
63
|
+
success: res => console.log('成功', res),
|
|
64
|
+
fail: res => console.log('失败', res)
|
|
65
|
+
})
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
#### alert(option)
|
|
69
|
+
显示提醒弹窗(只有确认按钮)
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
// 简单提醒
|
|
73
|
+
message.alert('操作完成')
|
|
74
|
+
|
|
75
|
+
// 详细配置
|
|
76
|
+
message.alert({
|
|
77
|
+
title: '提醒',
|
|
78
|
+
message: '请注意查看结果',
|
|
79
|
+
success: (res) => {
|
|
80
|
+
console.log('用户确认了')
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
#### confirm(option)
|
|
86
|
+
显示确认弹窗(有确认和取消按钮)
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
// 简单确认
|
|
90
|
+
message.confirm('确定要删除吗?')
|
|
91
|
+
|
|
92
|
+
// 详细配置
|
|
93
|
+
message.confirm({
|
|
94
|
+
title: '确认删除',
|
|
95
|
+
message: '删除后不可恢复,确定要删除吗?',
|
|
96
|
+
success: (res) => {
|
|
97
|
+
if (res.action === 'confirm') {
|
|
98
|
+
console.log('用户确认删除')
|
|
99
|
+
// 执行删除操作
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
fail: (res) => {
|
|
103
|
+
console.log('用户取消删除')
|
|
104
|
+
}
|
|
105
|
+
})
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
#### prompt(option)
|
|
109
|
+
显示输入弹窗(有输入框和确认取消按钮)
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
// 简单输入
|
|
113
|
+
message.prompt('请输入您的姓名')
|
|
114
|
+
|
|
115
|
+
// 详细配置
|
|
116
|
+
message.prompt({
|
|
117
|
+
title: '输入信息',
|
|
118
|
+
message: '请输入新的名称',
|
|
119
|
+
inputValue: '默认值',
|
|
120
|
+
inputPlaceholder: '请输入内容',
|
|
121
|
+
success: (res) => {
|
|
122
|
+
if (res.action === 'confirm') {
|
|
123
|
+
console.log('用户输入:', res.value)
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
fail: (res) => {
|
|
127
|
+
console.log('用户取消输入')
|
|
128
|
+
}
|
|
129
|
+
})
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
#### close()
|
|
133
|
+
手动关闭弹窗
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
message.close()
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## 参数说明
|
|
140
|
+
|
|
141
|
+
### GlobalMessageOptions
|
|
142
|
+
|
|
143
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
144
|
+
|------|------|--------|------|
|
|
145
|
+
| title | string | - | 弹窗标题 |
|
|
146
|
+
| message | string | - | 弹窗内容 |
|
|
147
|
+
| type | string | - | 弹窗类型:'alert' \| 'confirm' \| 'prompt' |
|
|
148
|
+
| showCancelButton | boolean | - | 是否显示取消按钮(自动设置) |
|
|
149
|
+
| inputValue | string | - | 输入框默认值(prompt类型) |
|
|
150
|
+
| inputPlaceholder | string | - | 输入框占位符(prompt类型) |
|
|
151
|
+
| success | Function | - | 成功回调函数 |
|
|
152
|
+
| fail | Function | - | 失败回调函数 |
|
|
153
|
+
| confirmButtonText | string | '确定' | 确认按钮文本 |
|
|
154
|
+
| cancelButtonText | string | '取消' | 取消按钮文本 |
|
|
155
|
+
|
|
156
|
+
### MessageResult
|
|
157
|
+
|
|
158
|
+
回调函数接收的参数对象:
|
|
159
|
+
|
|
160
|
+
| 参数 | 类型 | 说明 |
|
|
161
|
+
|------|------|------|
|
|
162
|
+
| action | string | 用户操作:'confirm' \| 'cancel' |
|
|
163
|
+
| value | string | 输入框的值(仅prompt类型) |
|
|
164
|
+
|
|
165
|
+
### 方法参数
|
|
166
|
+
|
|
167
|
+
所有方法都支持两种参数类型:
|
|
168
|
+
|
|
169
|
+
1. **字符串参数**:直接传入标题文本
|
|
170
|
+
2. **选项对象**:传入完整的 GlobalMessageOptions 配置
|
|
171
|
+
|
|
172
|
+
## 使用示例
|
|
173
|
+
|
|
174
|
+
### 基础示例
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
export default {
|
|
178
|
+
setup() {
|
|
179
|
+
const message = useGlobalMessage()
|
|
180
|
+
|
|
181
|
+
const showAlert = () => {
|
|
182
|
+
message.alert('这是一个提醒')
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const showConfirm = () => {
|
|
186
|
+
message.confirm({
|
|
187
|
+
title: '确认操作',
|
|
188
|
+
message: '确定要继续吗?',
|
|
189
|
+
success: (res) => {
|
|
190
|
+
if (res.action === 'confirm') {
|
|
191
|
+
console.log('用户确认')
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
})
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const showPrompt = () => {
|
|
198
|
+
message.prompt({
|
|
199
|
+
title: '输入信息',
|
|
200
|
+
message: '请输入您的姓名',
|
|
201
|
+
success: (res) => {
|
|
202
|
+
if (res.action === 'confirm') {
|
|
203
|
+
console.log('用户输入:', res.value)
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
})
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return {
|
|
210
|
+
showAlert,
|
|
211
|
+
showConfirm,
|
|
212
|
+
showPrompt
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### 删除确认示例
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
function handleDelete(item) {
|
|
222
|
+
message.confirm({
|
|
223
|
+
title: '确认删除',
|
|
224
|
+
message: `确定要删除"${item.name}"吗?删除后不可恢复。`,
|
|
225
|
+
success: async (res) => {
|
|
226
|
+
if (res.action === 'confirm') {
|
|
227
|
+
try {
|
|
228
|
+
await deleteItem(item.id)
|
|
229
|
+
toast.success('删除成功')
|
|
230
|
+
// 刷新列表
|
|
231
|
+
await fetchList()
|
|
232
|
+
}
|
|
233
|
+
catch (error) {
|
|
234
|
+
toast.error(`删除失败:${error.message}`)
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
})
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### 批量操作示例
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
function handleBatchDelete(selectedItems) {
|
|
246
|
+
message.confirm({
|
|
247
|
+
title: '批量删除',
|
|
248
|
+
message: `确定要删除选中的 ${selectedItems.length} 个项目吗?`,
|
|
249
|
+
success: async (res) => {
|
|
250
|
+
if (res.action === 'confirm') {
|
|
251
|
+
const loading = useGlobalLoading()
|
|
252
|
+
|
|
253
|
+
try {
|
|
254
|
+
loading.loading('删除中...')
|
|
255
|
+
await batchDeleteItems(selectedItems.map(item => item.id))
|
|
256
|
+
toast.success('批量删除成功')
|
|
257
|
+
await fetchList()
|
|
258
|
+
}
|
|
259
|
+
catch (error) {
|
|
260
|
+
toast.error('批量删除失败')
|
|
261
|
+
}
|
|
262
|
+
finally {
|
|
263
|
+
loading.close()
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
})
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### 表单验证示例
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
function handleSubmit() {
|
|
275
|
+
// 表单验证失败时的提醒
|
|
276
|
+
if (!formData.name) {
|
|
277
|
+
message.alert({
|
|
278
|
+
title: '验证失败',
|
|
279
|
+
message: '请输入姓名后再提交',
|
|
280
|
+
success: () => {
|
|
281
|
+
// 聚焦到输入框
|
|
282
|
+
document.getElementById('name-input').focus()
|
|
283
|
+
}
|
|
284
|
+
})
|
|
285
|
+
return
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// 提交前确认
|
|
289
|
+
message.confirm({
|
|
290
|
+
title: '确认提交',
|
|
291
|
+
message: '确定要提交表单吗?',
|
|
292
|
+
success: async (res) => {
|
|
293
|
+
if (res.action === 'confirm') {
|
|
294
|
+
await submitForm(formData)
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
})
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### 修改名称示例
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
function handleEditName(item) {
|
|
305
|
+
message.prompt({
|
|
306
|
+
title: '修改名称',
|
|
307
|
+
message: '请输入新的名称',
|
|
308
|
+
inputValue: item.name,
|
|
309
|
+
inputPlaceholder: '请输入名称',
|
|
310
|
+
success: async (res) => {
|
|
311
|
+
if (res.action === 'confirm') {
|
|
312
|
+
const newName = res.value.trim()
|
|
313
|
+
|
|
314
|
+
if (!newName) {
|
|
315
|
+
toast.error('名称不能为空')
|
|
316
|
+
return
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
if (newName === item.name) {
|
|
320
|
+
toast.info('名称未改变')
|
|
321
|
+
return
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
try {
|
|
325
|
+
await updateItemName(item.id, newName)
|
|
326
|
+
toast.success('修改成功')
|
|
327
|
+
item.name = newName
|
|
328
|
+
}
|
|
329
|
+
catch (error) {
|
|
330
|
+
toast.error(`修改失败:${error.message}`)
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
})
|
|
335
|
+
}
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### 退出登录示例
|
|
339
|
+
|
|
340
|
+
```typescript
|
|
341
|
+
function handleLogout() {
|
|
342
|
+
message.confirm({
|
|
343
|
+
title: '退出登录',
|
|
344
|
+
message: '确定要退出当前账号吗?',
|
|
345
|
+
confirmButtonText: '退出',
|
|
346
|
+
cancelButtonText: '取消',
|
|
347
|
+
success: async (res) => {
|
|
348
|
+
if (res.action === 'confirm') {
|
|
349
|
+
try {
|
|
350
|
+
await logout()
|
|
351
|
+
// 清除本地数据
|
|
352
|
+
clearUserData()
|
|
353
|
+
// 跳转到登录页
|
|
354
|
+
router.push('/login')
|
|
355
|
+
}
|
|
356
|
+
catch (error) {
|
|
357
|
+
toast.error('退出失败')
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
})
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### 复杂交互示例
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
function handleComplexOperation() {
|
|
369
|
+
// 第一步:确认是否继续
|
|
370
|
+
message.confirm({
|
|
371
|
+
title: '操作确认',
|
|
372
|
+
message: '此操作需要多个步骤,确定要继续吗?',
|
|
373
|
+
success: (res) => {
|
|
374
|
+
if (res.action === 'confirm') {
|
|
375
|
+
// 第二步:输入验证码
|
|
376
|
+
message.prompt({
|
|
377
|
+
title: '安全验证',
|
|
378
|
+
message: '请输入验证码',
|
|
379
|
+
inputPlaceholder: '请输入6位验证码',
|
|
380
|
+
success: async (res) => {
|
|
381
|
+
if (res.action === 'confirm') {
|
|
382
|
+
const code = res.value
|
|
383
|
+
|
|
384
|
+
if (!/^\d{6}$/.test(code)) {
|
|
385
|
+
message.alert({
|
|
386
|
+
title: '验证失败',
|
|
387
|
+
message: '请输入6位数字验证码',
|
|
388
|
+
success: () => {
|
|
389
|
+
// 重新输入
|
|
390
|
+
handleComplexOperation()
|
|
391
|
+
}
|
|
392
|
+
})
|
|
393
|
+
return
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// 第三步:最终确认
|
|
397
|
+
message.confirm({
|
|
398
|
+
title: '最终确认',
|
|
399
|
+
message: '验证通过,确定要执行操作吗?',
|
|
400
|
+
success: async (res) => {
|
|
401
|
+
if (res.action === 'confirm') {
|
|
402
|
+
try {
|
|
403
|
+
await executeComplexOperation(code)
|
|
404
|
+
toast.success('操作成功')
|
|
405
|
+
}
|
|
406
|
+
catch (error) {
|
|
407
|
+
toast.error(`操作失败:${error.message}`)
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
})
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
})
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
})
|
|
418
|
+
}
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
## 实现原理
|
|
422
|
+
|
|
423
|
+
### 状态管理
|
|
424
|
+
- 使用 Pinia 管理全局状态
|
|
425
|
+
- 状态包含:`messageOptions`(弹窗配置)、`currentPage`(当前页面路径)
|
|
426
|
+
|
|
427
|
+
### 页面检测机制
|
|
428
|
+
- 调用弹窗方法时记录当前页面路径
|
|
429
|
+
- 组件监听状态变化时验证页面路径
|
|
430
|
+
- 确保弹窗在正确的页面显示
|
|
431
|
+
|
|
432
|
+
### Promise 处理
|
|
433
|
+
- 使用 `wd-message-box` 的 Promise 接口
|
|
434
|
+
- 自动处理成功和失败回调
|
|
435
|
+
- 支持链式调用
|
|
436
|
+
|
|
437
|
+
### 组件配置
|
|
438
|
+
```typescript
|
|
439
|
+
export default {
|
|
440
|
+
options: {
|
|
441
|
+
virtualHost: true, // 虚拟节点
|
|
442
|
+
addGlobalClass: true, // 支持全局样式
|
|
443
|
+
styleIsolation: 'shared' // 样式隔离共享
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
## 最佳实践
|
|
449
|
+
|
|
450
|
+
1. **合理选择弹窗类型**
|
|
451
|
+
```typescript
|
|
452
|
+
// ✅ 根据场景选择
|
|
453
|
+
message.alert('操作完成') // 仅通知
|
|
454
|
+
message.confirm('确定删除?') // 需要确认
|
|
455
|
+
message.prompt('输入名称') // 需要输入
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
2. **提供清晰的标题和内容**
|
|
459
|
+
```typescript
|
|
460
|
+
// ✅ 清晰明确
|
|
461
|
+
message.confirm({
|
|
462
|
+
title: '删除确认',
|
|
463
|
+
message: '确定要删除这个文件吗?删除后无法恢复。'
|
|
464
|
+
})
|
|
465
|
+
|
|
466
|
+
// ❌ 模糊不清
|
|
467
|
+
message.confirm('确定吗?')
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
3. **正确处理回调**
|
|
471
|
+
```typescript
|
|
472
|
+
// ✅ 完整的回调处理
|
|
473
|
+
message.confirm({
|
|
474
|
+
title: '确认操作',
|
|
475
|
+
message: '确定要继续吗?',
|
|
476
|
+
success: (res) => {
|
|
477
|
+
if (res.action === 'confirm') {
|
|
478
|
+
// 处理确认
|
|
479
|
+
}
|
|
480
|
+
},
|
|
481
|
+
fail: (res) => {
|
|
482
|
+
if (res.action === 'cancel') {
|
|
483
|
+
// 处理取消
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
})
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
4. **输入验证**
|
|
490
|
+
```typescript
|
|
491
|
+
// ✅ 验证输入内容
|
|
492
|
+
message.prompt({
|
|
493
|
+
title: '输入信息',
|
|
494
|
+
success: (res) => {
|
|
495
|
+
if (res.action === 'confirm') {
|
|
496
|
+
const value = res.value.trim()
|
|
497
|
+
if (!value) {
|
|
498
|
+
toast.error('输入不能为空')
|
|
499
|
+
}
|
|
500
|
+
// 处理输入
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
})
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
5. **错误处理**
|
|
507
|
+
```typescript
|
|
508
|
+
// ✅ 完整的错误处理
|
|
509
|
+
message.confirm({
|
|
510
|
+
title: '确认操作',
|
|
511
|
+
success: async (res) => {
|
|
512
|
+
if (res.action === 'confirm') {
|
|
513
|
+
try {
|
|
514
|
+
await doSomething()
|
|
515
|
+
toast.success('操作成功')
|
|
516
|
+
}
|
|
517
|
+
catch (error) {
|
|
518
|
+
toast.error(`操作失败:${error.message}`)
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
})
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
## 使用场景
|
|
526
|
+
|
|
527
|
+
1. **确认操作**:删除、修改、提交等重要操作
|
|
528
|
+
2. **信息提醒**:操作完成、错误提示、注意事项
|
|
529
|
+
3. **数据输入**:快速输入、修改名称、设置参数
|
|
530
|
+
4. **流程控制**:多步骤操作、条件判断
|
|
531
|
+
5. **安全验证**:密码确认、验证码输入
|
|
532
|
+
|
|
533
|
+
## 注意事项
|
|
534
|
+
|
|
535
|
+
1. **回调函数处理**:确保正确处理 success 和 fail 回调
|
|
536
|
+
2. **输入验证**:prompt 类型要验证用户输入
|
|
537
|
+
3. **页面路径检测**:弹窗会自动在对应页面显示
|
|
538
|
+
4. **单例模式**:同时只能显示一个弹窗
|
|
539
|
+
5. **按钮样式**:默认按钮为非圆角样式
|
|
540
|
+
6. **异步操作**:在回调中执行异步操作要进行错误处理
|
|
541
|
+
|
|
542
|
+
## 与其他组件结合使用
|
|
543
|
+
|
|
544
|
+
```typescript
|
|
545
|
+
// 与 GlobalLoading 和 GlobalToast 结合使用
|
|
546
|
+
function handleCompleteOperation() {
|
|
547
|
+
message.confirm({
|
|
548
|
+
title: '确认操作',
|
|
549
|
+
message: '确定要执行这个操作吗?',
|
|
550
|
+
success: async (res) => {
|
|
551
|
+
if (res.action === 'confirm') {
|
|
552
|
+
const loading = useGlobalLoading()
|
|
553
|
+
const toast = useGlobalToast()
|
|
554
|
+
|
|
555
|
+
try {
|
|
556
|
+
loading.loading('处理中...')
|
|
557
|
+
await performOperation()
|
|
558
|
+
toast.success('操作成功')
|
|
559
|
+
}
|
|
560
|
+
catch (error) {
|
|
561
|
+
toast.error('操作失败')
|
|
562
|
+
}
|
|
563
|
+
finally {
|
|
564
|
+
loading.close()
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
})
|
|
569
|
+
}
|
|
570
|
+
```
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { deepClone, isFunction } from 'wot-design-uni/components/common/util'
|
|
3
|
+
import { storeToRefs } from 'pinia'
|
|
4
|
+
import { useMessage } from 'wot-design-uni'
|
|
5
|
+
import { defineOptions, nextTick, ref, watch } from 'vue'
|
|
6
|
+
import { useGlobalMessage } from '../../composables/useGlobalMessage'
|
|
7
|
+
import { getCurrentPath } from '../../utils/index'
|
|
8
|
+
|
|
9
|
+
defineOptions({
|
|
10
|
+
name: 'GlobalMessage',
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
const { messageOptions, currentPage } = storeToRefs(useGlobalMessage())
|
|
14
|
+
|
|
15
|
+
const messageBox = useMessage('globalMessage')
|
|
16
|
+
const currentPath = getCurrentPath()
|
|
17
|
+
|
|
18
|
+
// #ifdef MP-ALIPAY
|
|
19
|
+
const hackAlipayVisible = ref(false)
|
|
20
|
+
|
|
21
|
+
nextTick(() => {
|
|
22
|
+
hackAlipayVisible.value = true
|
|
23
|
+
})
|
|
24
|
+
// #endif
|
|
25
|
+
|
|
26
|
+
watch(() => messageOptions.value, (newVal) => {
|
|
27
|
+
if (newVal) {
|
|
28
|
+
if (currentPage.value === currentPath) {
|
|
29
|
+
const option = deepClone(newVal)
|
|
30
|
+
messageBox.show(option).then((res) => {
|
|
31
|
+
if (isFunction(option.success)) {
|
|
32
|
+
option.success(res)
|
|
33
|
+
}
|
|
34
|
+
}).catch((err) => {
|
|
35
|
+
if (isFunction(option.fail)) {
|
|
36
|
+
option.fail(err)
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
messageBox.close()
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<script lang="ts">
|
|
48
|
+
export default {
|
|
49
|
+
options: {
|
|
50
|
+
virtualHost: true,
|
|
51
|
+
addGlobalClass: true,
|
|
52
|
+
styleIsolation: 'shared',
|
|
53
|
+
},
|
|
54
|
+
}
|
|
55
|
+
</script>
|
|
56
|
+
|
|
57
|
+
<template>
|
|
58
|
+
<!-- #ifdef MP-ALIPAY -->
|
|
59
|
+
<wd-message-box v-if="hackAlipayVisible" selector="globalMessage" />
|
|
60
|
+
<!-- #endif -->
|
|
61
|
+
<!-- #ifndef MP-ALIPAY -->
|
|
62
|
+
<wd-message-box selector="globalMessage" />
|
|
63
|
+
<!-- #endif -->
|
|
64
|
+
</template>
|