Implementing dynamic component swapping in Vue 3 using components from another component

I currently have a display component called app-display, which contains a dynamic component inside (by default, it is set to app-empty):

    app.component('appDisplay', {
        template: `<component :is="currentComponent"></component>`,
        data() {
            return {currentComponent: 'appEmpty'}
        }
    });

My goal is to create a new instance of app-message, assign a value to the property message, and then set this instance as the current component for app-display when a button is clicked.

The following is the browser code related to this question:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue component reference</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app"></div>
<script>
    // Main application consists of a button and a display panel
    const app = self.Vue.createApp({
        template: `
          <app-btn></app-btn>
          <app-display></app-display>
        `
    });

    // Button component triggers an action
    app.component('appBtn', {
        template: `
          <button v-on:click="setDisplay">Display message</button>`,
        methods: {
            setDisplay() {
                console.log('To set "appMessage" with a specific "message" parameter as the inner component of "app-display", I need assistance here.');
            }
        }
    });

    // Component containing a dynamic components 
    app.component('appDisplay', {
        template: `<component :is="currentComponent"></component>`,
        data() {
            return {currentComponent: 'appEmpty'}
        }
    });

    // Default component displayed initially
    app.component('appEmpty', {
        template: `<div>I'm empty.</div>`
    });

    // Custom message component to be displayed on button click
    app.component('appMessage', {
        template: `
          <div>{{ message }}</div>
        `,
        props: {
            message: String
        }
    });
    // Mounting main app to the page
    app.mount('#app');
</script>
</body>
</html>

How can I access the app-display component from within the app-btn?

Answer №1

To ensure seamless communication between the button component and main component, you need to emit an event from the button component to the main component with the component name and message. In the main component, define a message and current component name which will be updated by the handler of the emitted event and then passed as props to the component responsible for displaying them:

// Here is the code snippet for the main application setup including the button and display panel
const app = Vue.createApp({
    template: `
        <app-btn @change-content="changeContent"></app-btn>
        <app-display :currentComponent="componentName" :message="msg"></app-display>
    `,
    data(){
        return{
            componentName:'appEmpty',
            msg:''
        }
    },
    methods:{
        changeContent(compName,msg){
            console.log(compName,msg)
            this.componentName=compName
            this.msg=msg
        }
    }
});

// Definition of the button component
app.component('appBtn', {
    template: `
        <button v-on:click="setDisplay">Display message</button>`,
    methods: {
        setDisplay() {
            this.$emit('change-content','appMessage','Hello message :)')
            
        }
    }
});

// Component containing dynamic content
app.component('appDisplay', {
    props:{
        currentComponent:{
            type:String,
            default:'appEmpty'
        }
    },
    template: `<component :is="currentComponent"></component>`,
  
});

// Default component to display initially
app.component('appEmpty', {
    template: `<div>I'm empty.</div>`
});

// Custom component to display custom message upon button click
app.component('appMessage', {
    template: `
        <div>{{ message }}</div>
    `,
    props: {
        message: String
    }
});
// Mounting the main app on the page
app.mount('#app');
<!DOCTYPE html>
<html lang="en>
<head>
    <meta charset="UTF-8>
    <title>Vue component reference</title>
    <script src="https://unpkg.com/vue@next></script>
</head>
<body>
<div id="app></div>

</body>
</html>

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

In what ways can you toggle the visibility of table rows and data dynamically with the onchange event in HTML?

I'm dealing with an HTML code that can dynamically change table data based on user selection. Here's the snippet of my HTML code: Select an option: <select name='set' id="set" class="selectpicker" onchange='displayFields(this. ...

Activate the download upon clicking in Angular 2

One situation is the following where an icon has a click event <md-list-item *ngFor="let history of exportHistory"> <md-icon (click)="onDownloadClick(history)" md-list-avatar>file_download</md-icon> <a md-line> ...

The div height adjustment peculiarities in IE7 and IE8 are causing quite a stir

I recently encountered a problem with my HTML/JS code that I thought was simple. The code is designed to expand the size of a div on mouseover and then collapse it back on mouseout. Here's how the code looks: CSS: .sign-in-up { position: absolut ...

Switching visual content according to dropdown choice

