Skip to content

Commit e31533e

Browse files
authored
fix(components): [tree-select] cache data update incorrect (element-plus#11225)
1 parent 2734d50 commit e31533e

File tree

2 files changed

+77
-20
lines changed

2 files changed

+77
-20
lines changed

packages/components/tree-select/__tests__/tree-select.test.tsx

Lines changed: 66 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ const createComponent = ({
1616
props?: typeof TreeSelect['props']
1717
} = {}) => {
1818
const wrapperRef = ref<InstanceType<typeof TreeSelect>>()
19-
const value = props.modelValue || ref('')
20-
const data = ref([
19+
const defaultData = ref([
2120
{
2221
value: 1,
2322
label: '一级 1',
@@ -36,24 +35,33 @@ const createComponent = ({
3635
},
3736
])
3837

39-
const wrapper = mount({
40-
render() {
41-
return (
42-
<TreeSelect
43-
data={data.value}
44-
renderAfterExpand={false}
45-
{...props}
46-
modelValue={value.value}
47-
onUpdate:modelValue={(val: string) => (value.value = val)}
48-
ref={(val: InstanceType<typeof TreeSelect>) =>
49-
(wrapperRef.value = val)
50-
}
51-
v-slots={slots}
52-
/>
53-
)
54-
},
38+
const bindProps = reactive({
39+
modelValue: ref(''),
40+
data: defaultData,
41+
renderAfterExpand: false,
42+
...props,
5543
})
5644

45+
const wrapper = mount(
46+
{
47+
render() {
48+
return (
49+
<TreeSelect
50+
{...bindProps}
51+
onUpdate:modelValue={(val: string) => (bindProps.modelValue = val)}
52+
ref={(val: InstanceType<typeof TreeSelect>) =>
53+
(wrapperRef.value = val)
54+
}
55+
v-slots={slots}
56+
/>
57+
)
58+
},
59+
},
60+
{
61+
attachTo: 'body',
62+
}
63+
)
64+
5765
return {
5866
wrapper,
5967
getWrapperRef: () =>
@@ -485,4 +493,44 @@ describe('TreeSelect.vue', () => {
485493
await nextTick()
486494
expect(select.vm.selectedLabel).toBe('1-label')
487495
})
496+
497+
test('filter-method', async () => {
498+
const modelValue = ref(1)
499+
const data = ref([
500+
{ value: 1, label: '1' },
501+
{ value: 2, label: '2' },
502+
{ value: 3, label: '3' },
503+
])
504+
const filterMethod = vi.fn((val: string) => {
505+
data.value = [...data.value].filter((item) => item.label.includes(val))
506+
})
507+
const { select, tree } = createComponent({
508+
props: {
509+
modelValue,
510+
data,
511+
filterable: true,
512+
filterMethod,
513+
// trigger cache data
514+
renderAfterExpand: true,
515+
},
516+
})
517+
518+
await nextTick()
519+
expect(tree.vm.data.length).toBe(3)
520+
expect(select.vm.selectedLabel).toBe('1')
521+
522+
const input = select.find('input')
523+
input.element.focus()
524+
await nextTick()
525+
expect(select.vm.selectedLabel).toBe('')
526+
expect(filterMethod).toHaveBeenLastCalledWith('')
527+
528+
select.vm.selectedLabel = '2'
529+
select.vm.debouncedOnInputChange()
530+
// await debounce
531+
await new Promise((resolve) => setTimeout(resolve))
532+
expect(select.vm.selectedLabel).toBe('2')
533+
expect(filterMethod).toHaveBeenLastCalledWith('2')
534+
expect(tree.text()).toBe('2')
535+
})
488536
})

packages/components/tree-select/src/cache-options.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,18 @@ export default defineComponent({
2929
select.cachedOptions.set(item.value, item)
3030
}
3131
})
32-
select.setSelected()
32+
33+
// fork from packages/select/src/useSelect.ts#330
34+
const inputs = select.selectWrapper?.querySelectorAll('input') || []
35+
if (
36+
!Array.from(inputs).includes(
37+
document.activeElement as HTMLInputElement
38+
)
39+
) {
40+
select.setSelected()
41+
}
3342
},
34-
{ immediate: true, deep: true }
43+
{ flush: 'post', immediate: true }
3544
)
3645

3746
return () => undefined

0 commit comments

Comments
 (0)