Guide on how to verify if a component with a specific name is registered within the Composition API of Vue 3

My current situation involves a template that loads dynamic components based on their names:

<template>
      <div>
        <div>
          <div>
            <component
              :is="getFormRenderer"
            ></component>
          </div>
        </div>
      </div>
</template>

The getFormRenderer function retrieves a string (obtained from an API) which specifies the component by its name.

In this scenario, only two sub-components (telegram_send_message and time_time) are imported and registered:


<script>
import { useStore } from "vuex";
import { computed } from "vue";

import exampleComponentOne from "@/components/forms/exampleComponentOne.vue";
import exampleComponentTwo from "@/components/forms/exampleComponentTwo.vue";
import defaultComponentTwo from "@/components/forms/defaultComponent.vue";

export default {
  name: "ActionEditor",
  setup() {
    const store = useStore();

    const getFormRenderer = computed(() => {
      return (
        store.state.level.actionSelected.plugin
      );
    });
    return {
      getFormRenderer,
    };
  },
  components: {
    exampleComponentOne,
    exampleComponentTwo,
    defaultComponent
  },
};
</script>

Now I am looking to enhance the functionality of the dynamic <component> so that it defaults to defaultComponent.vue if the specified component does not exist in the list.

I have explored using this.hasOwnProperty(), but within the setup() function, this is undefined. Is there a conventional method to accomplish this task?

Answer №1

One way to verify the presence of a component in the setup() function is by utilizing either resolveComponent() or resolveDynamicComponent(). These functions search for a component based on its name. It's worth noting that the documentation for resolveDynamicComponent() wrongly mentions it throws a warning for non-existent components, when in fact this behavior belongs to resolveComponent() (as of v3.0.9).

Both methods will return the component name if the component does not exist, which allows you to check if the component exists by ensuring the return type is not a string:

import { computed, resolveDynamicComponent } from 'vue'

export default {
  setup() {
    const isComponent = name => typeof resolveDynamicComponent(name) !== 'string

    const store = useStore();
    const getFormRenderer = computed(() =>
      isComponent(store.state.level.actionSelected.plugin)
        ? store.state.level.actionSelected.plugin
        : 'DefaultComponent'
    );

    return {
      getFormRenderer
    }
  },
  components: {
    //...
  },
}

View a demonstration

Answer №2

To check if a component with a specific name is globally registered in the application, you can utilize the app.component() function by passing only the component name as an argument.

In any component within your app, you can use the somewhat obscurely documented getCurrentInstance function - ensuring it is called only within the `setup` or hooks sections. You can then use the returned value to test whether the component is registered.

  1. For global components, employ the

    getCurrentInstance().appContext.app.component()
    function (where `appContext.app` refers to the main `app` object created using `createApp()`).

  2. For locally registered components, utilize

    getCurrentInstance().components['name']
    .

Take a look at the example below for global components. Please note that the example uses Vue from a CDN, assuming the global Vue object. In actual development scenarios, imports are preferred; for instance,

import { getCurrentInstance } from 'vue'
.

const app = Vue.createApp({})

app.component('mainComponent', {
  template: `
    <component :is="getComp1OrDefault"></component>
    <component :is="getComp2OrDefault"></component>
  `,
  setup() {  
    const vm =  Vue.getCurrentInstance()
    //console.log(vm) 
    const getComp1OrDefault = Vue.computed(() => {
      return vm.appContext.app.component('comp1') ? 'comp1' : `defaultComp`
    });
    
    const getComp2OrDefault = Vue.computed(() => {
      return vm.appContext.app.component('comp2') ? 'comp2' : `defaultComp`
    });
    
    return {
      getComp1OrDefault,
      getComp2OrDefault
    };
  }
})

app.component('comp1', {
  template: `<div>Comp1</div>`
})

app.component('defaultComp', {
  template: `<div>defaultComp</div>`
})

app.mount("#app")
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.7/vue.global.js" integrity="sha512-+i5dAv2T8IUOP7oRl2iqlAErpjtBOkNtREnW/Te+4VgQ52h4tAY5biFFQJmF03jVDWU4R7l47BwV8H6qQ+/MfA==" crossorigin="anonymous"></script>

<div id="app">
  <main-component />
</div>

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

Retrieve and access an array of objects from MongoDB