Hey there! I've been working on my HTML file and ran into a little issue. I'm trying to change the image in the div section based on a dropdown selection that modifies the source of the image from an XML file. However, I keep getting an error tha ...

Using Javascript variables within Django HTML templates

As I develop my Django app, I find myself in uncharted territory with JavaScript. My goal is to integrate a map into one of my pages by adding a few lines of JavaScript. The JavaScript code includes initializing the map and placing markers based on data s ...

display rails view using ajax

I have developed a new form that I would like to render using ajax in case it fails validations. In my controller, the code looks like this: def create event = CEvent.new(params[:c_event]) respond_to do |format| if event.save format.html { ...

What is the reason that PHP has the ability to set Cookies but Local Storage does not?

Let's take a step back to the era of cookies, not too far back since they are considered old but still quite relevant. PHP allows you to set and read them even though they are a client-side technology; however, JavaScript can also be used completely o ...

Tips on invoking a factory method from a different service method in AngularJS

I have a factory method that goes like this.. (function (angular) { "use strict"; angular .module('app') .factory('UserService', ['$rootScope', '$q', function ($rootScope, $q) { ...

The behavior of Date's constructor differs when applied to trimmed versus untrimmed strings

Although it's commonly advised against creating a date from a string, I stumbled upon an interesting phenomenon: adding a space before or after the date string can impact the resulting date value. console.log([ new Date('2019-03'), ...

Choose the specific Element by its dynamicID in JQuery

Just starting out with Jquery and I have a specific task in mind. In my HTML page, I have elements with IDs generated by concatenating a string variable. My goal is to use JQuery to select the element with this dynamically generated ID. See below for more ...

The Price Filtering feature in the MERN Stack for Products is currently experiencing technical difficulties

Hey there! I am currently working on developing an Ecommerce Application using the MERN Stack with redux. I've encountered a problem while trying to send a price array argument in my fetching function. The error message states: XHR GET http://localhos ...

Is it possible to retrieve the controller path for an AJAX request from within a partial view?

Looking for a solution to fully decouple and reuse a partial view that allows users to select dates and filter results based on those dates. This widget can be used on multiple pages, so I wanted to add event listeners that would submit the form within the ...

Display webpage content in an Iframe using Javascript after PHP code has been executed

Despite researching keywords like PHP // Javascript // Load // URL online, I'm still struggling to fully grasp the concepts. Real-life case studies have been helpful, but I must admit that I'm feeling a bit overwhelmed at the moment. I created a ...

Ajax is unintentionally duplicating the request

When the "async" parameter is set to "true", ajax sends two requests at the same time. But, when it is set to "false", there are no issues. To prevent the page from reloading, I am using the following code: $(document).ready(function() { $(document).on(& ...

Ensure consistency across browsers by disabling zoom functionality on touchpad inputs while still permitting scrolling actions

I am looking for a way to disable 2-finger zoom on trackpad "wheel" events while still allowing 2-finger scroll. On mobile, I have already disabled zoom with: <meta name="viewport" content="initial-scale=1, minimum-scale=1, m ...

Unleashing the power of RollupJs: A guide to dynamically bundling modules and objects

Is there a way to dynamically bundle a module/object into my RollupJs output file? I have experimented with various options without success in achieving the desired result. Below is a brief sample project that demonstrates what I am trying to achieve. The ...

Mastering the use of gl Scissor is essential for effectively implementing popups in your

I am attempting to implement a pop-up view on top of the current webGL view. My strategy is as follows: Whenever I need to display a popup, I create a scissorRect and begin rendering the popup scene onto it. I was hoping that the content of the previous s ...

What is the best way to reset the state to null when the input field is blank?

After setting some inputs with a state of null, I noticed that when the end-user types something and then deletes it all, the input reverts back to an empty string. How can I adjust the state so that it returns to null? I seem to be encountering an issue ...

The automatic refresh feature of the DataTable every 30 seconds is malfunctioning

Currently, I am implementing an application that retrieves records from a database and populates them into a dataTable using JSON. Although my app is functioning correctly, I want to refresh the table every 30 seconds and update any added or modified rows ...

Ways to simulate the route object in Vue 3 composition functions?

I'm looking to simulate the route object in order to avoid test failures such as TypeError: Cannot read properties of undefined when trying to access route.x. Here's what I attempted: const route = { fullPath: '/', path: '/' ...