Can you verify my comprehension of the process for iteratively displaying numerous custom Tree components in Vue.js 3?

While exploring the Vue.js documentation, I came across an example of iteratively rendering a Tree using the v-for directive. My aim was to modify the code to render multiple TreeItems in the App.vue file.

I am puzzled by the fact that it is possible to iteratively render TreeItem by passing down a list of children objects in the 'TreeItem.vue' file but not when attempting to do so in App.vue. Despite reading through the docs, the usage of v-for seems inconsistent with how it works in 'TreeItem.vue'.

I would appreciate any explanation or insight into this matter!

Original code example: https://vuejs.org/examples/#tree

My initial attempt within the TreeItem component using v-for:

const listOfTrees = ref([{
  name: 'My Tree 2',
  children: [
    { name: 'hello' },
    { name: 'world' },
    {
      name: 'child folder',
      children: [
        {
          name: 'child folder',
          children: [{ name: 'hello' }, { name: 'world' }]
        },
      ]
    }
  ]
},{
  name: 'My Tree',
  children: [
    { name: 'hello' },
    { name: 'world' },
    {
      name: 'child folder',
      children: [
        {
          name: 'child folder',
          children: [{ name: 'hello' }, { name: 'world' }]
        },
        { name: 'hello' },
        { name: 'world' },
        {
          name: 'child folder',
          children: [{ name: 'hello' }, { name: 'world' }]
        }
      ]
    }
  ]
}
])


<template>
  <ul>
    <TreeItem class="item" f-for="tree in listOfTrees" :model="treeData"></TreeItem>
  </ul>
</template>

I managed to achieve the desired result by iterating div elements in the second approach:

<template>
  <!-- Wrapped the entire ul in a div and iterate the div's -->
  <div v-for= "tree in listOfTrees">
    <ul>
        <TreeItem class="item" :model="tree"></TreeItem>
    </ul>
  </div>
</template>

The success of the second attempt raises the question of why the initial method did not produce the expected outcome. Your insights are welcomed!

Answer №1

To improve the organization of listOfTrees, consider restructuring it using only objects to simplify the component recursion process. Implement styles for a more visually appealing demonstration. Here is an example tailored to your specific 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>

Answer №2

In a previous example, I demonstrated how to handle unknown nesting of data structures. However, if you are certain that the maximum nesting level is 3 (which is sufficient for scenarios like menus), styling and event handling become much simpler and more convenient.

<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>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The angular 5 application encountered an issue where it was unable to access the property 'singlePost' due to a null value, resulting

When using the once method to fetch data from the Firebase database, everything works correctly. However, when I try to use the on method, I encounter an error that says: ERROR TypeError: Cannot read property 'singlePost' of null. How can I prope ...

Achieving multiple validations on a single element in AngularJS, along with the ability to validate

Currently, I am in the process of constructing a form and utilizing the built-in AngularJS validation objects to validate the form. The following is an overview of my form: <form name="myForm" ng-submit="DoSomething()" novalidate> <te ...

retrieve the value of an HTML element once it has been modified

When I am working in a view, I encounter an issue where I need to retrieve the value of an HTML input box after it has been changed. Initially, the page loads with the following code: <input id="input_one" type="text" value = "apple" /> Upon loadin ...

Javascript: regular expression to validate alphanumeric and special characters

Looking to create a regular expression for a string (company/organization name) with the following conditions: No leading or trailing spaces No double spaces in between Shouldn't allow only a single character (alphanumeric or whitelisted) Can start ...

Sort the inner array within an outer array

