fix(components): [tree-select] cache data update incorrect (#11225)

This commit is contained in:
yujinpan 2023-03-05 07:24:25 +08:00 committed by GitHub
parent 2734d50967
commit e31533e8fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 77 additions and 20 deletions

View File

@ -16,8 +16,7 @@ const createComponent = ({
props?: typeof TreeSelect['props']
} = {}) => {
const wrapperRef = ref<InstanceType<typeof TreeSelect>>()
const value = props.modelValue || ref('')
const data = ref([
const defaultData = ref([
{
value: 1,
label: '一级 1',
@ -36,24 +35,33 @@ const createComponent = ({
},
])
const wrapper = mount({
render() {
return (
<TreeSelect
data={data.value}
renderAfterExpand={false}
{...props}
modelValue={value.value}
onUpdate:modelValue={(val: string) => (value.value = val)}
ref={(val: InstanceType<typeof TreeSelect>) =>
(wrapperRef.value = val)
}
v-slots={slots}
/>
)
},
const bindProps = reactive({
modelValue: ref(''),
data: defaultData,
renderAfterExpand: false,
...props,
})
const wrapper = mount(
{
render() {
return (
<TreeSelect
{...bindProps}
onUpdate:modelValue={(val: string) => (bindProps.modelValue = val)}
ref={(val: InstanceType<typeof TreeSelect>) =>
(wrapperRef.value = val)
}
v-slots={slots}
/>
)
},
},
{
attachTo: 'body',
}
)
return {
wrapper,
getWrapperRef: () =>
@ -485,4 +493,44 @@ describe('TreeSelect.vue', () => {
await nextTick()
expect(select.vm.selectedLabel).toBe('1-label')
})
test('filter-method', async () => {
const modelValue = ref(1)
const data = ref([
{ value: 1, label: '1' },
{ value: 2, label: '2' },
{ value: 3, label: '3' },
])
const filterMethod = vi.fn((val: string) => {
data.value = [...data.value].filter((item) => item.label.includes(val))
})
const { select, tree } = createComponent({
props: {
modelValue,
data,
filterable: true,
filterMethod,
// trigger cache data
renderAfterExpand: true,
},
})
await nextTick()
expect(tree.vm.data.length).toBe(3)
expect(select.vm.selectedLabel).toBe('1')
const input = select.find('input')
input.element.focus()
await nextTick()
expect(select.vm.selectedLabel).toBe('')
expect(filterMethod).toHaveBeenLastCalledWith('')
select.vm.selectedLabel = '2'
select.vm.debouncedOnInputChange()
// await debounce
await new Promise((resolve) => setTimeout(resolve))
expect(select.vm.selectedLabel).toBe('2')
expect(filterMethod).toHaveBeenLastCalledWith('2')
expect(tree.text()).toBe('2')
})
})

View File

@ -29,9 +29,18 @@ export default defineComponent({
select.cachedOptions.set(item.value, item)
}
})
select.setSelected()
// fork from packages/select/src/useSelect.ts#330
const inputs = select.selectWrapper?.querySelectorAll('input') || []
if (
!Array.from(inputs).includes(
document.activeElement as HTMLInputElement
)
) {
select.setSelected()
}
},
{ immediate: true, deep: true }
{ flush: 'post', immediate: true }
)
return () => undefined