1- import {
2- type IfAny ,
3- isArray ,
4- isFunction ,
5- isOn ,
6- normalizeClass ,
7- normalizeStyle ,
8- } from '@vue/shared'
1+ import { type IfAny , isArray , isFunction } from '@vue/shared'
92import {
103 type EffectScope ,
114 effectScope ,
125 isReactive ,
13- pauseTracking ,
14- resetTracking ,
156 shallowReactive ,
167} from '@vue/reactivity'
178import {
@@ -25,6 +16,7 @@ import { createComment, createTextNode, insert, remove } from './dom/element'
2516import { VaporErrorCodes , callWithAsyncErrorHandling } from './errorHandling'
2617import type { NormalizedRawProps } from './componentProps'
2718import type { Data } from '@vue/runtime-shared'
19+ import { mergeProps } from './dom/prop'
2820
2921// TODO: SSR
3022
@@ -176,58 +168,44 @@ export function createSlot(
176168
177169function normalizeSlotProps ( rawPropsList : NormalizedRawProps ) {
178170 const ret = shallowReactive < Data > ( { } )
171+ const { length } = rawPropsList
172+ const isNeedToMerge = length > 1
173+ const dataCache = isNeedToMerge ? shallowReactive < Data [ ] > ( [ ] ) : undefined
179174
180- for ( let i = 0 ; i < rawPropsList . length ; i ++ ) {
175+ for ( let i = 0 ; i < length ; i ++ ) {
181176 const rawProps = rawPropsList [ i ]
182177 if ( isFunction ( rawProps ) ) {
183178 renderEffect ( ( ) => {
184179 const props = rawProps ( )
185- for ( const key in props ) {
186- setValue ( key , props [ key ] )
180+ if ( isNeedToMerge ) {
181+ dataCache ! [ i ] = props
182+ } else {
183+ for ( const key in props ) {
184+ ret [ key ] = props [ key ]
185+ }
187186 }
188187 } )
189188 } else {
189+ const itemRet = isNeedToMerge
190+ ? ( dataCache ! [ i ] = shallowReactive < Data > ( { } ) )
191+ : ret
190192 for ( const key in rawProps ) {
191193 const valueSource = rawProps [ key ]
192194 renderEffect ( ( ) => {
193- setValue ( key , valueSource ( ) )
195+ itemRet [ key ] = valueSource ( )
194196 } )
195197 }
196198 }
197199 }
198- return ret
199-
200- // In multiple effects, get and set the same reactive may cause stack overflow.
201- // So we need to pause tracking before get and reset tracking after set.
202- function getValue ( key : string ) {
203- pauseTracking ( )
204- const value = ret [ key ]
205- resetTracking ( )
206- return value
207- }
208200
209- function setValue ( key : string , value : unknown ) {
210- if ( key === 'class' ) {
211- const existing = getValue ( 'class' )
212- if ( existing !== value ) {
213- ret . class = normalizeClass ( [ existing , value ] )
201+ if ( isNeedToMerge ) {
202+ renderEffect ( ( ) => {
203+ const props = mergeProps ( ... dataCache ! )
204+ for ( const key in props ) {
205+ ret [ key ] = props [ key ]
214206 }
215- } else if ( key === 'style' ) {
216- ret . style = normalizeStyle ( [ getValue ( 'class' ) , value ] )
217- } else if ( isOn ( key ) ) {
218- const existing = getValue ( key )
219- const incoming = value
220- if (
221- incoming &&
222- existing !== incoming &&
223- ! ( isArray ( existing ) && existing . includes ( incoming ) )
224- ) {
225- ret [ key ] = existing
226- ? [ ] . concat ( existing as any , incoming as any )
227- : incoming
228- }
229- } else if ( key !== '' ) {
230- ret [ key ] = value
231- }
207+ } )
232208 }
209+
210+ return ret
233211}
0 commit comments