Creating a self-updating dynamic component: A step-by-step guide

Currently, I am working on a component that receives another component via props to render. However, this component has the ability to update and change itself. The issue arises when the first time it is changed, the component functions correctly but crashes the Vue instance, preventing the second component from functioning independently.

I have included a link to the Playground where you can view my code:

Playground Link

Main Component

<script setup>
import { ref,shallowRef } from 'vue'
import Component1 from './Component1.vue';

const msg = ref('Hello World!')
const renderComponent = shallowRef(Component1)
const updateComponent = (component)=>{
renderComponent.value=component
}

</script>

<template>
 <component :is="renderComponent" @updateComponent="updateComponent"></component>
</template>

Component 1

<script setup>
import Component2 from './Component2.vue';
const emit=defineEmits(["updateComponent"])
</script>

<template>
  <div>
    Hello, I'm component 1
  </div>
  <button @click="emit('updateComponent',Component2)"> 
  click here to change component</button>
</template>

Component 2

<script setup>
import Component1 from './Component1.vue';
const emit=defineEmits(["updateComponent"])
</script>

<template>
  <div>
     Hello, I'm component 2
  </div>
  <button @click="emit('updateComponent',Component1)"> 
  click here to change component</button>
</template>

I have made attempts using "ref", "shallowRef", "markRaw", as well as importing all components into the main file, but none of these solutions worked successfully.

Answer №1

To address this issue, I propose a solution where the child components will emit the string name of the dynamic component. The parent component will then import all possible components and set the correct one based on the emitted string.

Playground link

App.vue

<script setup>
import { shallowRef } from 'vue'
import Component1 from './Component1.vue';
import Component2 from './Component2.vue';

// array to hold add as many as needed
const dynamicComponents = [Component1, Component2]

const renderComponent = shallowRef(Component1)
const updateComponent = (component) =>{
  renderComponent.value = dynamicComponents.find(c => c.__name === component)
}
</script>

<template>
 <component :is="renderComponent" @updateComponent="updateComponent"></component>
</template>

Component1.vue (Component2 being basically the same):

<script setup>
const emit = defineEmits(["updateComponent"])
</script>

<template>
  <div>
    Hello, I'm component 1
  </div>
  <button @click="emit('updateComponent', 'Component2')"> 
  click here to change component</button>
</template>

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

Transfer a Sencha Touch application from iOS to Android and Windows devices

I am a dedicated Android developer who is diving into the world of Sencha Touch, Windows app development, and VisualStudio environments for the first time. Please excuse the detailed explanation of my problem, as I want to make sure all crucial details are ...

Error message stating that there is an issue with the `this.extButton` variable being null when attempting to manually adjust the toolbar settings for

When using aloha in a web application, I have found it to be very effective and capable of performing all necessary tasks. However, I have run into an issue when attempting to customize the toolbar with the following settings: Aloha.settings = { ... ...

Maintain the grouping of objects based on duplicate values present in an array of objects

This array contains objects with unique id and time: var array = [{ id: 1, name: 'A', family: 'B', number: 100, category: 'test', time: '2018-03-02T10:33:00.000Z' }, { id: 2, name ...

What is the best way to add a constant value to all objects within an array without having to iterate through each one

Is there a more concise way to add a fixed value to each object in an array without using a loop in JavaScript? Programming Language used: JavaScript Example Array: "cars": [ { "name":"Ford", "models":"Fiesta" }, { "name":"BMW", "models":"X1" }, ...

Modify the color of the table map based on specific conditions in a React.js application

To modify the table entry's color based on the current balance, follow these conditions: If the current balance is less than 100, it should be shown in red. If the current balance is between 100 and 200, display it in yellow. Otherwise, show it in gre ...

IE is failing to trigger jAlert function

When I validate a text box by pressing the enter key on my keyboard, the validation works fine but the JAlert doesn't show up. However, when I call the same function on a button click, the alert shows in IE. I am quite confused by this behavior and wo ...

Creating a JavaScript function that generates a heading element

Hey there, I'm just starting out and could really use some guidance. I want to be able to have a function called addHeading() that takes the heading type selected from a drop-down menu and the text inputted in a form field, then creates and displays t ...

Retrieving all options from a dropdown list in HTML using ASP.net C#

I am currently working with a select list that looks like this: <select name="Section" id="Section" size="5"> <option>Section1</option> <option>Section2</option> <option>Section3</option> <option>Section4< ...

What are your thoughts on Uptrends vs Dynatrace for Website Monitoring?

I'm seeking recommendations for improving monitoring on a retail website. Any advice would be appreciated. Thank you in advance. ...

Utilizing inline JavaScript to automatically refresh a webpage at specified intervals and monitor for updates within a specific div element

I am currently working on creating an inline script that will automatically refresh a webpage at regular intervals and check for changes in a specific element. If the element meets certain criteria, then the script should proceed to click on a designated b ...

By utilizing the HTML element ID to retrieve the input value, it is possible that the object in Typescript may be null

When coding a login feature with next.js, I encountered an issue: import type { NextPage } from 'next' import Head from 'next/head' import styles from '../styles/Home.module.css' import Router from 'nex ...

Using Puppeteer to wait for an element to disappear or be removed from the DOM

Are there any methods in the Puppeteer API that allow us to wait for an element to disappear or be removed from the DOM before continuing execution? For example, if I have a loading animation that I want to wait for until it is no longer present in the DO ...

"Which is the better choice for a Django application's for loop: views.py or

I'm in the process of creating a Django app that features a word list. The app currently utilizes a speech function to inform the user of the first word on the list. The user is then able to record an audio clip of a word they say, which is converted ...

Is it possible to display this code through printing rather than using an onclick event?

I have a puzzle website in the works where users select a puzzle to solve. I am looking for a way to display the puzzles directly on the website instead of using pop-up boxes. I am proficient in various coding languages, so any solution will work for me. ...

What methods are available for integrating ArcGIS JS into Vue.js?

I have been exploring the examples provided in the documentation for ArcGIS, but I am facing difficulties in using it correctly. For instance, when I try to import Map from ArcGIS as demonstrated in this example: import Map from '@arcgis/Map' I ...

Setting up Jest to run in WebStorm for a Vue project with TypeScript can be done through

I am struggling to run all my tests within WebStorm. I set up a project with Babel, TypeScript, and Vue using vue-cli 3.0.0-rc3. My run configuration looks like this: https://i.stack.imgur.com/7H0x3.png Unfortunately, I encountered the following error: ...

What is the reason for IE displaying null when the model does not exist?

Why does IE 11 render 'null' if my model does not exist? For instance: <tr> <td [innerHTML]="model?.prop1 | my-pipe"></td> </tr> Imagine this scenario: When the page loads, a request is sent to the server and the res ...

How can I retrieve a child method in the Vue.js 3 Options API?

When working with Vue.js 3 using the Options API, I encountered a challenge in accessing a child component's method. Although there is a solution provided for Vue.js 2 and Vue.js 3 with Composition API on How to access to a child method from the paren ...

Issue encountered with Angular template rendering in combination with Node.js

I'm currently working on a small node project and trying to incorporate AngularJS into it. Within my project, I have a partial view that utilizes ng-controller and ng-repeat. Here is the structure of my angular.html page: <!DOCTYPE html> <h ...

The Material UI component successfully loads the options data list from the server response, however, it fails to return the selected value when an option

My goal is to dynamically populate my country and province select component based on server response data. The process begins with the user selecting a country, which triggers a request to the server using the selected country's id. The server respond ...