From 20b3a83392a1a071baf7ccf2cbc7779f255531aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E4=BC=9F=E6=9D=B0?= <674416404@qq.com> Date: Fri, 26 Apr 2024 12:31:06 +0800 Subject: [PATCH 1/6] refactor(cascader): sfc to tsx --- .../__test__/__snapshots__/demo.test.jsx.snap | 130 ++------- src/cascader/__test__/index.test.jsx | 2 +- src/cascader/cascader.en-US.md | 12 +- src/cascader/cascader.md | 11 +- src/cascader/{cascader.vue => cascader.tsx} | 266 +++++++++--------- src/cascader/index.ts | 2 +- src/cascader/props.ts | 15 +- src/cascader/type.ts | 13 +- .../__test__/__snapshots__/demo.test.jsx.snap | 21 +- 9 files changed, 183 insertions(+), 289 deletions(-) rename src/cascader/{cascader.vue => cascader.tsx} (54%) diff --git a/src/cascader/__test__/__snapshots__/demo.test.jsx.snap b/src/cascader/__test__/__snapshots__/demo.test.jsx.snap index d762da073..242cf8102 100644 --- a/src/cascader/__test__/__snapshots__/demo.test.jsx.snap +++ b/src/cascader/__test__/__snapshots__/demo.test.jsx.snap @@ -69,9 +69,7 @@ exports[`Cascader > Cascader baseVue demo works fine 1`] = `
- 选择地址 -
Cascader baseVue demo works fine 1`] = `
- 选择选项 -
Cascader baseVue demo works fine 1`] = `
- - +
Cascader checkStrictlyVue demo works fine 1`] = `
- 选择地址 -
Cascader checkStrictlyVue demo works fine 1`] = `
- 选择选项 -
Cascader checkStrictlyVue demo works fine 1`] = `
- - +
Cascader keysVue demo works fine 1`] = `
- 选择地址 -
Cascader keysVue demo works fine 1`] = `
- 选择选项 -
Cascader keysVue demo works fine 1`] = `
- - +
Cascader keysVue demo works fine 1`] = ` class="t-radio__original" name="" type="radio" - value="110000" />
Cascader keysVue demo works fine 1`] = `
- - 北京市 - +
@@ -641,7 +620,6 @@ exports[`Cascader > Cascader keysVue demo works fine 1`] = ` class="t-radio__original" name="" type="radio" - value="120000" />
Cascader keysVue demo works fine 1`] = `
- - 天津市 - +
@@ -753,9 +726,7 @@ exports[`Cascader > Cascader lazyVue demo works fine 1`] = `
- 选择地址 -
Cascader lazyVue demo works fine 1`] = `
- 选择选项 -
Cascader lazyVue demo works fine 1`] = `
-
- +
Cascader mobileVue demo works fine 1`] = `
- 选择地址 -
Cascader mobileVue demo works fine 1`] = `
- 选择选项 -
Cascader mobileVue demo works fine 1`] = `
-
- +
Cascader mobileVue demo works fine 1`] = `
- 选择地址 -
Cascader mobileVue demo works fine 1`] = `
-
- - -
- + +
Cascader mobileVue demo works fine 1`] = `
- 选择地址 -
Cascader mobileVue demo works fine 1`] = `
- 选择选项 -
Cascader mobileVue demo works fine 1`] = `
-
- +
Cascader mobileVue demo works fine 1`] = `
- 选择地址 -
Cascader mobileVue demo works fine 1`] = `
- 选择选项 -
Cascader mobileVue demo works fine 1`] = `
-
- +
Cascader mobileVue demo works fine 1`] = ` class="t-radio__original" name="" type="radio" - value="110000" />
Cascader mobileVue demo works fine 1`] = `
- - 北京市 - +
@@ -1795,7 +1737,6 @@ exports[`Cascader > Cascader mobileVue demo works fine 1`] = ` class="t-radio__original" name="" type="radio" - value="120000" />
Cascader mobileVue demo works fine 1`] = `
- - 天津市 - +
@@ -1920,9 +1856,7 @@ exports[`Cascader > Cascader mobileVue demo works fine 1`] = `
- 选择地址 -
Cascader mobileVue demo works fine 1`] = `
- 选择选项 -
Cascader mobileVue demo works fine 1`] = `
-
Cascader mobileVue demo works fine 1`] = `
- 选择地址 -
Cascader mobileVue demo works fine 1`] = `
- 选择选项 -
Cascader mobileVue demo works fine 1`] = `
-
- +
Cascader mobileVue demo works fine 1`] = `
- 选择地址 -
Cascader mobileVue demo works fine 1`] = `
- 选择选项 -
Cascader mobileVue demo works fine 1`] = `
-
- +
Cascader themeTabVue demo works fine 1`] = `
- 选择地址 -
Cascader themeTabVue demo works fine 1`] = `
-
- - -
- + +
Cascader withTitleVue demo works fine 1`] = `
- 选择地址 -
Cascader withTitleVue demo works fine 1`] = `
- 选择选项 -
Cascader withTitleVue demo works fine 1`] = `
-
Cascader withValueVue demo works fine 1`] = `
- 选择地址 -
Cascader withValueVue demo works fine 1`] = `
- 选择选项 -
Cascader withValueVue demo works fine 1`] = `
-
- +
` | N +placeholder | String / Slot / Function | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N subTitles | Array | [] | Typescript:`Array` | N -theme | String | step | options:step/tab | N +theme | String | step | options: step/tab | N title | String / Slot / Function | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N value | String / Number | - | `v-model` and `v-model:value` is supported | N defaultValue | String / Number | - | uncontrolled property | N visible | Boolean | false | \- | N -checkStrictly | Boolean | false | 父子节点选中状态不再关联,可各自选中或取消 | N -placeholder | String / Slot / Function | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N onChange | Function | | Typescript:`(value: string \| number, selectedOptions: string[]) => void`
| N onClose | Function | | Typescript:`(trigger: TriggerSource) => void`
[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/cascader/type.ts)。
`type TriggerSource = 'overlay' \| 'close-btn' \| 'finish'`
| N -onPick | Function | | Typescript:`(context: { level: number; value: string | number; index: number }) => void`
| N +onPick | Function | | Typescript:`(context: { level: number, value: string \| number, index: number }) => void`
| N ### Cascader Events @@ -29,8 +29,8 @@ change | `(value: string \| number, selectedOptions: string[])` | \- close | `(trigger: TriggerSource)` | [see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/cascader/type.ts)。
`type TriggerSource = 'overlay' \| 'close-btn' \| 'finish'`
pick | `(context: { level: number, value: string \| number, index: number })` | \- +### CSS 变量 -### CSS Variables The component provides the following CSS variables, which can be used to customize styles. Name | Default Value | Description -- | -- | -- @@ -43,4 +43,4 @@ Name | Default Value | Description --td-cascader-step-dot-size | 8px | - --td-cascader-step-height | 44px | - --td-cascader-title-color | @font-gray-1 | - ---td-cascder-title-font-size | 18px | - +--td-cascder-title-font-size | 18px | - \ No newline at end of file diff --git a/src/cascader/cascader.md b/src/cascader/cascader.md index 571d66189..5b585caa2 100644 --- a/src/cascader/cascader.md +++ b/src/cascader/cascader.md @@ -1,21 +1,22 @@ :: BASE_DOC :: ## API + ### Cascader Props -名称 | 类型 | 默认值 | 说明 | 必传 +名称 | 类型 | 默认值 | 描述 | 必传 -- | -- | -- | -- | -- +checkStrictly | Boolean | false | 父子节点选中状态不再关联,可各自选中或取消 | N closeBtn | Boolean / Slot / Function | true | 关闭按钮。TS 类型:`boolean \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N keys | Object | - | 用来定义 value / label 在 `options` 中对应的字段别名。TS 类型:`KeysType`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N options | Array | [] | 可选项数据源。TS 类型:`Array` | N +placeholder | String / Slot / Function | - | 未选中时的提示文案。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N subTitles | Array | [] | 每级展示的次标题。TS 类型:`Array` | N theme | String | step | 展示风格。可选项:step/tab | N title | String / Slot / Function | - | 标题。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N value | String / Number | - | 选项值。支持语法糖 `v-model` 或 `v-model:value` | N defaultValue | String / Number | - | 选项值。非受控属性 | N visible | Boolean | false | 是否展示 | N -checkStrictly | Boolean | false | 父子节点选中状态不再关联,可各自选中或取消 | N -placeholder | String / Slot / Function | 选择选项 | 未选中时的提示文案。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N onChange | Function | | TS 类型:`(value: string \| number, selectedOptions: string[]) => void`
值发生变更时触发 | N onClose | Function | | TS 类型:`(trigger: TriggerSource) => void`
关闭时触发。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/cascader/type.ts)。
`type TriggerSource = 'overlay' \| 'close-btn' \| 'finish'`
| N onPick | Function | | TS 类型:`(context: { level: number, value: string \| number, index: number }) => void`
选择后触发 | N @@ -28,8 +29,8 @@ change | `(value: string \| number, selectedOptions: string[])` | 值发生变 close | `(trigger: TriggerSource)` | 关闭时触发。[详细类型定义](https://github.com/Tencent/tdesign-mobile-vue/tree/develop/src/cascader/type.ts)。
`type TriggerSource = 'overlay' \| 'close-btn' \| 'finish'`
pick | `(context: { level: number, value: string \| number, index: number })` | 选择后触发 - ### CSS 变量 + 组件提供了下列 CSS 变量,可用于自定义样式。 名称 | 默认值 | 描述 -- | -- | -- @@ -42,4 +43,4 @@ pick | `(context: { level: number, value: string \| number, index: number })` | --td-cascader-step-dot-size | 8px | - --td-cascader-step-height | 44px | - --td-cascader-title-color | @font-gray-1 | - ---td-cascder-title-font-size | 18px | - +--td-cascder-title-font-size | 18px | - \ No newline at end of file diff --git a/src/cascader/cascader.vue b/src/cascader/cascader.tsx similarity index 54% rename from src/cascader/cascader.vue rename to src/cascader/cascader.tsx index 14c1f192c..026d510c4 100644 --- a/src/cascader/cascader.vue +++ b/src/cascader/cascader.tsx @@ -1,78 +1,3 @@ - - - diff --git a/src/cascader/index.ts b/src/cascader/index.ts index 9188643ee..2bbcd00a2 100644 --- a/src/cascader/index.ts +++ b/src/cascader/index.ts @@ -1,4 +1,4 @@ -import Cascader from './cascader.vue'; +import Cascader from './cascader'; import { withInstall, WithInstallType } from '../shared'; import './style'; diff --git a/src/cascader/props.ts b/src/cascader/props.ts index dedacc5be..efa3ed48a 100644 --- a/src/cascader/props.ts +++ b/src/cascader/props.ts @@ -8,6 +8,8 @@ import { TdCascaderProps } from './type'; import { PropType } from 'vue'; export default { + /** 父子节点选中状态不再关联,可各自选中或取消 */ + checkStrictly: Boolean, /** 关闭按钮 */ closeBtn: { type: [Boolean, Function] as PropType, @@ -22,6 +24,10 @@ export default { type: Array as PropType, default: (): TdCascaderProps['options'] => [], }, + /** 未选中时的提示文案 */ + placeholder: { + type: [String, Function] as PropType, + }, /** 每级展示的次标题 */ subTitles: { type: Array as PropType, @@ -53,17 +59,8 @@ export default { defaultValue: { type: [String, Number] as PropType, }, - /** 未选中时的提示文案 */ - placeholder: { - type: [String, Function] as PropType, - }, /** 是否展示 */ visible: Boolean, - /** 父子节点选中状态不再关联,可各自选中或取消 */ - checkStrictly: { - type: Boolean, - default: false, - }, /** 值发生变更时触发 */ onChange: Function as PropType, /** 关闭时触发 */ diff --git a/src/cascader/type.ts b/src/cascader/type.ts index fcdae0a07..e8ffe1b83 100644 --- a/src/cascader/type.ts +++ b/src/cascader/type.ts @@ -7,6 +7,11 @@ import { TNode, TreeOptionData, KeysType } from '../common'; export interface TdCascaderProps { + /** + * 父子节点选中状态不再关联,可各自选中或取消 + * @default false + */ + checkStrictly?: boolean; /** * 关闭按钮 * @default true @@ -21,6 +26,10 @@ export interface TdCascaderProps; + /** + * 未选中时的提示文案 + */ + placeholder?: string | TNode; /** * 每级展示的次标题 * @default [] @@ -52,10 +61,6 @@ export interface TdCascaderProps Form horizontalVue demo works fine 1`] = `
- 选择地址 -
Form horizontalVue demo works fine 1`] = `
- 选择选项 -
Form horizontalVue demo works fine 1`] = `
-
- +
Form mobileVue demo works fine 1`] = `
- 选择地址 -
Form mobileVue demo works fine 1`] = `
- 选择选项 -
Form mobileVue demo works fine 1`] = `
- - +
Form verticalVue demo works fine 1`] = `
- 选择地址 -
Form verticalVue demo works fine 1`] = `
- 选择选项 -
Form verticalVue demo works fine 1`] = `
- - +
Date: Fri, 26 Apr 2024 12:31:54 +0800 Subject: [PATCH 2/6] =?UTF-8?q?fix(cell):=20note=20=E5=93=8D=E5=BA=94?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cell/cell.tsx | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/cell/cell.tsx b/src/cell/cell.tsx index 943cc5d99..69225c8c3 100644 --- a/src/cell/cell.tsx +++ b/src/cell/cell.tsx @@ -81,19 +81,20 @@ export default defineComponent({ ); }; - const note = readerTNodeContent('default', 'note'); - - return () => ( -
- {readerLeft()} - {readerTitle()} - {note &&
{note}
} - {readerRight()} -
- ); + return () => { + const note = readerTNodeContent('default', 'note'); + return ( +
+ {readerLeft()} + {readerTitle()} + {note &&
{note}
} + {readerRight()} +
+ ); + }; }, }); From b815746e8c590013d34ed46092295a1c10adc352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E4=BC=9F=E6=9D=B0?= <674416404@qq.com> Date: Fri, 26 Apr 2024 12:38:55 +0800 Subject: [PATCH 3/6] test: snap update --- .../__test__/__snapshots__/demo.test.jsx.snap | 28 +++++++++---------- .../__snapshots__/index.test.jsx.snap | 9 ++---- src/cascader/cascader.tsx | 2 +- .../__test__/__snapshots__/demo.test.jsx.snap | 6 ++-- 4 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/cascader/__test__/__snapshots__/demo.test.jsx.snap b/src/cascader/__test__/__snapshots__/demo.test.jsx.snap index 242cf8102..ca6b7bb51 100644 --- a/src/cascader/__test__/__snapshots__/demo.test.jsx.snap +++ b/src/cascader/__test__/__snapshots__/demo.test.jsx.snap @@ -133,7 +133,7 @@ exports[`Cascader > Cascader baseVue demo works fine 1`] = ` class="t-cascader__options" >
Cascader checkStrictlyVue demo works fine 1`] = ` class="t-cascader__options" >
Cascader keysVue demo works fine 1`] = ` class="t-cascader__options" >
Cascader lazyVue demo works fine 1`] = ` class="t-cascader__options" >
Cascader mobileVue demo works fine 1`] = ` class="t-cascader__options" >
Cascader mobileVue demo works fine 1`] = ` class="t-cascader__options" >
Cascader mobileVue demo works fine 1`] = ` class="t-cascader__options" >
Cascader mobileVue demo works fine 1`] = ` class="t-cascader__options" >
Cascader mobileVue demo works fine 1`] = ` class="t-cascader__options" >
Cascader mobileVue demo works fine 1`] = ` class="t-cascader__options" >
Cascader mobileVue demo works fine 1`] = ` class="t-cascader__options" >
Cascader themeTabVue demo works fine 1`] = ` class="t-cascader__options" >
Cascader withTitleVue demo works fine 1`] = ` class="t-cascader__options" >
Cascader withValueVue demo works fine 1`] = ` class="t-cascader__options" >
events > : pick 1`] = `
- + 标题
events > : pick 1`] = `
- 选择选项 -
events > : pick 1`] = `
-
- +
events > : pick 1`] = ` class="t-cascader__options" >
Form horizontalVue demo works fine 1`] = ` class="t-cascader__options" >
Form mobileVue demo works fine 1`] = ` class="t-cascader__options" >
Form verticalVue demo works fine 1`] = ` class="t-cascader__options" >
Date: Fri, 17 May 2024 10:01:42 +0800 Subject: [PATCH 4/6] chore: format code --- src/cascader/cascader.tsx | 81 ++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/src/cascader/cascader.tsx b/src/cascader/cascader.tsx index 3bd229263..30f6ff05a 100644 --- a/src/cascader/cascader.tsx +++ b/src/cascader/cascader.tsx @@ -53,7 +53,7 @@ export default defineComponent({ const cascaderClass = usePrefixClass('cascader'); const { globalConfig } = useConfig('cascader'); - const { visible, value, modelValue, subTitles, options, keys, checkStrictly } = toRefs(props); + const { visible, value, modelValue, keys } = toRefs(props); const open = ref(visible.value || false); const [cascaderValue, setCascaderValue] = useVModel(value, modelValue, props.defaultValue, props.onChange); @@ -62,24 +62,13 @@ export default defineComponent({ const stepIndex = ref(0); const selectedIndexes = reactive([]); const selectedValue = reactive([]); - const items: Array> = reactive([options.value ?? []]); + const items: Array> = reactive([props.options ?? []]); const steps = reactive([placeholder.value]); - watch(placeholder, (newValue, oldValue) => { - const index = steps.indexOf(oldValue); - if (index !== -1) { - steps[index] = newValue; - } - }); - - onMounted(() => { - initWithValue(); - }); - const initWithValue = () => { if (value.value != null) { steps.pop(); - const path = getIndexesByValue(options.value, value.value); + const path = getIndexesByValue(props.options, value.value); path?.forEach((e: number) => { // @ts-ignore selectedIndexes.push(e); @@ -89,7 +78,7 @@ export default defineComponent({ }; const watchSelectedIndexes = () => { - if (options.value && options.value.length > 0) { + if (props.options && props.options.length > 0) { for (let i = 0, size = selectedIndexes.length; i < size; i += 1) { const index = selectedIndexes[i]; const next = items[i]?.[index]; @@ -171,33 +160,13 @@ export default defineComponent({ } props.onPick?.({ level, value: item[(keys as Ref).value?.value ?? 'value'], index }); - if (checkStrictly.value && selectedValue.includes(String(value))) { + if (props.checkStrictly && selectedValue.includes(String(value))) { cancelSelect(value, level, index, item); } else { chooseSelect(value, level, index, item); } }; - watch(open, () => { - context.emit('update:visible', open.value); - }); - - watch(visible, () => { - open.value = visible.value; - }); - - watch( - () => props.options, - () => { - if (open.value) { - handleSelect(childrenInfo.value, childrenInfo.level); - } - }, - { - deep: true, - }, - ); - const close = (trigger: TriggerSource) => { props.onClose?.(trigger); }; @@ -222,7 +191,7 @@ export default defineComponent({ }; const onCloseBtn = () => { - if (checkStrictly.value) { + if (props.checkStrictly) { updateCascaderValue(); onClose(); } else { @@ -237,6 +206,38 @@ export default defineComponent({ const onTabChange = (value: number | string) => { stepIndex.value = Number(value); }; + + watch(open, () => { + context.emit('update:visible', open.value); + }); + + watch(visible, () => { + open.value = visible.value; + }); + + watch( + () => props.options, + () => { + if (open.value) { + handleSelect(childrenInfo.value, childrenInfo.level); + } + }, + { + deep: true, + }, + ); + + watch(placeholder, (newValue, oldValue) => { + const index = steps.indexOf(oldValue); + if (index !== -1) { + steps[index] = newValue; + } + }); + + onMounted(() => { + initWithValue(); + }); + return () => { const title = renderTNodeJSX('title') || globalConfig.value.title; const closeBtn = renderTNodeJSX('closeBtn', { defaultNode: }); @@ -310,8 +311,8 @@ export default defineComponent({
{readerSteps()} - {subTitles.value && subTitles.value[stepIndex.value] && ( -
{subTitles.value[stepIndex.value]}
+ {props.subTitles && props.subTitles[stepIndex.value] && ( +
{props.subTitles[stepIndex.value]}
)}
Date: Fri, 17 May 2024 10:08:53 +0800 Subject: [PATCH 5/6] fix: keys --- .../__test__/__snapshots__/demo.test.jsx.snap | 40 ++++++++++++---- src/cascader/cascader.tsx | 47 ++++++++++--------- 2 files changed, 57 insertions(+), 30 deletions(-) diff --git a/src/cascader/__test__/__snapshots__/demo.test.jsx.snap b/src/cascader/__test__/__snapshots__/demo.test.jsx.snap index da6b8825b..bce4216ab 100644 --- a/src/cascader/__test__/__snapshots__/demo.test.jsx.snap +++ b/src/cascader/__test__/__snapshots__/demo.test.jsx.snap @@ -576,6 +576,7 @@ exports[`Cascader > Cascader keysVue demo works fine 1`] = ` class="t-radio__original" name="" type="radio" + value="110000" />
Cascader keysVue demo works fine 1`] = `
- - + + 北京市 + +
@@ -600,6 +606,7 @@ exports[`Cascader > Cascader keysVue demo works fine 1`] = ` class="t-radio__original" name="" type="radio" + value="120000" />
Cascader keysVue demo works fine 1`] = `
- - + + 天津市 + +
@@ -1657,6 +1669,7 @@ exports[`Cascader > Cascader mobileVue demo works fine 1`] = ` class="t-radio__original" name="" type="radio" + value="110000" />
Cascader mobileVue demo works fine 1`] = `
- - + + 北京市 + +
@@ -1681,6 +1699,7 @@ exports[`Cascader > Cascader mobileVue demo works fine 1`] = ` class="t-radio__original" name="" type="radio" + value="120000" />
Cascader mobileVue demo works fine 1`] = `
- - + + 天津市 + +
diff --git a/src/cascader/cascader.tsx b/src/cascader/cascader.tsx index 30f6ff05a..f7928fedf 100644 --- a/src/cascader/cascader.tsx +++ b/src/cascader/cascader.tsx @@ -53,10 +53,10 @@ export default defineComponent({ const cascaderClass = usePrefixClass('cascader'); const { globalConfig } = useConfig('cascader'); - const { visible, value, modelValue, keys } = toRefs(props); - const open = ref(visible.value || false); + const { visible, value, modelValue } = toRefs(props); const [cascaderValue, setCascaderValue] = useVModel(value, modelValue, props.defaultValue, props.onChange); + const open = ref(visible.value || false); const placeholder = computed(() => props.placeholder || globalConfig.value.placeholder); const stepIndex = ref(0); @@ -79,13 +79,14 @@ export default defineComponent({ const watchSelectedIndexes = () => { if (props.options && props.options.length > 0) { + const keys = props.keys as KeysType; for (let i = 0, size = selectedIndexes.length; i < size; i += 1) { const index = selectedIndexes[i]; const next = items[i]?.[index]; - selectedValue.push(next[(keys as Ref).value?.value ?? 'value']); - steps.push(next[(keys as Ref).value?.label ?? 'label']); - if (next[(keys as Ref).value?.children ?? 'children']) { - items.push(next[(keys as Ref).value?.children ?? 'children']); + selectedValue.push(next[keys?.value ?? 'value']); + steps.push(next[keys?.label ?? 'label']); + if (next[keys?.children ?? 'children']) { + items.push(next[keys?.children ?? 'children']); } } } @@ -96,12 +97,13 @@ export default defineComponent({ }; const getIndexesByValue = (options: any, value: any) => { + const keys = props.keys as KeysType; for (let i = 0; i < options.length; i++) { - if (options[i][(keys as Ref).value?.value ?? 'value'] === value) { + if (options[i][keys?.value ?? 'value'] === value) { return [i]; } - if (options[i][(keys as Ref).value?.children ?? 'children']) { - const res: any = getIndexesByValue(options[i][(keys as Ref).value?.children ?? 'children'], value); + if (options[i][keys?.children ?? 'children']) { + const res: any = getIndexesByValue(options[i][keys?.children ?? 'children'], value); if (res) { return [i, ...res]; } @@ -110,24 +112,25 @@ export default defineComponent({ }; const chooseSelect = (value: RadioValue, level: number, index: number, item: any) => { + const keys = props.keys as KeysType; selectedIndexes[level] = index; selectedIndexes.length = level + 1; selectedValue[level] = String(value); selectedValue.length = level + 1; - steps[level] = item[(keys as Ref).value?.label ?? 'label'] as string; + steps[level] = item[keys?.label ?? 'label'] as string; - if (item[(keys as Ref).value?.children ?? 'children']?.length) { - items[level + 1] = item[(keys as Ref).value?.children ?? 'children']; + if (item[keys?.children ?? 'children']?.length) { + items[level + 1] = item[keys?.children ?? 'children']; items.length = level + 2; stepIndex.value += 1; steps[level + 1] = placeholder.value; steps.length = level + 2; - } else if (item[(keys as Ref).value?.children ?? 'children']?.length === 0) { + } else if (item[keys?.children ?? 'children']?.length === 0) { childrenInfo.value = value; childrenInfo.level = level; } else { setCascaderValue( - item[(keys as Ref).value?.value ?? 'value'], + item[keys?.value ?? 'value'], items.map((item, index) => toRaw(item?.[selectedIndexes[index]])), ); close('finish'); @@ -135,6 +138,7 @@ export default defineComponent({ }; const cancelSelect = (value: RadioValue, level: number, index: number, item: any) => { + const keys = props.keys as KeysType; selectedIndexes[level] = index; selectedIndexes.length = level; selectedValue.length = level; @@ -142,23 +146,22 @@ export default defineComponent({ steps[level + 1] = placeholder.value; steps.length = level + 1; - if (item[(keys as Ref).value?.children ?? 'children']?.length) { - items[level + 1] = item[(keys as Ref).value?.children ?? 'children']; - } else if (item[(keys as Ref).value?.children ?? 'children']?.length === 0) { + if (item[keys?.children ?? 'children']?.length) { + items[level + 1] = item[keys?.children ?? 'children']; + } else if (item[keys?.children ?? 'children']?.length === 0) { childrenInfo.value = value; childrenInfo.level = level; } }; const handleSelect = (value: RadioValue, level: number) => { - const index = items[level].findIndex( - (item: any) => item[(keys as Ref).value?.value ?? 'value'] === value, - ); + const keys = props.keys as KeysType; + const index = items[level].findIndex((item: any) => item[keys?.value ?? 'value'] === value); const item = items[level][index]; if (item.disabled) { return; } - props.onPick?.({ level, value: item[(keys as Ref).value?.value ?? 'value'], index }); + props.onPick?.({ level, value: item[keys?.value ?? 'value'], index }); if (props.checkStrictly && selectedValue.includes(String(value))) { cancelSelect(value, level, index, item); @@ -325,7 +328,7 @@ export default defineComponent({
Date: Fri, 17 May 2024 14:38:58 +0800 Subject: [PATCH 6/6] =?UTF-8?q?test:=20=E6=B5=8B=E8=AF=95=E6=A1=88?= =?UTF-8?q?=E4=BE=8B=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cascader/__test__/index.test.jsx | 17 ++++++++++++----- src/cascader/cascader.tsx | 6 +++--- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/cascader/__test__/index.test.jsx b/src/cascader/__test__/index.test.jsx index 8c268cf31..4a758d238 100644 --- a/src/cascader/__test__/index.test.jsx +++ b/src/cascader/__test__/index.test.jsx @@ -287,19 +287,26 @@ describe('cascader', () => { }); describe('events', () => { - it(': close', async () => { + it(': close trigger closeBtn', async () => { const onClose = vi.fn(); const wrapper = mount(); const $closeBtn = wrapper.find(`.${name}__close-btn`); await $closeBtn.trigger('click'); expect(onClose).toHaveBeenCalledTimes(1); - expect(onClose).toHaveBeenLastCalledWith({ trigger: 'close-btn' }); + expect(onClose).toHaveBeenLastCalledWith('close-btn'); + + }); + + it(': close trigger overlay', async () => { + const onClose = vi.fn(); + const wrapper = mount(); // overlay - const $overlay = wrapper.find(`.${prefix}-overlay`); + const $overlay = wrapper.find(`.${prefix}-overlay--active`); + expect($overlay.exists()).toBeTruthy() $overlay.trigger('click'); - expect(onClose).toBeCalledTimes(2); - expect(onClose).toHaveBeenLastCalledWith({ trigger: 'overlay' }); + expect(onClose).toBeCalledTimes(1); + expect(onClose).toHaveBeenLastCalledWith('overlay'); }); it(': pick', async () => { diff --git a/src/cascader/cascader.tsx b/src/cascader/cascader.tsx index f7928fedf..ab38af7cf 100644 --- a/src/cascader/cascader.tsx +++ b/src/cascader/cascader.tsx @@ -21,8 +21,8 @@ import TdCascaderProps from './props'; import { useVModel } from '../shared'; import { TreeOptionData } from '../common'; import { useConfig } from '../config-provider/useConfig'; -import { useTNodeJSX } from '@/hooks/tnode'; -import { usePrefixClass } from '@/hooks/useClass'; +import { useTNodeJSX } from '../hooks/tnode'; +import { usePrefixClass } from '../hooks/useClass'; import { TriggerSource } from './type'; const { prefix } = config; @@ -66,7 +66,7 @@ export default defineComponent({ const steps = reactive([placeholder.value]); const initWithValue = () => { - if (value.value != null) { + if (cascaderValue.value != null) { steps.pop(); const path = getIndexesByValue(props.options, value.value); path?.forEach((e: number) => {