const dataArray = [ { id: 1, title: "stuffed chicken is tasty as anything", picture: "./img/chicken.jpg", tags: ["oooo", "tasty", "stuffed"] }, { id: 2, title: "noodles with shrimp and salad", ...

When a model is changed from within a jQuery event, Angular 2 fails to update the view

During the development process, I encountered an issue while creating a custom search panel that displayed search results in a dropdown container. In my controller, I defined the following: export class ProductSearchComponent implements OnInit { publ ...

The challenge of navigating through $scope

In my Angular view/form, I have an input file element that is being utilized with ng-upload. The code snippet looks like this: <input id="img" type="file" name="image" onchange="angular.element(this).scope().setFile(this)"> <input id="imgname" ty ...

Having trouble retrieving a value within the jQuery.ajax success function

I need to implement jQuery Validator in order to validate if a user's desired username is available during the sign-up process. The PHP script untaken.php is responsible for checking this, returning either ok if the username is free or taken if it is ...

Does Vue.js interfere with classList.remove functionality?

When working with Vue.js, I encountered an issue where elements would briefly flash curly braces to the user before being hidden. To combat this problem, I implemented the following solution: HTML: <div class="main hide-me" id="my-vue-element"> ...

Can a function be passed as props in a scenario where both a Parent and Child component are functional components?

I have a component called ParentComponent where I am trying to pass a function named toggleDrawer to another component called ChildComponent in the following way: const ParentComponent = () { const [drawerState, setDrawerState] = useState(false); ...

The Facebook Like Button appears on Firefox but not on Internet Explorer due to Javascript errors

Hello everyone, I could really use some help with an issue I am facing. My Facebook like button works perfectly fine in Firefox, but when it comes to Internet Explorer, I keep encountering Javascript errors and the button doesn't show up at all: If y ...

Starting Array index value at 1 in React js: A step-by-step guide

Is there a way to make the index value start from 1 instead of 0? {props.useraccountListData.useraccountTypeList.map((item, index) => ( {index} ))} The current output is starting from 0, 1, 2. However, I would like it to start from 1, 2, 3... ...

How to access iFrame in ReactJS using document.getElementById

I am facing a challenge on my website where I need to transfer data (using postMessage) to an iframe. Typically in plain JavaScript, I would use techniques like document.getElementById or $("#iframe") in jQuery to target the iframe. However, I am unsure ...

What is the reason for the neglect of this function's definition?

Is there a reason behind the error message I am receiving? TypeError: getStatusCode(...) is not a function This error occurs when I execute the following code: const getStatusCode = require('./getStatusCode') tmpStatus = await getStatusCode({url ...

How to effectively leverage useMediaQuery in material ui?

Upon completing the web application, I have made the decision to ensure it is mobile-friendly. Utilizing the material UI framework with react, I delved into the documentation but found myself uncertain about how to effectively implement it. Let me provide ...

Is there a way to determine completion of page loading in an AngularJS application using JavaScript?

I am currently in the process of crafting Robot Framework tests to address specific use cases for an external AngularJS application. One of my requirements is the utilization of Python 3.5+ and SeleniumLibrary instead of the outdated Selenium2Library. In ...

An issue occurred during the construction of an angular project: The Tuple type '[]' with a length of '0' does not contain any elements at index '0'

When I run the command ng build --prod, I encounter the following error: ERROR in src/app/inventory/inv-parts-main-table/dialog-component/dialog-component.component.html(5,16): Tuple type '[]' of length '0' has no element at index &apo ...

Navigate through intricate nested JSON array structures in JavaScript

nested json structure Json Tree Structure: { "id": "30080", "dataelements": { "Name": "abc" }, "children": [ { "id": "33024", "dataelements": { "Name": "a" }, "children": [ { "id": "33024", ...

What is the process for converting strings or text to EBCDIC using JavaScript?

In the midst of developing a website, I am working on a feature that allows users to input a minimum of 256 characters/strings (with code verification), choose between ASCII or EBCDIC conversion, and view the converted text string displayed on the page bas ...

$q.all - successfully resolving some HTTP requests while encountering errors on others

I encountered a coding scenario like this angular.forEach(config.tvshows.shows, function(show) { promises.push($http.get('http://epguides.frecar.no/show/' + show.replace(/\s|\./g, '') + '/next/')); }); re ...