Seeking the identification of recursive components in Vue3- what's the way?

I am facing a challenge with my component called Group, which has the ability to contain recursive components. Within this Group component, there is another component named ButtonsContainer. The ButtonsContainer component provides functions to focus on the first and last buttons. My goal is to obtain references to both the first group and the last group, including any nested groups. I attempted to achieve this using a recursive function, but unfortunately, it resulted in exceeding the maximum call stack size.

Displayed below is the code snippet for the Group component. I have excluded the ButtonsContainer component since it primarily displays buttons in a grid without any special functionalities.

Group Component:

<script setup lang="ts">

const props = defineProps<{
    group: Group
}>();

const buttonsContainerRef = ref<InstanceType<typeof ButtonsContainer> | null>(null);
const firstGroupRef       = ref<InstanceType<typeof Group> | null>(null);
const lastNestedGroupRef  = ref<InstanceType<typeof Group> | null>(null);

function getLastButtonsContainerRef(): Ref<InstanceType<typeof ButtonsContainer> | null> | undefined {
    if (props.group.groups.length > 0) {
        // return getLastButtonsContainerRef(); // still does not work:(
        getLastButtonsContainerRef();
    } else {
        return buttonsContainerRef;
    }
}
</script>

<template>
    <ul>
        <li v-if="group.buttons.length > 0 && !props.group.collapsed">
            <ButtonsContainer
                :buttons="group.buttons"
                ref="buttonsContainerRef"
            />
        </li>
        <li
            v-if="group.groups.length > 0 && !props.group.collapsed"
            v-for="nestedGroup in group.groups"
            :key="nestedGroup.uuid"
        >
            <Group
                :group="nestedGroup"
                class="nested-group"
            />
        </li>
    </ul>
</template>

If you have any suggestions on how I can retrieve references to both the first and last group, along with any nested ones, please feel free to share your insights. Your assistance is greatly appreciated. Thank you!

Answer №1

To access the nested refs, you will have to navigate through the tree manually.

There isn't a pre-built solution available for this specific scenario.

Here's a basic example demonstrating how to iterate through refs, including all nested children.

const { createApp, ref } = Vue;

const CompB = {
  props: ['id'],
  setup(props) {
    const name = "CompB"
    return { name }
  },
  template: '<div class="b">CompB, id:<b>{{id}}</b></div>'
}

const CompA = {
  components: { CompB },
  props: ['id'],
  setup(props) {
    const name = "CompA"
    const child = ref(null)
    return { name, child }
  },
  template: '<div class="a">CompA, id:<b>{{id}}</b><CompB ref="child" :id="`${id}.1`" /></div>'
}

const App = {
  components: { CompA },
  setup(props) {
    const refs = ref([])
    const showRefs = (ref) => {
       if (!ref) {
          for(var i = 0; i < refs.value.length; i++) {
            console.log(`Name: ${refs.value[i].name}, id: ${refs.value[i].id}`);
            if (refs.value[i].child) showRefs(refs.value[i].child)
          }
       } else {
          console.log(`Name: ${ref.name}, id: ${ref.id}`);
       }
    }
    return { refs, showRefs }
  }
}
const app = createApp(App)
app.mount('#app')
#app { line-height: 2; }
[v-cloak] { display: none; }
.a {
  background-color: lightblue;
  margin: 4px;
  padding: 4px;
}
.b {
  background-color: lightyellow;
  margin: 4px;
  padding: 4px;
}
<div id="app" v-cloak>
<button @click="showRefs()">Show refs</button><br/>
<comp-a v-for="n in 3" :id="n" ref="refs"></comp-a>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></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

Maintaining User Login State Across Route Changes in Vue with Vuex