Assuming I have some data stored in MongoDB as follows - [ { _id: new ObjectId("63608e3c3b74ed27b5bdf6fa"), latitude: 24.3065, hotels: [ { name: "Saunders Oconnor", lat ...

The color scheme detection feature for matching media is malfunctioning on Safari

As I strive to incorporate a Dark Mode feature based on the user's system preferences, I utilize the @media query prefers-color-scheme: dark. While this approach is effective, I also find it necessary to conduct additional checks using JavaScript. de ...

The trio of Javascript, Ajax, and FormData are

I'm struggling with sending form values to a PHP file. Here's the code I have: <form role="form" id="upload_form" method="post" enctype="multipart/form-data"> <div class="form-group"> <label for="formlabel">Title< ...

What is the reason for create-react-app initializing twice?

After creating a react app using the command npx create-react-app, I encountered an issue: import React from 'react'; class Costly { constructor() { console.log('creating costly class'); } } function App() { const costlyRef ...

Ensuring promise doesn't resolve until the IF STATEMENT is executed

I am encountering an issue with the "checkWorkflow" function where it seems to be executing the "If" statement before actually checking. This deduction is based on the output in my console, which makes me believe there might be a problem with how I am hand ...

Failed to access the 'totalQty' property as it is undefined

I have developed a cart object that can hold products in a shopping cart. The issue arises when an item is undefined before it gets added to the cart. How can I ensure that the cart is defined even when it's empty during the session? I am using ejs. ...

Completion of TypeScript code is not working as expected, the variable that is dependent upon is not

Looking for assistance with creating code completion in TypeScript. Variable.Append1 Variable.Append2 Variable.Append3 I have defined the following class: class Variable { Append1(name: string){ if (name == undefined) ...

Is there a way to restrict the amount of user input that is allowed?

Is it possible to restrict the input quantity when using the built-in arrow icon in the text field, but not when typing manually? <TextField variant="outlined" label="Quantity" onChange={(e) => setItemName({...i ...

Utilizing jQuery to Perform Calculations with Objects

Can someone help me with a calculation issue? I need to calculate the number of adults based on a set price. The problem I'm facing is that when I change the selection in one of the dropdown menus, the calculation doesn't update and continues to ...

Completing a form and saving data to a document

I have a form that successfully writes to a text file using PHP. However, after submitting the form, the page reloads and shows a blank page. Currently, there is a message that appears using jQuery after the form is submitted. My goal is to prevent the pa ...

The Right Way to Set Up Form Data in VueJS

Currently, I am facing an issue with a component that renders a form and pre-fills the fields with data retrieved from an ajax request. The problem lies in my desire to edit existing fields and simultaneously add new fields for submission. To accomplish t ...

JQuery Accordion SubMenu/Nested Feature malfunctioning

I have successfully implemented a JQuery Accordion on my website and it is functioning properly, opening and closing as expected. However, I am facing an issue when trying to add a submenu within the accordion. The submenu does not work as intended and lac ...

Steps to run a function for updating a JSON data file

I currently have a Leaflet map displaying weather data retrieved from a Json source. There is already a function in place that updates the data every x minutes using setInterval. setTimeout(function () { refreshId = setInterval(function () { ...

Having Difficulty with Splicing Arrays in React?

Currently working on learning React and trying to develop my own mini-app. I'm basing it very closely on the project showcased in this video tutorial. I've run into an issue with the comment deletion functionality in my app. Despite searching va ...

Clicking on a table will toggle the checkboxes

I am facing an issue with this function that needs to work only after the page has finished loading. The problem arises due to a missing semicolon on the true line. Another requirement is that when the checkbox toggle-all is clicked as "checked", I want ...

How to Call a Nested Object in JavaScript Dynamically?

var myObj = { bar_foo : "test", bar : { foo : "hi there"; }, foo : { bar : { foo: "and here we go!" } } } How can we achieve the following: var arr = [["bar", "foo"], ...

The variable ReactFauxDOM has not been declared

Exploring the combination of D3 and React components. Utilizing OliverCaldwell's Faux-DOM element has led me to encounter a frustrating error message stating "ReactFauxDOM is not defined”. Despite following the npm install process correctly... It s ...

Tips for adding JSON values to an object

There is a specific object called SampleObject which has the following structure: { ID: "", Name: "", URL: "", prevName: "", Code: "", } I am looking to insert the values from the JSON object below (values only): var object = { "Sample ...

RegEx in JavaScript to identify and match the innerHTML property of all elements

I am currently in the process of developing a Chrome extension that needs to identify specific pages within a website, including the Log In / Sign In page, the Sign Up / Register page, the About page, and the Contact Us page. My approach involves obtainin ...

jQuery: Issue with controller function execution when using ajax

Currently, I am working on developing a web application using C# MVC that dynamically fetches information from a server to enhance performance. However, I have encountered some errors and I am having trouble pinpointing the exact cause. Allow me to provid ...