Skip to content

Commit d83b89b

Browse files
committed
fix(nested): react to items changes
fixes #21733
1 parent 3622fe8 commit d83b89b

File tree

3 files changed

+37
-7
lines changed

3 files changed

+37
-7
lines changed

packages/vuetify/src/composables/nested/nested.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import {
3131
leafSingleSelectStrategy,
3232
trunkSelectStrategy,
3333
} from './selectStrategies'
34-
import { consoleError, getCurrentInstance, propsFactory } from '@/util'
34+
import { consoleError, getCurrentInstance, propsFactory, throttle } from '@/util'
3535

3636
// Types
3737
import type { InjectionKey, MaybeRefOrGetter, PropType, Ref } from 'vue'
@@ -220,6 +220,11 @@ export const useNested = (props: NestedProps) => {
220220

221221
const nodeIds = new Set<unknown>()
222222

223+
const itemsUpdatePropagation = throttle(() => {
224+
children.value = new Map(children.value)
225+
parents.value = new Map(parents.value)
226+
}, 100)
227+
223228
const nested: NestedProvide = {
224229
id: shallowRef(),
225230
root: {
@@ -255,6 +260,7 @@ export const useNested = (props: NestedProps) => {
255260
if (parentId != null) {
256261
children.value.set(parentId, [...children.value.get(parentId) || [], id])
257262
}
263+
itemsUpdatePropagation()
258264
},
259265
unregister: id => {
260266
if (isUnmounted) return
@@ -268,6 +274,7 @@ export const useNested = (props: NestedProps) => {
268274
children.value.set(parent, list.filter(child => child !== id))
269275
}
270276
parents.value.delete(id)
277+
itemsUpdatePropagation()
271278
},
272279
open: (id, value, event) => {
273280
vm.emit('click:open', { id, value, path: getPath(id), event })

packages/vuetify/src/composables/nested/selectStrategies.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ export const classicSelectStrategy = (mandatory?: boolean): SelectStrategy => {
193193
return selected
194194
},
195195
in: (v, children, parents, disabled) => {
196+
console.log('classicSelectStrategy:in', parents.size, children.size)
196197
let map = new Map()
197198

198199
for (const id of (v || [])) {

packages/vuetify/src/util/helpers.ts

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -419,15 +419,37 @@ export function debounce (fn: Function, delay: MaybeRef<number>) {
419419
return wrap
420420
}
421421

422-
export function throttle<T extends (...args: any[]) => any> (fn: T, limit: number) {
422+
export function throttle<T extends (...args: any[]) => any> (
423+
fn: T,
424+
delay: number,
425+
options = { leading: false, trailing: true },
426+
) {
427+
let timeoutId = 0
428+
let lastExec = 0
423429
let throttling = false
424-
return (...args: Parameters<T>): void | ReturnType<T> => {
425-
if (!throttling) {
426-
throttling = true
427-
setTimeout(() => throttling = false, limit)
428-
return fn(...args)
430+
431+
const wrap = (...args: Parameters<T>): void | ReturnType<T> => {
432+
clearTimeout(timeoutId)
433+
const now = Date.now()
434+
const elapsed = now - lastExec
435+
436+
if ((!throttling && options.leading) || elapsed >= delay) {
437+
lastExec = now
438+
window.setTimeout(() => fn(...args)) // ignore 'fn' executin errors
429439
}
440+
441+
throttling = true
442+
timeoutId = window.setTimeout(() => {
443+
throttling = false
444+
if (options.trailing) {
445+
fn(...args)
446+
}
447+
}, delay)
430448
}
449+
450+
wrap.clear = () => clearTimeout(timeoutId)
451+
wrap.immediate = fn
452+
return wrap
431453
}
432454

433455
export function clamp (value: number, min = 0, max = 1) {

0 commit comments

Comments
 (0)