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

Save the click value for future use

My appointment form is divided into separate panels. At Step 1, if a user clicks on London (#Store1), I want to hide the Sunday and Monday options from the calendar in panel 5. Essentially, I need to save this click event so that when the user reaches th ...

What is the method for reaching a service in a different feature module?

Currently, I am utilizing Angular 2/4 and have organized my code into feature modules. For instance, I have a Building Module and a Client Module. https://i.stack.imgur.com/LvmkU.png The same structure applies to my Client Feature Module as well. Now, i ...

Having trouble displaying dynamically added images in my jsx-react component. The images are not showing up as expected

import React from "react"; import ReactDOM from "react-dom"; var bImg = prompt("Enter the URL of the image you want to set as the background:"); const bStyle = { backgroundImage: "url(bImg)"; // The link is stored ...

Understanding Mongodb: the process of populating a schema that is referenced within another schema using an API

Looking to make adjustments to my Api in order to populate a referenced schema. Here's the schema I am working with: export const taskSchema = new Schema ({ user:{ type: String, required: true }, project: { type ...

No assets detected in sails.js

Recently, I began a new sails project using 'sails new project --linker'. Initially, everything was functioning correctly but today I encountered a problem. Every time I start the server with 'sails lift', I now receive a 404 error for ...

How can one effectively manage asynchronous behavior on the client side of a Meteor application?

My focus is on Meteor. I want to connect with the Facebook API through Meteor's HTTP in order to show images on Meteor's client side. I've come across suggestions like Fiber Futures, storing data in Sessions, and triggering a synchronous se ...

How can I create a website that features both multiple pages and a single-page application design?

Currently, I am in the process of developing a Single Page Application (SPA) using Vue.js for the frontend and Express for the backend. However, my dilemma lies in finding an effective way to merge a traditional static website with individual pages into th ...

Error encountered while trying to implement sleep function in script

Good evening. I've been attempting to implement the sleep function from the system-sleep library, but my script keeps crashing. This is the code snippet I'm working with: page.html <html lang="en"> <head> <meta charset= ...

The functionality of jQuery's appendTo method seems to be malfunctioning

I am trying to display an image with a popup using jQuery mobile. In my loop, I have the code below: for( var i = 0; i < imageArray.length; i++ ) { counter ++; // Create a new Image element var img = $('<img data-rel="popup" class=" ...

The inner workings of v8's fast object storage method

After exploring the answer to whether v8 rehashes when an object grows, I am intrigued by how v8 manages to store "fast" objects. According to the response: Fast mode for property access is significantly faster, but it requires knowledge of the object&ap ...

What is the best method to securely install a private Git repository using Yarn, utilizing access tokens without the need to hardcode them

My initial thought was to utilize .npmrc for v1 or .yarnrc.yml for v2/3/4, but in all scenarios, Yarn does not even attempt to authenticate with Github. nodeLinker: node-modules npmScopes: packagescope: npmAlwaysAuth: true npmAuthToken: my_perso ...

Navigating within a React application - rendering JSX components based on URL parameters

As I work on developing a web-app with a chapter/lesson structure, I have been exploring ways to handle the organization of lessons without storing HTML or React code in my database. One idea I had was to save each lesson as a .jsx file within a folder str ...

Generating intricate JSON structures with JavaScript programming instructions

In the world of JSON, I am still a novice. I need to use JavaScript to construct the JSON structure below, but I'm struggling with adding the second element ("12101") and populating the people in the JSON Structure. Below is the code I tried, however, ...

Using Jquery to attach an event to a particular div which is part of a group of divs sharing

I am trying to implement a mouseup event on a series of divs that, when clicked, will reveal a child div ('menu'). All the parent divs have the same class. Here is an example: <div class="container"> <div class="menu"><p>Text ...

When using React, draggable components with input fields may lose their ability to receive focus when clicking on the input field

<Draggable axis="y" grid={[135,135]} onStop={this.handleStop} defaultPosition={{x: this.props.task.positionX, y: this.props.task.positionY,}}> <div id="edit-task-component"> <form onSubmit={this.handleSubmit} id=" ...

What is the reason for the emergence of this error message: "TypeError: mkdirp is not recognized as a function"?

While running the code, I encountered an error indicating that the file creation process was not working. I am seeking assistance to resolve this issue. The code is designed to fetch data from the Naver Trend API and Naver Advertising API, calculate resul ...

Attempting to run the npm install command led to encountering a SyntaxError with an

Recently, I made some alterations to my npm configuration and ever since then, I have been consistently encountering the same error whenever I try to install various packages. It seems that due to a personal mistake in changing the npm settings, I am now u ...

Navigating jQuery Tabs by Linking to a Specific Tab in a Separate File

I am currently using Bootstrap 3 to develop a basic website. On the about.html page, I have set up Tabs with various content. <ul class="nav nav-tabs" id="TabSomos"> <li class="active"><a href="#somos" data-toggle="tab">About Us</a> ...

Creating interactive JSON objects through the use of JavaScript and AngularJS

When using AngularJS to build a dynamic JSON from server data, I encountered an issue where my current declaration only works if the server data contains one item in the object array. How can I modify this to handle multiple items dynamically? $scope.it ...

Sequelize querying using the `WHERE NOT EXISTS()` condition

I am currently working with a many-to-many relationship setup in my database: var Genres = db.define('Movie', { name: { type: Sequelize.STRING(100), allowNull: false }, description: { type:Sequelize.STRING(), ...