Skip to content

Commit 78bed6a

Browse files
feat: ✨ MessageBox支持确认前置处理钩子beforeConfirm
Closes: #229
1 parent 8d3f617 commit 78bed6a

9 files changed

Lines changed: 166 additions & 40 deletions

File tree

docs/component/message-box.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,42 @@ function withSlot() {
158158
}
159159
```
160160

161+
## 确认前置处理
162+
163+
设置 `beforeConfirm` 函数,在用户选择图片点击确认后,会执行 `beforeConfirm` 函数,接收 { resolve },开发者可以在确认前进行处理,并通过 `resolve` 函数告知组件是否确定通过,`resolve` 接受 1 个 `boolean` 值,`resolve(true)` 表示选项通过,`resolve(false)` 表示选项不通过,不通过时不会完成确认操作。
164+
165+
```html
166+
<wd-toast />
167+
<wd-message-box />
168+
<wd-button @click="beforeConfirm">beforeConfirm</wd-button>
169+
```
170+
```typescript
171+
import { useMessage, useToast } from '@/uni_modules/wot-design-uni'
172+
const message = useMessage()
173+
const toast = useToast()
174+
175+
function beforeConfirm() {
176+
message
177+
.confirm({
178+
msg: '是否删除',
179+
title: '提示',
180+
beforeConfirm: ({ resolve }) => {
181+
toast.loading('删除中...')
182+
setTimeout(() => {
183+
toast.close()
184+
resolve(true)
185+
toast.success('删除成功')
186+
}, 2000)
187+
}
188+
})
189+
.then(() => {})
190+
.catch((error) => {
191+
console.log(error)
192+
})
193+
}
194+
195+
```
196+
161197
---
162198

163199
弹框在点击确定和取消按钮时,会返回一个 promise 对象,用 then 接收“确定”按钮事件,用 catch 接收“取消”按钮事件。传入的 action 值为:'confirm'、'cancel'、'modal'。

docs/component/toast.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -84,18 +84,19 @@ toast.close()
8484

8585
## options
8686

87-
| 参数 | 说明 | 类型 | 可选值 | 默认值 | 最低版本 |
88-
| ------------ | --------------------------------------------------------------------------- | ------- | ------------------------- | ------------ | -------- |
89-
| msg | 消息内容 | string | - | - | - |
90-
| duration | 持续时间,单位 ms,为 0 时表示不自动关闭 | number | - | 2000 | - |
91-
| iconName | 图标类型 | string | success / error / warning | - | - |
92-
| iconSize | 左侧图标尺寸 | string | - | 42px | - |
93-
| iconClass | 图标类目,自定义图标,可以使用 Icon 章节的那些图标类名,iconName 优先级更高 | string | - | - | - |
94-
| customIcon | 自定义图标,开启后可以通过 custom-icon-class 类名自定义图标 | Boolean | - | false | - |
95-
| position | 提示信息框的位置 | string | top / middle / bottom | middle | - |
96-
| zIndex | toast 层级 | number | - | 100 | - |
97-
| loadingType | [加载中图标类型](/component/loading) | string | ring | outline | - |
98-
| loadingColor | [加载中图标颜色](/component/loading) | string | - | #4D80F0 | - |
87+
| 参数 | 说明 | 类型 | 可选值 | 默认值 | 最低版本 |
88+
| ------------ | --------------------------------------------------------------------------- | ------- | ------------------------- | ---------------------- | -------- |
89+
| msg | 消息内容 | string | - | - | - |
90+
| duration | 持续时间,单位 ms,为 0 时表示不自动关闭 | number | - | 2000 | - |
91+
| iconName | 图标类型 | string | success / error / warning | - | - |
92+
| iconSize | 左侧图标尺寸 | string | - | 42px | - |
93+
| iconClass | 图标类目,自定义图标,可以使用 Icon 章节的那些图标类名,iconName 优先级更高 | string | - | - | - |
94+
| customIcon | 自定义图标,开启后可以通过 custom-icon-class 类名自定义图标 | Boolean | - | false | - |
95+
| position | 提示信息框的位置 | string | top / middle / bottom | middle | - |
96+
| zIndex | toast 层级 | number | - | 100 | - |
97+
| loadingType | [加载中图标类型](/component/loading) | string | ring | outline | - |
98+
| loadingColor | [加载中图标颜色](/component/loading) | string | - | #4D80F0 | - |
99+
| cover | 是否存在一个透明遮罩 | boolean | - | `loading`时默认为 true | 1.2.15 |
99100

100101
## Methods
101102

src/pages/messageBox/Index.vue

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,19 @@
2727
<demo-block title="使用wd-message-box组件,通过slot插入其他组件内容">
2828
<wd-button @click="withSlot">custom</wd-button>
2929
</demo-block>
30+
31+
<demo-block title="使用beforeConfirm钩子,在弹框确认前,可以进行一些操作">
32+
<wd-button @click="beforeConfirm">beforeConfirm</wd-button>
33+
</demo-block>
3034
</page-wraper>
3135
</template>
3236
<script lang="ts" setup>
33-
import { useMessage } from '@/uni_modules/wot-design-uni'
37+
import { useMessage, useToast } from '@/uni_modules/wot-design-uni'
3438
import { ref } from 'vue'
3539
const rate = ref<number>(1)
3640
const value1 = ref<string>('')
3741
42+
const toast = useToast()
3843
const message = useMessage()
3944
const message1 = useMessage('wd-message-box-slot')
4045
@@ -77,6 +82,27 @@ function alertWithLongChar() {
7782
title: '标题'
7883
})
7984
}
85+
86+
function beforeConfirm() {
87+
message
88+
.confirm({
89+
msg: '是否删除',
90+
title: '提示',
91+
beforeConfirm: ({ resolve }) => {
92+
toast.loading('删除中...')
93+
setTimeout(() => {
94+
toast.close()
95+
resolve(true)
96+
toast.success('删除成功')
97+
}, 3000)
98+
}
99+
})
100+
.then(() => {})
101+
.catch((error) => {
102+
console.log(error)
103+
})
104+
}
105+
80106
function withSlot() {
81107
message1
82108
.confirm({

src/pages/toast/Index.vue

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
<!--
2+
* @Author: weisheng
3+
* @Date: 2023-09-20 11:10:44
4+
* @LastEditTime: 2024-04-10 21:14:50
5+
* @LastEditors: weisheng
6+
* @Description:
7+
* @FilePath: /wot-design-uni/src/pages/toast/Index.vue
8+
* 记得注释
9+
-->
110
<template>
211
<view>
312
<page-wraper>

src/uni_modules/wot-design-uni/components/wd-message-box/types.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
/*
22
* @Author: weisheng
33
* @Date: 2024-04-08 22:34:01
4-
* @LastEditTime: 2024-04-09 22:07:26
4+
* @LastEditTime: 2024-04-10 12:58:10
55
* @LastEditors: weisheng
66
* @Description:
7-
* @FilePath: /wot-design-uni/src/uni_modules/wot-design-uni/components/wd-message-box/types.ts
7+
* @FilePath: \wot-design-uni\src\uni_modules\wot-design-uni\components\wd-message-box\types.ts
88
* 记得注释
99
*/
1010
import { baseProps } from '../common/props'
1111

1212
export type MessageType = 'alert' | 'confirm' | 'prompt'
1313

14+
export type MessageBeforeConfirmOption = {
15+
resolve: (isPass: boolean) => void
16+
}
17+
1418
export type MessageOptions = {
1519
/**
1620
* 标题
@@ -78,6 +82,10 @@ export type MessageOptions = {
7882
* 弹层内容懒渲染,触发展示时才渲染内容
7983
*/
8084
lazyRender?: boolean
85+
/**
86+
* 确认前钩子
87+
*/
88+
beforeConfirm?: (options: MessageBeforeConfirmOption) => void
8189
}
8290

8391
export type ActionType = 'confirm' | 'cancel' | 'modal'

src/uni_modules/wot-design-uni/components/wd-message-box/wd-message-box.vue

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,16 @@ export default {
5959

6060
<script lang="ts" setup>
6161
import { computed, inject, ref, watch } from 'vue'
62-
import { messageBoxProps, type InputValidate, type MessageOptions, type MessageType } from './types'
62+
import {
63+
messageBoxProps,
64+
type InputValidate,
65+
type MessageBeforeConfirmOption,
66+
type MessageOptions,
67+
type MessageResult,
68+
type MessageType
69+
} from './types'
6370
import { defaultOptions, messageDefaultOptionKey } from '.'
64-
import { isDef } from '../common/util'
71+
import { isDef, isFunction } from '../common/util'
6572
import { useTranslate } from '../composables/useTranslate'
6673
6774
const props = defineProps(messageBoxProps)
@@ -83,10 +90,9 @@ const messageOption = inject(messageOptionKey, ref<MessageOptions>(defaultOption
8390
* 消息文案
8491
*/
8592
const msg = ref<string>('')
86-
// eslint-disable-next-line @typescript-eslint/ban-types
87-
let onConfirm: Function | null = null
88-
// eslint-disable-next-line @typescript-eslint/ban-types
89-
let onCancel: Function | null = null
93+
let onConfirm: ((res: MessageResult) => void) | null = null
94+
let onCancel: ((res: MessageResult) => void) | null = null
95+
let beforeConfirm: ((options: MessageBeforeConfirmOption) => void) | null = null
9096
const show = ref<boolean>(false)
9197
/**
9298
* 标题
@@ -189,29 +195,53 @@ function toggleModal(action: 'confirm' | 'cancel' | 'modal') {
189195
if (type.value === 'prompt' && action === 'confirm' && !validate()) {
190196
return
191197
}
192-
show.value = false
193198
switch (action) {
194199
case 'confirm':
195-
onConfirm &&
196-
onConfirm({
200+
if (beforeConfirm) {
201+
beforeConfirm({
202+
resolve: (isPass) => {
203+
if (isPass) {
204+
handleConfirm({
205+
action: action,
206+
value: inputValue.value
207+
})
208+
}
209+
}
210+
})
211+
} else {
212+
handleConfirm({
197213
action: action,
198214
value: inputValue.value
199215
})
216+
}
200217
break
201218
case 'cancel':
202-
onCancel &&
203-
onCancel({
204-
action: action
205-
})
219+
handleCancel({
220+
action: action
221+
})
206222
break
207223
default:
208-
onCancel &&
209-
onCancel({
210-
action: 'modal'
211-
})
224+
handleCancel({
225+
action: 'modal'
226+
})
212227
break
213228
}
214229
}
230+
231+
function handleConfirm(result: MessageResult) {
232+
show.value = false
233+
if (isFunction(onConfirm)) {
234+
onConfirm(result)
235+
}
236+
}
237+
238+
function handleCancel(result: MessageResult) {
239+
show.value = false
240+
if (isFunction(onCancel)) {
241+
onCancel(result)
242+
}
243+
}
244+
215245
/**
216246
* @description 如果存在校验规则行为,则进行判断校验是否通过规则。默认不存在校验直接铜鼓。
217247
* @return {Boolean} 是否通过校验
@@ -269,6 +299,7 @@ function reset(option: MessageOptions) {
269299
inputValidate = option.inputValidate!
270300
onConfirm = (option as any).onConfirm
271301
onCancel = (option as any).onCancel
302+
beforeConfirm = option.beforeConfirm!
272303
inputError.value = option.inputError!
273304
showErr.value = option.showErr!
274305
zIndex.value = option.zIndex!

src/uni_modules/wot-design-uni/components/wd-toast/index.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* @Author: weisheng
33
* @Date: 2024-03-29 13:29:57
4-
* @LastEditTime: 2024-04-01 19:13:51
4+
* @LastEditTime: 2024-04-10 20:18:47
55
* @LastEditors: weisheng
66
* @Description:
77
* @FilePath: \wot-design-uni\src\uni_modules\wot-design-uni\components\wd-toast\index.ts
@@ -52,8 +52,8 @@ export function useToast(selector: string = ''): Toast {
5252
show: true
5353
}) as ToastOptions
5454
// 开始渲染,并在 duration ms之后执行清除
55+
timer && clearTimeout(timer)
5556
if (toastOption.value.duration && toastOption.value.duration > 0) {
56-
timer && clearTimeout(timer)
5757
timer = setTimeout(() => {
5858
timer && clearTimeout(timer)
5959
close()
@@ -63,7 +63,8 @@ export function useToast(selector: string = ''): Toast {
6363

6464
const loading = createMethod({
6565
iconName: 'loading',
66-
duration: 0
66+
duration: 0,
67+
cover: true
6768
})
6869
const success = createMethod({
6970
iconName: 'success',

src/uni_modules/wot-design-uni/components/wd-toast/types.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
/*
22
* @Author: weisheng
33
* @Date: 2023-06-19 12:47:57
4-
* @LastEditTime: 2024-03-14 21:18:15
4+
* @LastEditTime: 2024-04-10 20:18:34
55
* @LastEditors: weisheng
66
* @Description:
7-
* @FilePath: \wot-design-uni\src\uni_modules\wot-design-uni\components\wd-toast\type.ts
7+
* @FilePath: \wot-design-uni\src\uni_modules\wot-design-uni\components\wd-toast\types.ts
88
* 记得注释
99
*/
1010
import type { ExtractPropTypes } from 'vue'
@@ -30,6 +30,10 @@ export type ToastOptions = {
3030
position?: ToastPositionType
3131
show?: boolean
3232
zIndex?: number
33+
/**
34+
* 是否存在遮罩层
35+
*/
36+
cover?: boolean
3337
}
3438

3539
export interface Toast {

src/uni_modules/wot-design-uni/components/wd-toast/wd-toast.vue

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<template>
2+
<wd-overlay v-if="cover" :z-index="zIndex" lock-scroll :show="show" custom-style="background-color: transparent;pointer-events: auto;"></wd-overlay>
23
<wd-transition name="fade" :show="show" :custom-style="transitionStyle">
34
<view :class="rootClass">
45
<!--iconName优先级更高-->
@@ -31,7 +32,7 @@ export default {
3132
</script>
3233

3334
<script lang="ts" setup>
34-
import { computed, inject, onBeforeMount, ref, watch } from 'vue'
35+
import { computed, inject, onBeforeMount, ref, watch, type CSSProperties } from 'vue'
3536
import base64 from '../common/base64'
3637
import { defaultOptions, toastDefaultOptionKey, toastIcon } from '.'
3738
import { toastProps, type ToastLoadingType, type ToastOptions } from './types'
@@ -49,6 +50,7 @@ const loadingType = ref<ToastLoadingType>('outline')
4950
const loadingColor = ref<string>('#4D80F0')
5051
const iconSize = ref<number>(42)
5152
const svgStr = ref<string>('') // 图标
53+
const cover = ref<boolean>(false) // 是否存在遮罩层
5254
5355
const toastOptionKey = props.selector ? toastDefaultOptionKey + props.selector : toastDefaultOptionKey
5456
const toastOption = inject(toastOptionKey, ref<ToastOptions>(defaultOptions)) // toast选项
@@ -77,11 +79,18 @@ watch(
7779
}
7880
)
7981
82+
/**
83+
* 动画自定义样式
84+
*/
85+
const isLoading = computed(() => {
86+
return iconName.value === 'loading'
87+
})
88+
8089
/**
8190
* 动画自定义样式
8291
*/
8392
const transitionStyle = computed(() => {
84-
const style: Record<string, string | number> = {
93+
const style: CSSProperties = {
8594
'z-index': zIndex.value,
8695
position: 'fixed',
8796
top: '50%',
@@ -97,7 +106,7 @@ const transitionStyle = computed(() => {
97106
* 加载自定义样式
98107
*/
99108
const loadingStyle = computed(() => {
100-
const style: Record<string, string | number> = {
109+
const style: CSSProperties = {
101110
display: 'inline-block',
102111
'margin-right': '16px'
103112
}
@@ -137,6 +146,7 @@ function reset(option: ToastOptions) {
137146
loadingType.value = isDef(option.loadingType!) ? option.loadingType! : 'outline'
138147
loadingColor.value = isDef(option.loadingColor!) ? option.loadingColor! : '#4D80F0'
139148
iconSize.value = isDef(option.iconSize!) ? option.iconSize! : 42
149+
cover.value = isDef(option.cover!) ? option.cover! : false
140150
}
141151
}
142152
}

0 commit comments

Comments
 (0)