Our small Dev-Team is excited to venture into creating our own social media website just for fun. We have implemented a login process using a jwt that is stored in localStorage. async login( { commit }, user) { commit('auth_request'); ...

The Axios POST function experiences issues on Safari (macOS) and all iOS and Mozilla browsers, but functions properly on Brave and Chrome

Error console screen The error appears in Safari console, but not in Chrome. Here is my method: async postRequest() { try { const res = await axios.post(baseURL, { name: this.formdata.name, vd:this.formdata.vd, tp:this.formdata.tp ...

Every time I attempt to use the reset() function in typescript, I encounter a type error that prevents its

I am encountering a type error message that reads: 9: Property 'reset' does not exist on type 'EventTarget'. 18 | }); 19 | 20 | e.target.reset() | ^^^^^ 21 | } Below is the relevant code snippet: const hand ...

Vue.js checkbox group with multiple selections

My goal is to have 3 checkboxes and receive a result in the format {ceheckboxName1:value,ceheckboxName2:value,ceheckboxName3:value}. To better understand, take a look at my code snippet below. <li> <input name="" type="checkbox" value="100 ...

Tips for handling the user's logged-in status in NativeScript Vue

I had a question about managing user login/logout, so I tried the following approach: store.commit('load_state'); store.subscribe((mutations, state) => { ApplicationSettings.setString('store', JSON.stringify(state)); }); new Vue( ...

Record the success or failure of a Protractor test case to generate customized reports

Recently, I implemented Protractor testing for our Angular apps at the company and I've been searching for a straightforward method to record the pass/fail status of each scenario in the spec classes. Is there a simple solution for this? Despite my at ...

Resolving Node.js Absolute Module Paths with TypeScript

Currently, I am facing an issue where the modules need to be resolved based on the baseUrl so that the output code is compatible with node.js. Here is my file path: src/server/index.ts import express = require('express'); import {port, database ...

Unable to integrate vue.js into a django project

I integrated vuejs with webpack in django, but I'm facing an issue where I can't access Vue instances from django templates. Upon inspecting the chrome devtool, the transpiled JavaScript is being loaded correctly, but it displays {{message}}. T ...

Is there a way to monitor user engagement within my app without depending on external analytics platforms?

I'm looking to enhance the user-friendliness of my applications deployed on the Play Store by tracking users' interactions. Specifically, I want to keep track of: Screen Time: Monitoring how much time users spend on each screen. Clicks: Tracking ...

What are the benefits of using material-ui@next without the need for

Thinking about creating a project using material-ui@next, but trying to avoid using withStyles. However, encountering issues with the draft of TypeScript that includes the decorator @withStyles. This leads to one question - is it possible to use material ...

The VueJS router $routes.push method does not support adding query parameters

Why is it that this code isn't functioning correctly? selectChanged(val) { let term_ids = []; let taxonomy = ''; val.forEach((obj) => { term_ids.push(obj.term_id); taxonomy = obj.taxonomy; ...

Secret key management in VueJs: Best practices

As I prepare to launch my personal blog, built using VueJS and hosted by a Go web-server, I am faced with the challenge of securely storing private keys. The content for my blog is managed by ButterCMS and accessed through the fetch API. During developmen ...

Testing @microsoft/applicationinsights-web within an Angular project on a local environment

How can I test Microsoft's application insights locally? Most guides I've come across suggest testing it on the Azure portal, but I can't do that as it would mean testing it in a production environment. ...

Update the URL for the Swagger 2.0 documentation path

This is how I set up swagger : const openapi = Openapi.initialize({ paths: openApiPaths, app, apiDoc, }); const openApiSpec = openapi.apiDoc; console.log(openApiSpec); app.use(swaggerUI(openApiSpec)); How do I update the base path ...

How can I monitor an input field that already has a value in Vue?

My current setup includes an email input and a watcher that verifies if the input is valid or not. The issue I'm facing is that the watch event only triggers when something new is typed into the email field. This means that if the existing value in th ...

Troubleshooting: Why does getElementById return undefined in Vue's mounted hook?

I'm facing an issue when trying to access the DOM using Vue3 mounted hook. Interestingly, I've found that utilizing the getElementById or getElementByClassName functions within the mounted hook results in undefined values, whereas using the quer ...

Acquire Binance account balances through NextJS, ccxt library, and TypeScript integration

Currently, I am attempting to retrieve balances from Binance within my NextJS 13 application, utilizing the /src/app directory along with TypeScript. async function fetchData() { const exchange = new ccxt.binance ({ "apiKey": "mykey ...

Module augmentations do not allow for exports or export assignments

import { Request as ExpressRequest, Response as ExpressResponse } from 'express'; declare module 'kvl' { export = kvl; } declare const kvl: { ValidationDone:(param:(error: any, response: ExpressResponse) => void) => void; ...

How to retrieve a value from an asynchronous function using async/await in a computed property in Vue

While working with my Vue.js search bar, I encountered an issue where the results were not displaying based on matching characters entered in the input field. To fetch the data, I am utilizing an async await function to wait for the API response. However, ...

Can you explain how to incorporate a node module script into a React.js project?

I have encountered an issue where the element works perfectly fine when using an external node module, but fails to function properly when using a locally downloaded node module. Unfortunately, I am unable to identify the root cause of this problem. You c ...