diff --git a/packages/vuetify/src/components/VTreeview/VTreeview.ts b/packages/vuetify/src/components/VTreeview/VTreeview.ts index 0c5b0feed73e..29d662d7a9aa 100644 --- a/packages/vuetify/src/components/VTreeview/VTreeview.ts +++ b/packages/vuetify/src/components/VTreeview/VTreeview.ts @@ -28,6 +28,7 @@ import { filterTreeItems, filterTreeItem, } from './util/filterTreeItems' +import { preventLoops } from '@/util/nested' type VTreeviewNodeInstance = InstanceType @@ -307,6 +308,7 @@ export default mixins( const parents = [] while (parent !== null) { + preventLoops(parents, parent) parents.push(parent) parent = this.nodes[parent].parent } diff --git a/packages/vuetify/src/composables/nested/nested.ts b/packages/vuetify/src/composables/nested/nested.ts index 5f80f4da0906..753f159fddc6 100644 --- a/packages/vuetify/src/composables/nested/nested.ts +++ b/packages/vuetify/src/composables/nested/nested.ts @@ -18,6 +18,7 @@ import { leafSingleSelectStrategy, } from './selectStrategies' import { getCurrentInstance, getUid, propsFactory } from '@/util' +import { preventLoops } from '@/util/nested' // Types import type { InjectionKey, PropType, Ref } from 'vue' @@ -182,6 +183,7 @@ export const useNested = (props: NestedProps) => { let parent: unknown = id while (parent != null) { + preventLoops(path, parent) path.unshift(parent) parent = parents.value.get(parent) } diff --git a/packages/vuetify/src/labs/VTreeview/VTreeview.tsx b/packages/vuetify/src/labs/VTreeview/VTreeview.tsx index d4079447da04..237c0543a1b3 100644 --- a/packages/vuetify/src/labs/VTreeview/VTreeview.tsx +++ b/packages/vuetify/src/labs/VTreeview/VTreeview.tsx @@ -10,6 +10,7 @@ import { useProxiedModel } from '@/composables/proxiedModel' // Utilities import { computed, provide, ref, toRaw, toRef } from 'vue' import { genericComponent, omit, propsFactory, useRender } from '@/util' +import { preventLoops } from '@/util/nested' // Types import { VTreeviewSymbol } from './shared' @@ -98,6 +99,7 @@ export const VTreeview = genericComponent( const path: unknown[] = [] let parent: unknown = id while (parent != null) { + preventLoops(path, parent) path.unshift(parent) parent = vListRef.value?.parents.get(parent) } diff --git a/packages/vuetify/src/util/nested.ts b/packages/vuetify/src/util/nested.ts new file mode 100644 index 000000000000..488e144c9ef9 --- /dev/null +++ b/packages/vuetify/src/util/nested.ts @@ -0,0 +1,9 @@ +export function preventLoops (path: T[] | Set | Map, itemToPush: T) { + if ( + (Array.isArray(path) && path.includes(itemToPush)) || + (path instanceof Set && path.has(itemToPush)) || + (path instanceof Map && path.has(itemToPush)) + ) { + throw new Error('[Vuetify] Could not resolve nested path because of duplicated identifiers') + } +}