0👍
✅
Hmmm. first of all there is a typeo, so f-for
should be v-for
.
Also, template goes like this:
<template>
<ul>
<TreeItem class="item" v-for="(tree, index) in listOfTrees" :model="tree" :key="index"></TreeItem>
</ul>
</template>
So, iteration goes like this on vue.
Don’t hesitate if you need more explanation.
0👍
You probably should reorganize listOfTrees using only objects
(simplify the recursion of the component),
(Styles - for example - for a visual demonstration),
but it is for your case:
Tree Component
<template>
<div class="flexCol">
<template v-for="item in listOfTrees">
<template v-for="(value, key) in item">
<div v-if="key === 'name'" class="group">Name: {{value}}</div>
<template v-else-if="key === 'children'">
<Menutree :menuPart="value"></Menutree>
</template>
</template>
</template>
</div>
</template>
<script setup>
import {ref} from 'vue'
import Menutree from './Menutree'
const listOfTrees = ref( [{
name: 'My Tree 2',
children: [
{name: 'hello1'},
{name: 'world1'},
{
name: 'child of My Tree 2',
children: [
{
name: 'child 1 of child of My Tree 2',
children: [{name: 'hello'}, {name: 'world'}]
},
]
}
]
}, {
name: 'My Tree',
children: [
{name: 'hello'},
{name: 'world'},
{
name: 'child of My Tree ',
children: [
{
name: 'child 1 of child of My Tree',
children: [{name: 'hello'}, {name: 'world'}]
},
{name: 'hello'},
{name: 'world'},
{
name: 'child 2 of child of My Tree',
children: [{name: 'hello'}, {name: 'world'}]
}
]
}
]
}
])
</script>
<style scoped>
.flexCol {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
}
.group {
width: 10rem;
text-align: center;
background-color: #97e6f3;
padding: 0.25rem 0;
margin: 0.25rem;
}
</style>
Module - Menutree
<template>
<div class="flexCol">
<template v-for="item in menuPart">
<template v-for="(valueBase, keyBase) in item">
<div v-if="keyBase === 'name'" style="margin-left: 3rem"
class="subGroup">Name: {{valueBase}}</div>
<template v-else-if="keyBase === 'children'">
<template v-for="subitem in valueBase">
<div v-if="subitem['name']" style="margin-left: 6rem"
class="subSubGroup">SubName: {{subitem['name']}}</div>
<Menutree :menuPart="subitem['children']" style="margin-
left:6rem; background-color: lightyellow"></Menutree>
</template>
</template>
</template>
</template>
</div>
</template>
<script setup>
import {ref} from 'vue'
defineProps(['menuPart'])
</script>
<style scoped>
.flexCol {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
}
.subGroup {
width: auto;
text-align: left;
background-color: #f4e1cc;
padding: 0.25rem;
margin: 0.25rem 3rem;
}
.subSubGroup {
width: auto;
text-align: left;
background-color: #d6f4cc;
padding: 0.25rem;
margin: 0.25rem 6rem;
}
</style>
0👍
Before, I gave an example for the case of unknown nesting of data.
However, if you know for sure that the maximum nesting level is 3 (this is enough for a menu, for example), then everything is generally easier and more convenient for styling and event handling.
<template>
<div class="flexCol">
<template v-for="item in listOfTrees">
<template v-for="(value, key) in item">
<div v-if="key === 'name'" class="group">Name: {{value}}</div>
<template v-if="key === 'children' && value.length > 0">
<template v-for="sub1 in value">
<div v-if="sub1['name']" style="margin-left: 3rem">Sub1:
{{sub1['name']}}</div>
<template v-if="sub1['children']?.length > 0">
<template v-for="sub2 in sub1['children']">
<div v-if="sub2['name']" style="margin-left:
6rem">Sub2: {{sub2['name']}}</div>
<template v-if="sub2['children']?.length > 0">
<div v-for="sub3 in sub2['children']">
<div v-if="sub3['name']" style="margin-left:
9rem">Sub3: {{sub3['name']}}</div>
</div>
</template>
</template>
</template>
</template>
</template>
</template>
</template>
</div>
</template>
Source:stackexchange.com