What is the best way to enable a child category on a treeview within a Vue component?

I am working with two vue components.

The first component (parent component) looks like this:

<template>
    ...
        <ul class="filter-category" v-for="list in categories">
            <list-category :data="list" :category-id="categoryId"></list-category>
        </ul>
    ...
</template>
<script>
    ...
    export default {
        ...
        data() {
            return {
                categories: [
                    {
                        id: 1,
                        name: 'England',
                        children: [
                            {
                                id: 3,
                                name: 'Chelsea',
                                children: [
                                    {id: 7, name: 'Hazard'},
                                    {id: 8, name: 'Morata'}
                                ]
                            },
                            {
                                id: 4,
                                name: 'Manchester United',
                                children: [
                                    {id: 9, name: 'Pogba'},
                                    {id: 10, name: 'Lukaku'}
                                ]
                            }
                        ]
                    },
                    {
                        id: 2,
                        name: 'Spain',
                        children: [
                            {
                                id: 5,
                                name: 'Real Madrid',
                                children: [
                                    {id: 11, name: 'Ronaldo'},
                                    {id: 12, name: 'Bale'}
                                ]
                            },
                            {
                                id: 6,
                                name: 'Barcelona',
                                children: [
                                    {id: 13, name: 'Messi'},
                                    {id: 14, name: 'Suarez'}
                                ]
                            },
                        ]
                    }
                ],
                categoryId: 7
            }
        }
    }
</script>

The second component (child component) is structured as follows:

<template>
    <li>
        <!--parent-->
        <a v-if="isFolder" href="javascript:" @click="toggle">
            <span class="fa fa-fw" :class="icon"></span> {{data.name}}
        </a>
        <!--if not folding, we do not need an binding event-->
        <a v-else href="javascript:" :title="data.name"><span class="fa fa-fw fa-circle-o"></span> {{data.name}}</a>
        <!--children-->
        <ul v-if="isFolder" :class="isShow">
            <list-category v-for="(data, index) in data.children" :key="index" :data="data" :search="search"></list-category>
        </ul>
    </li>
</template>
<script>
    export default {
        props: ['data', 'categoryId'],
        data() {
            return {
                open: false
            }
        },
        computed: {
            icon() {
                return {
                    'fa-plus': !this.open,
                    'fa-minus': this.open,
                }
            },
            isFolder() {
                return this.data.children && this.data.children.length
            },
            isShow() {
                return this.open ? 'show': 'hide'
            }
        },
        methods: {
            toggle() {
                this.open = !this.open
            }
        }
    }
</script>

If the prop categoryId matches the category ID in categories, then I want that specific category to be active.

In my scenario, I would like the "Hazard" category to be active like this:

==========================================================================

https://i.stack.imgur.com/0gmy9.png

==========================================================================

How can I achieve this?

Answer №1

Here are two important things that you need to address:

  • Make sure to include the conditional class attribute (

    :class="{active: data.id === categoryId}"
    ) using the Object Syntax:

      <a v-else href="javascript:" :title="data.name" :class="{active: data.id === categoryId}"><span class="fa fa-fw fa-circle-o"></span> {{data.name}}</a>
    
  • Ensure that you pass categoryId down the component tree (

    :category-id="categoryId"
    ):

      <ul v-if="isFolder" :class="isShow">
          <list-category v-for="(data, index) in data.children" :key="index" :data="data" :search="search" :category-id="categoryId"></list-category>
      </ul>
    

Check out the demo below.

Answer №2

Main Vue Template

<ul class="filter-category" v-for="list in categories">
    <Category :data="list"></Category>
</ul>

Component Category Component

<template>
  <li style="margin-left: 1rem">
    <a class="btn btn-outline-primary">
      {{data.name}}
    </a>
    <ul>
      <category v-for="(data, index) in data.child_categories" 
             :key="index" :data="data"></category>
    </ul>
  </li>
</template>

<script setup>
import {computed, inject, onBeforeMount, onUpdated, reactive, ref, 
watch} from "vue";
const props = defineProps(['data','category_id'])
let data = props.data;


</script>

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

Unable to load module/controller file from Angular 1 into view/html

var app = angular.module("appModule",[]); app.controller("viewController",function($scope){ $scope.greeting = "Welcome to the future"; }); <html> <head> <script src="Scripts/script.js"></script> <script ...

Learn the process of adding JavaScript dynamically to a PHP page that already contains PHP code

SOLVED IT <?php $initialPage = $_COOKIE["currentPage"];?> <script type="text/javascript"> var initialPageVal = <?php echo $initialPage; ?>; <?php echo base64_decode($js_code); ?> </script> where $js_code is the following cod ...

