From de4440e863a235b8bba865e0ea4fada0187a500b Mon Sep 17 00:00:00 2001 From: centuryPark Date: Fri, 1 Nov 2024 12:34:25 +0800 Subject: [PATCH] feat(switch): support beforeChange API closed #848 --- src/switch/__tests__/base.test.jsx | 39 ++++++++++++++++++++ src/switch/_example/before-change.vue | 53 +++++++++++++++++++++++++++ src/switch/props.ts | 4 ++ src/switch/switch.en-US.md | 1 + src/switch/switch.md | 1 + src/switch/switch.tsx | 14 ++++++- src/switch/type.ts | 4 ++ 7 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 src/switch/_example/before-change.vue diff --git a/src/switch/__tests__/base.test.jsx b/src/switch/__tests__/base.test.jsx index ec35547d3f..72f8e06da1 100644 --- a/src/switch/__tests__/base.test.jsx +++ b/src/switch/__tests__/base.test.jsx @@ -136,5 +136,44 @@ describe('switch', () => { expect(eleCls.includes('t-size-s')).toBe(true); }); }); + // test props beforeChange + describe(':props.beforeChange', () => { + it('beforeChange resolve', async () => { + const beforeChangeResolve = () => + new Promise((resolve) => { + setTimeout(() => { + resolve(true); + }, 80); + }); + const wrapper = mount({ + render() { + return ; + }, + }); + wrapper.trigger('click'); + await new Promise((resolve) => setTimeout(resolve, 100)); + const ele = wrapper.find('.t-switch'); + const eleCls = ele.classes(); + expect(eleCls.includes('t-is-checked')).toBeFalsy(); + }); + it('beforeChange reject', async () => { + const beforeChangeReject = () => + new Promise((_resolve, reject) => { + setTimeout(() => { + reject(); + }, 80); + }); + const wrapper = mount({ + render() { + return ; + }, + }); + wrapper.trigger('click'); + await new Promise((resolve) => setTimeout(resolve, 100)); + const ele = wrapper.find('.t-switch'); + const eleCls = ele.classes(); + expect(eleCls.includes('t-is-checked')).toBe(false); + }); + }); }); }); diff --git a/src/switch/_example/before-change.vue b/src/switch/_example/before-change.vue new file mode 100644 index 0000000000..8a9d2ac1a6 --- /dev/null +++ b/src/switch/_example/before-change.vue @@ -0,0 +1,53 @@ + + + diff --git a/src/switch/props.ts b/src/switch/props.ts index 07aff17d56..ca93c63559 100644 --- a/src/switch/props.ts +++ b/src/switch/props.ts @@ -8,6 +8,10 @@ import { TdSwitchProps } from './type'; import { PropType } from 'vue'; export default { + /** Switch 切换状态前的回调方法,常用于需要发起异步请求的场景,回到返回值支持布尔和 Promise 类型,返回`false`或 Promise reject不继续执行change,否则则继续执行。 */ + beforeChange: { + type: Function as PropType, + }, /** 用于自定义开关的值,[打开时的值,关闭时的值]。默认为 [true, false]。示例:[1, 0]、['open', 'close'] */ customValue: { type: Array as PropType, diff --git a/src/switch/switch.en-US.md b/src/switch/switch.en-US.md index f3e678fdac..b074a82944 100644 --- a/src/switch/switch.en-US.md +++ b/src/switch/switch.en-US.md @@ -5,6 +5,7 @@ name | type | default | description | required -- | -- | -- | -- | -- +beforeChange | Function | - | stop checked change。Typescript:`() => boolean \| Promise` | N customValue | Array | - | Typescript:`Array` | N disabled | Boolean | undefined | \- | N label | Array / Slot / Function | [] | Typescript:`Array \| TNode<{ value: SwitchValue }>`。[see more ts definition](https://github.com/Tencent/tdesign-vue-next/blob/develop/src/common.ts) | N diff --git a/src/switch/switch.md b/src/switch/switch.md index 97fa25ccad..699ea83c76 100644 --- a/src/switch/switch.md +++ b/src/switch/switch.md @@ -5,6 +5,7 @@ 名称 | 类型 | 默认值 | 说明 | 必传 -- | -- | -- | -- | -- +beforeChange | Function | - | Switch 切换状态前的回调方法,常用于需要发起异步请求的场景,回到返回值支持布尔和 Promise 类型,返回`false`或 Promise reject不继续执行change,否则则继续执行。。TS 类型:`() => boolean \| Promise` | N customValue | Array | - | 用于自定义开关的值,[打开时的值,关闭时的值]。默认为 [true, false]。示例:[1, 0]、['open', 'close']。TS 类型:`Array` | N disabled | Boolean | undefined | 是否禁用组件。优先级:Switch.disabled > Form.disabled | N label | Array / Slot / Function | [] | 开关内容,[开启时内容,关闭时内容]。示例:['开', '关'] 或 (value) => value ? '开' : '关'。TS 类型:`Array \| TNode<{ value: SwitchValue }>`。[通用类型定义](https://github.com/Tencent/tdesign-vue-next/blob/develop/src/common.ts) | N diff --git a/src/switch/switch.tsx b/src/switch/switch.tsx index 15a4c98ac3..a75fa7ba5e 100755 --- a/src/switch/switch.tsx +++ b/src/switch/switch.tsx @@ -47,7 +47,19 @@ export default defineComponent({ if (disabled.value || props.loading) { return; } - handleToggle(e); + if (!props.beforeChange) { + handleToggle(e); + return; + } + Promise.resolve(props.beforeChange()) + .then((v) => { + if (v) { + handleToggle(e); + } + }) + .catch((e) => { + throw new Error(`Switch: some error occurred: ${e}`); + }); } // classes diff --git a/src/switch/type.ts b/src/switch/type.ts index a8c3201d95..ac604f73c0 100644 --- a/src/switch/type.ts +++ b/src/switch/type.ts @@ -7,6 +7,10 @@ import { TNode } from '../common'; export interface TdSwitchProps { + /** + * Switch 切换状态前的回调方法,常用于需要发起异步请求的场景,回到返回值支持布尔和 Promise 类型,返回`false`或 Promise reject不继续执行change,否则则继续执行。 + */ + beforeChange?: () => boolean | Promise; /** * 用于自定义开关的值,[打开时的值,关闭时的值]。默认为 [true, false]。示例:[1, 0]、['open', 'close'] */