Is it possible to assign a Component a name based on data?

In my project, I have three component icons named <DiscoverIcon>, <FeedIcon>, and <ProfileIcon>. In a tab loop, I want to display a different icon for each respective title.

I experimented with using a list element like this:

{ key: 1, icon: <div class='iconbgd'><DiscoverIcon /></div>, text: 'Discover', route: '/discover'}

and tried calling {{ link.icon }} as well as

{ key: 1, text: 'Discover', route: '/discover'}

along with calling

<div class='iconbgd'><{{link.text}}Icon /></div>

<template>
  <v-tabs fixed-tabs>
    <v-tab
      v-for="link in links"
      :key="link.key"
    >
      <div class='iconbgd'><{{link.text}}Icon /></div><h4>{{ link.text }}</h4>
    </v-tab>
  </v-tabs>
</template>
<script>
import DiscoverIcon from '../components/icons/DiscoverIcon'
import FeedIcon from '../components/icons/FeedIcon'
import ProfileIcon from '../components/icons/ProfileIcon' 

export default {
  components: {
      DiscoverIcon,
      FeedIcon,
      ProfileIcon
    },
  name: 'App',
  data () {
    return {
      links: [
          { key: 1, icon: <div class='iconbgd'><DiscoverIcon /></div>, text: 'Discover', route: '/discover'},
          { key: 2, icon: <div class='iconbgd'><FeedIcon /></div>, text: 'Feed', route: '/feed'},
          { key: 3, icon: <div class='iconbgd'><ProfileIcon /></div>, text: 'Profile', route: '/profile'}
      ]
    }
  }
}
</script>