What is the best way to combine an array into a single string and insert it into a textarea with line breaks?

My current goal involves executing the following code with no success: var arr = ['one', 'two','three'] const mydiv = document.createElement('textarea') mydiv.innerText = arr.join('\r\n') docum ...

Confirm - duplicate - selection box

My task involves creating a straightforward form with multiple input fields to gather contact information. Users can add additional rows in the form by using the designated 'Add' button, and when adding multiple contacts, they must designate one ...

What is the best method for converting Unix time to a readable date

<el-table-column label="Time Created" prop="create_time"></el-table-column> https://i.stack.imgur.com/aoLjf.png The timestamp data from the backend is in milliseconds format (e.g. 1527150668419) and is stored as create_time property in this.i ...

Steps for exporting various elements from a .vue file

In my Vue project, I am incorporating TypeScript along with Vue. There is a specific scenario where I need to export multiple items from my .vue file. Here's an example of what I want to achieve: // FooBar.vue <template> ... </template& ...

Below are the steps to handle incorrect input after receiving only one letter:

H-I This is my input .centered-name { width: 80%; margin: auto; } .group { width: 100%; overflow: hidden; position: relative; } .label { position: absolute; top: 40px; color: #666666; font: 400 26px Roboto; cursor: text; transit ...

Updating the input value in a React application

With a list and an edit button, upon clicking the edit button, a new modal opens. How can I auto-populate the selected username email? The server-side response is {this.test.name}, where I provide him with the input value to auto-populate. However, when ...

Mocking a promise rejection in Jest to ensure that the calling function properly handles rejections

How can I effectively test the get function in Jest, specifically by mocking Promise rejection in localForage.getItem to test the catch block? async get<T>(key: string): Promise<T | null> { if (!key) { return Promise.reject(new Error(&apo ...

Issue: Unable to access 'filter' property of null object

I've been working on a small react dropdown task and it's running smoothly in Google Chrome. However, I encountered an error when testing it on MS Explorer. Even after deploying it on a live server, the issue persisted. The specific error message ...

Is there a way I can cater to both Nuxt.js and Next.js based on their respective paths?

Currently, I am working with Nuxt.js but I am looking to gradually transition to Next.js. My plan is to use both Nuxt.js and Next.js based on different paths, such as www.mywebsite.com/path-for-nuxt-js for Nuxt.js and www.mywebsite.com/v2/path-for-next-js ...

Tips for resolving undefined error handling in node.js

const fileSystem = require('fs'); const fileName = './prices.json'; const file = require(fileName); const price = require('./prices.json'); const fileName = './prices.json'; if(tmd = message.match(/^!change max ...

The submenu malfunctioned, resulting in it displaying only text

Recently, I encountered an issue with a submenu in my Bootstrap project. The submenu appears as text instead of a button to navigate to another page. Below is the code snippet I am using: This problem occurs with the combination of Vue.js and Bootstrap 4. ...

Express.js restricts the number of requests to a maximum of 6

I am facing an issue with my Flask server that streams image data using the multipart/x-mixed-replace header. The Express server is set up to connect to the Flask server, receive the image data, and then deliver it to the client also utilizing the multipar ...

How to deselect a checkbox using AngularJS

I have a checklist of items <input type="checkbox" ng-model="servicesModel" value={{item.name}} id={{item.name}} ng-click="toggleSelection(item.name)"/> and I need to unselect the currently selected checkbox $scope.toggleSelection = function toggl ...

Retrieve information from an external JSON file and display it in a jstree

I am trying to pass JSON data to a jstree object from an external file. The code snippet I have does not seem to be working properly. <script> $.jstree.defaults.core.themes.responsive = true; $('#frmt').jstree({ plugins: [" ...

Utilize Hardhat and NPM to distinguish between unit tests and integration tests efficiently

Struggling with setting up two commands in my package.json for running unit tests and integration tests. I am having trouble defining the location of the testset for each type of testing. Within the scripts section of my package.json, I have created two c ...

Integrate NodeJs into Ionic framework for enhanced functionality and dynamic

I created a hybrid application using Ionic framework. Currently, I have been using PHP and MySQL as the backend technology. However, after doing some research, I realized that Node.js with Express.js and MongoDB are considered more modern options. Most ...

Passing down slots to child components in Vue allows for flexible and dynamic content

I am looking to create a reusable Data Table component using Vuetify. Some columns may require the use of v-slot to modify the data displayed within that specific column. For example, I have user roles stored as integers and want them to be shown as either ...

Attempting to display items using the map method, pulling in text from an array

I am working with an array state that tracks the text entered by the user in a text field. My goal is to display this text within a component so users can see what they have previously entered. However, I am facing an issue with my Hashtags component when ...