From 9c7c5fb856c4f26a3bc523395de96a92f01989e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=98=BF=20Cai?= Date: Thu, 13 Feb 2025 14:36:06 +0800 Subject: [PATCH 1/4] fix(select): `checkAll` will check all filtered data of `reserveKeyword` --- .../select/hooks/useSelectOptions.ts | 2 +- packages/components/select/select.tsx | 40 ++++++++++++++----- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/packages/components/select/hooks/useSelectOptions.ts b/packages/components/select/hooks/useSelectOptions.ts index 4c8dfff3b8..60901a5ead 100644 --- a/packages/components/select/hooks/useSelectOptions.ts +++ b/packages/components/select/hooks/useSelectOptions.ts @@ -113,7 +113,7 @@ export const useSelectOptions = (props: TdSelectProps, keys: Ref, inpu if (isFunction(props.filter)) { return props.filter(`${inputValue.value}`, option); } - + if ((option as TdOptionProps)?.checkAll === true) return true; return option.label?.toLowerCase?.().indexOf(`${inputValue.value}`.toLowerCase()) > -1; }; diff --git a/packages/components/select/select.tsx b/packages/components/select/select.tsx index 14ba4e716a..2f8f531b88 100644 --- a/packages/components/select/select.tsx +++ b/packages/components/select/select.tsx @@ -22,7 +22,7 @@ import { useSelectOptions } from './hooks/useSelectOptions'; import useKeyboardControl from './hooks/useKeyboardControl'; import type { PopupProps, PopupVisibleChangeContext } from '../popup'; import type { SelectInputValueChangeContext } from '../select-input'; -import type { TdSelectProps, SelectValue } from './type'; +import type { TdSelectProps, SelectValue, TdOptionProps } from './type'; import { SelectInputValueDisplayOptions } from '../select-input/useSingle'; export default defineComponent({ @@ -215,6 +215,24 @@ export default defineComponent({ max: props.max, }); + /** + * 获取过滤后可以全选的选项 + * @returns 可选选项的列表的 value + */ + const getFilteredOptions = computed(() => { + const inputValue = innerInputValue.value.toLowerCase(); + return optionalList.value + .filter((option) => { + if (option.disabled) return false; + if (typeof props.filter === 'function') { + return props.filter(innerInputValue.value, option); + } + + return option.label.toLowerCase().includes(inputValue); + }) + .map((option) => option.value); + }); + /* * 全选逻辑: * 根据 checked 的值计算最终选中的值: @@ -224,23 +242,25 @@ export default defineComponent({ const onCheckAllChange = (checked: boolean) => { if (!props.multiple) return; const lockedValues = innerValue.value.filter((value: string | number | boolean) => { - return optionsList.value.find((item) => item.value === value && item.disabled); + return optionsList.value.some((item) => item.value === value && item.disabled); }); - const activeValues = optionalList.value.map((option) => option.value); - const values = checked ? [...new Set([...activeValues, ...lockedValues])] : [...lockedValues]; + const values = checked ? [...new Set([...getFilteredOptions.value, ...lockedValues])] : lockedValues.value; setInnerValue(values, { selectedOptions: getSelectedOptions(values), trigger: checked ? 'check' : 'clear' }); }; // 已选的长度 - const intersectionLen = computed(() => { - const values = optionalList.value.map((item) => item.value); - const n = intersection(innerValue.value, values); - return n.length; + const intersectionLen = computed(() => { + const validValues = new Set(getFilteredOptions.value); + return innerValue.value.filter((v: string | number | boolean) => validValues.has(v)).length; }); // 全选 - const isCheckAll = computed(() => { - return intersectionLen.value === optionalList.value.length; + const isCheckAll = computed(() => { + const filtered = getFilteredOptions.value; + if (filtered.length === 0) return false; + + const selectedSet = new Set(innerValue.value); + return filtered.every((v) => selectedSet.has(v)); }); // 半选 From c4ad31acf19ff89feee66a0e30ddc70238b289d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=98=BF=20Cai?= Date: Thu, 13 Feb 2025 15:28:20 +0800 Subject: [PATCH 2/4] fix: remove error data acquisition --- packages/components/select/select.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/components/select/select.tsx b/packages/components/select/select.tsx index 2f8f531b88..b14004ff2d 100644 --- a/packages/components/select/select.tsx +++ b/packages/components/select/select.tsx @@ -5,7 +5,6 @@ import { isFunction } from 'lodash-es'; import { debounce } from 'lodash-es'; import { cloneDeep } from 'lodash-es'; import { get } from 'lodash-es'; -import { intersection } from 'lodash-es'; import FakeArrow from '../common-components/fake-arrow'; import SelectInput from '../select-input'; import SelectPanel from './select-panel'; @@ -22,7 +21,7 @@ import { useSelectOptions } from './hooks/useSelectOptions'; import useKeyboardControl from './hooks/useKeyboardControl'; import type { PopupProps, PopupVisibleChangeContext } from '../popup'; import type { SelectInputValueChangeContext } from '../select-input'; -import type { TdSelectProps, SelectValue, TdOptionProps } from './type'; +import type { TdSelectProps, SelectValue } from './type'; import { SelectInputValueDisplayOptions } from '../select-input/useSingle'; export default defineComponent({ @@ -244,7 +243,7 @@ export default defineComponent({ const lockedValues = innerValue.value.filter((value: string | number | boolean) => { return optionsList.value.some((item) => item.value === value && item.disabled); }); - const values = checked ? [...new Set([...getFilteredOptions.value, ...lockedValues])] : lockedValues.value; + const values = checked ? [...new Set([...getFilteredOptions.value, ...lockedValues])] : lockedValues; setInnerValue(values, { selectedOptions: getSelectedOptions(values), trigger: checked ? 'check' : 'clear' }); }; From cf6aa53c54960877e0d09c1b5ab1fc98be0b802f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=98=BF=20Cai?= Date: Thu, 13 Feb 2025 15:39:50 +0800 Subject: [PATCH 3/4] =?UTF-8?q?fix:=20=E4=BD=BF=E7=94=A8=E5=8F=AF=E9=80=89?= =?UTF-8?q?=E9=81=BF=E5=85=8D=E7=A9=BA=E5=80=BC=E8=BF=9B=E8=A1=8C=20toLowe?= =?UTF-8?q?rCase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/components/select/select.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/components/select/select.tsx b/packages/components/select/select.tsx index b14004ff2d..d636531cc3 100644 --- a/packages/components/select/select.tsx +++ b/packages/components/select/select.tsx @@ -219,7 +219,7 @@ export default defineComponent({ * @returns 可选选项的列表的 value */ const getFilteredOptions = computed(() => { - const inputValue = innerInputValue.value.toLowerCase(); + const inputValue = innerInputValue.value?.toLowerCase(); return optionalList.value .filter((option) => { if (option.disabled) return false; @@ -227,7 +227,7 @@ export default defineComponent({ return props.filter(innerInputValue.value, option); } - return option.label.toLowerCase().includes(inputValue); + return option.label?.toLowerCase().includes(inputValue); }) .map((option) => option.value); }); From b1d908975261f1d169888a5fad64768a4671def3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=98=BF=20Cai?= Date: Thu, 13 Feb 2025 15:56:13 +0800 Subject: [PATCH 4/4] =?UTF-8?q?chore:=20=E6=9B=B4=E6=96=B0=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E5=BF=AB=E7=85=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/components/select/select.tsx | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/components/select/select.tsx b/packages/components/select/select.tsx index d636531cc3..6a50af6b3c 100644 --- a/packages/components/select/select.tsx +++ b/packages/components/select/select.tsx @@ -1,10 +1,5 @@ import { defineComponent, provide, computed, toRefs, watch, ref, nextTick, PropType } from 'vue'; -import { pick as picker } from 'lodash-es'; -import { isArray } from 'lodash-es'; -import { isFunction } from 'lodash-es'; -import { debounce } from 'lodash-es'; -import { cloneDeep } from 'lodash-es'; -import { get } from 'lodash-es'; +import { pick as picker, isArray, isFunction, debounce, cloneDeep, get, intersection } from 'lodash-es'; import FakeArrow from '../common-components/fake-arrow'; import SelectInput from '../select-input'; import SelectPanel from './select-panel'; @@ -249,8 +244,9 @@ export default defineComponent({ // 已选的长度 const intersectionLen = computed(() => { - const validValues = new Set(getFilteredOptions.value); - return innerValue.value.filter((v: string | number | boolean) => validValues.has(v)).length; + const values = optionalList.value.map((item) => item.value); + const n = intersection(innerValue.value, values); + return n.length; }); // 全选