<style>
.iconbgd svg{
  fill:url(#grad1);
  width: 30px;
  height: auto;
  padding-right: 5px;
}
</style>

The goal here is to implement the Vuetify tabs component in a way that allows me to cycle through different icons within each tab instead of simply creating separate buttons as currently done.

Answer №1

First of all, the {{link.icon}} should not be treated as HTML for display. It's recommended to use an alternative method.

Converting

<div class='iconbgd'><{{link.text}}Icon />
to
 <div class='iconbgd' v-text="link.text"><Icon />
. Vue provides a v-html directive specifically for handling HTML content, detailed information can be found here in the directives documentation.

Avoid using v-html whenever possible. The similar structure of different {{link.icon}} values allows for effective functionality without relying on v-html.

The usage of <{{link.text}}Icon /> seems to imply dynamic component binding. Check out more about dynamic components, which offer powerful features for such requirements.

I took a quick look at the Vuetify documentation regarding v-tabs and made some modifications based on that. While I haven't tested it myself, the following code snippet may align with your intended goal:

<template>
  <v-tabs fixed-tabs>
    <v-tab v-for="link in links" :key="link.key">
      <div class="iconbgd">{{link.label}}</div>
    </v-tab>
    <v-tab-item v-for="link in links" :key="link.key">
      <h4>{{link.label}}</h4>
      <component :is="link.label + 'Icon'" :key="link.key"/>
    </v-tab-item>
  </v-tabs>
</template>
    
<script>
import DiscoverIcon from '../components/icons/DiscoverIcon';
import FeedIcon from '../components/icons/FeedIcon';
import ProfileIcon from '../components/icons/ProfileIcon';

export default {
  data() {
    return {
      links: [
        {
          key: 1,
          label: 'Discover',
          route: '/discover'
        },
        {
          key: 2,
          label: 'Feed',
          route: '/feed'
        },
        {
          key: 3,
          label: 'Profile',
          route: '/profile'
        }
      ]
    };
  },
  name: 'App',
  components: {
    DiscoverIcon,
    FeedIcon,
    ProfileIcon
  }
};
</script>
    
    
<style>
.iconbgd svg {
  fill: url(#grad1);
  width: 30px;
  height: auto;
  padding-right: 5px;
}
</style>
 

Answer №2

I truly appreciate your help! With a few adjustments, everything is now functioning perfectly.

<v-tabs fixed-tabs color='transparent' slider-color='#1341B2'>
         <v-tab v-for="link in links" :key="link.key" :to="link.route">
            <div class="iconbgd">
                <component :is="link.label + 'Icon'" :key="link.key"/>
            </div>
            <h4>{{link.label}}</h4>
        </v-tab>
    </v-tabs>

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

Populate Vue 3 Element-plus Virtualized Table with actual data

As a newcomer to frontend development, I am currently working on integrating Element-plus Virtualized Table with actual data. Here is the basic structure of the example: const generateColumns = (length = 10, prefix = 'column-', props?: any) => ...

html table displaying incorrect data while using dynamic data in vue 3

example status 1 Hello there! I'm trying to create a table (check out example status 1 for guidance). Here's the code snippet I am using: <table> <tr> <th>Product</th> <th>Price</th> <th>Av ...

Testing-library does not seem to recognize SFC styles

I've been working on implementing unit tests in our Vue codebase, but I'm running into some trouble when it comes to testing the visibility of an element. Even though I render the component as per usual and following the examples provided in the ...

Vue Tab doesn't properly initialize Vue Chart.js

In my component, I have two vue-tabs with two instances of vue-chart-js each. While they initialize without errors, attempting to extract an image from a chart in the inactive tab using document.querySelector('#mySecondChart').toDataURL() results ...

Guide on redirecting to a specific Vue-app page using Flask

I am currently working on an application that includes a page that ends with '@' and provides meta information for the page without '@'. For example, if the page '/user/aabb' contains information about the user 'aabb&apos ...

Data is not loaded until after the HTML for the Nuxt page has been

My issue is that I have a dynamic page where product details are loaded, but the html code loads before the data. This results in errors when trying to use static elements like images because the "product" object does not exist. To address this problem, I ...

Tips for showing a single progress message when uploading multiple files on eleme.io [vuejs]

Tech Stack: Utilizing Vuejs with element.eleme.io framework. Objective: To implement a feature that allows users to upload multiple files while displaying only one "in progress message". To handle image uploads, we are integrating . During the upload pr ...

What are the reasons for being unable to access the HTML canvas in Vue?

I am currently working on creating a canvas element in Vue, but I seem to be encountering issues with the canvas instance. It appears that I may not be declaring or utilizing it correctly, as I am receiving the following error: TypeError: Cannot set pro ...

Launching a new VueJS app using PM2 generates a blank process rather than the expected result

pm2 start npm -- serve pm2 start npm --watch -- run dev pm2 start npm --name "vue-app" -- start sudo pm2 start npm run serve --name vue-app -- start When I execute these commands, a process starts but my app does not launch. When I run sudo lsof ...

Tips for resolving the "semicolon expected" alerts in your CSS code (css-semicolonexpected)

Having some trouble with using the Tailwindcss @apply directive within a <style> tag in a Nuxt.js Vue file. It seems to be working fine, but those annoying red squiggly lines keep popping up. Any help would be greatly appreciated! Thank you! Take a ...

choose a selection hopscotch

Is there a way to prevent the input field from jumping out of alignment when an option is selected in these q-select inputs? I want to fix this issue so that the field remains in line with the horizontal alignment. https://codepen.io/kiggs1881/pen/RwENYEX ...

utilize computed properties to automatically update components when Vuex state changes

Currently, I'm in the process of developing a basic movie application using Vue and Vuex. My goal is to allow users to add movies to a favorites list by clicking a button. The movies are stored in the Vuex state; however, I'd like the text on the ...

What is the best approach to integrate a JQuery-powered widget into a Vue.js module for seamless use?

I have a group of colleagues who have started developing a complex web application using Vue.js. They are interested in incorporating some custom widgets I created with JQuery in the past, as re-creating them would be time-consuming and challenging. While ...

Troubleshooting Vue Single File Components Displaying Missing Styles

I'm currently attempting to incorporate styles into a vuejs single file component. I've successfully achieved this in a node app previously, but now I am working with a python/flask backend (not that it should make a difference). The Vue componen ...

The HTML input type color will render as a text input displaying the selected color code

Currently, I am experimenting with using an input field that includes a color selector in Vue. <input type="color" v-model="model.$.message_color"> This is my first time working with the type="color" attribute. However, ...

Configuring Visual Studio Publish settings for Single Page Applications deployed on Azure

I have set up my Azure App Service and downloaded the publish profile settings to use FTP for publishing my single page app to Azure. However, I am interested in configuring this process in Visual Studio similar to how one would publish a .Net application ...

Having trouble creating an axios instance in Vue

I recently came across a helpful tip in an article about using axios for AJAX requests in Vue. The author mentioned that by setting Vue.prototype.$http = axios, we can then use this.$http within the Vue instance, which worked perfectly for me. However, wh ...

Strategies for extracting taginput information from an API

I have a collection of tags stored in a database that I can retrieve using an API. Although I am able to use these tags within my template, I am facing issues specifically when trying to display them in the tag list. As someone who is new to Vue.js, I sus ...

How can Nuxt 3's useHead method be utilized to replace body classes instead of just adding to them?

Currently, I am developing a Nuxt 3 project and my goal is to update the body class whenever there is a route change by utilizing the useHead hook. Specifically, my plan is to employ useFetch to fetch data for the current page, and once that data is retrie ...

At random intervals, a ReferenceError is triggered stating that Vue is not defined

While working on an application that uses templates rendered by Apache Velocity, I encountered the error "Uncaught ReferenceError: Vue is not defined" when trying to incorporate vue.js components. Oddly enough, this error is not consistent - it occurs most ...