@@ -234,6 +234,69 @@ describe('Select', () => {
234234 panelNode . parentNode . removeChild ( panelNode ) ;
235235 } ) ;
236236 } ) ;
237+ describe ( 'onCreate #6228' , ( ) => {
238+ it ( 'should correctly pass created option data when onCreate uses async operation' , async ( ) => {
239+ const onChangeFn = vi . fn ( ) ;
240+ const value = ref ( '' ) ;
241+ const optionsRef = ref ( [
242+ { label : '选项一' , value : '1' } ,
243+ { label : '选项二' , value : '2' } ,
244+ ] ) ;
245+
246+ const wrapper = mount ( {
247+ setup ( ) {
248+ return { value, options : optionsRef } ;
249+ } ,
250+ render ( ) {
251+ return (
252+ < Select
253+ v-model = { value . value }
254+ creatable
255+ filterable
256+ options = { optionsRef . value }
257+ onChange = { onChangeFn }
258+ onCreate = { ( val ) => {
259+ // Simulate async operation (e.g., checking with backend)
260+ setTimeout ( ( ) => {
261+ optionsRef . value . push ( { label : String ( val ) , value : val } ) ;
262+ } , 100 ) ;
263+ } }
264+ />
265+ ) ;
266+ } ,
267+ } ) ;
268+
269+ // Open the popup and type to create a new option
270+ const input = wrapper . find ( '.t-input' ) ;
271+ await input . trigger ( 'click' ) ;
272+ await wrapper . setProps ( { popupProps : { visible : true } } ) ;
273+
274+ // Simulate typing in the input
275+ const textbox = wrapper . find ( 'input' ) ;
276+ await textbox . setValue ( 'newOption' ) ;
277+ await nextTick ( ) ;
278+
279+ // Wait for the create option to appear
280+ await nextTick ( ) ;
281+
282+ // Click the create option
283+ const createOption = document . querySelector ( '.t-select__create-option--special' ) ;
284+ if ( createOption instanceof HTMLElement ) {
285+ createOption . click ( ) ;
286+ await nextTick ( ) ;
287+
288+ // Verify onChange was called with the correct option data
289+ expect ( onChangeFn ) . toHaveBeenCalled ( ) ;
290+ const [ newValue , context ] = onChangeFn . mock . calls [ 0 ] ;
291+ expect ( newValue ) . toBe ( 'newOption' ) ;
292+ // The fix ensures option is correctly constructed from props even before async onCreate completes
293+ expect ( context . option ) . toEqual ( expect . objectContaining ( { value : 'newOption' , label : 'newOption' } ) ) ;
294+ }
295+
296+ const panelNode = document . querySelector ( '.t-select__list' ) ;
297+ panelNode ?. parentNode ?. removeChild ( panelNode ) ;
298+ } ) ;
299+ } ) ;
237300 } ) ;
238301
239302 describe ( 'keys' , ( ) => {
@@ -426,67 +489,3 @@ describe('Select CheckAll with Disabled Option', () => {
426489 cleanup ( ) ;
427490 } ) ;
428491} ) ;
429-
430- describe ( 'Select Creatable with Async onCreate' , ( ) => {
431- it ( 'should correctly pass created option data when onCreate uses async operation' , async ( ) => {
432- const onChangeFn = vi . fn ( ) ;
433- const value = ref ( '' ) ;
434- const optionsRef = ref ( [
435- { label : '选项一' , value : '1' } ,
436- { label : '选项二' , value : '2' } ,
437- ] ) ;
438-
439- const wrapper = mount ( {
440- setup ( ) {
441- return { value, options : optionsRef } ;
442- } ,
443- render ( ) {
444- return (
445- < Select
446- v-model = { value . value }
447- creatable
448- filterable
449- options = { optionsRef . value }
450- onChange = { onChangeFn }
451- onCreate = { ( val ) => {
452- // Simulate async operation (e.g., checking with backend)
453- setTimeout ( ( ) => {
454- optionsRef . value . push ( { label : String ( val ) , value : val } ) ;
455- } , 100 ) ;
456- } }
457- />
458- ) ;
459- } ,
460- } ) ;
461-
462- // Open the popup and type to create a new option
463- const input = wrapper . find ( '.t-input' ) ;
464- await input . trigger ( 'click' ) ;
465- await wrapper . setProps ( { popupProps : { visible : true } } ) ;
466-
467- // Simulate typing in the input
468- const textbox = wrapper . find ( 'input' ) ;
469- await textbox . setValue ( 'newOption' ) ;
470- await nextTick ( ) ;
471-
472- // Wait for the create option to appear
473- await nextTick ( ) ;
474-
475- // Click the create option
476- const createOption = document . querySelector ( '.t-select__create-option--special' ) ;
477- if ( createOption ) {
478- createOption . click ( ) ;
479- await nextTick ( ) ;
480-
481- // Verify onChange was called with the correct option data
482- expect ( onChangeFn ) . toHaveBeenCalled ( ) ;
483- const [ newValue , context ] = onChangeFn . mock . calls [ 0 ] ;
484- expect ( newValue ) . toBe ( 'newOption' ) ;
485- // The fix ensures option is correctly constructed from props even before async onCreate completes
486- expect ( context . option ) . toEqual ( expect . objectContaining ( { value : 'newOption' , label : 'newOption' } ) ) ;
487- }
488-
489- const panelNode = document . querySelector ( '.t-select__list' ) ;
490- if ( panelNode ) panelNode . parentNode . removeChild ( panelNode ) ;
491- } ) ;
492- } ) ;
0 commit comments