Creating Vue3 Component Instances Dynamically with a Button Click

Working with Vue2 was a breeze:

<template>
    <button :class="type"><slot /></button>
  </template>
  <script>
  export default {
    name: 'Button',
    props: [ 'type' ],
  }
  </script>
  
import Button from 'Button.vue'
  import Vue from 'vue'

  var ComponentClass = Vue.extend(Button)
  var instance = new ComponentClass()

  instance.$mount() // pass nothing
  this.$refs.container.appendChild(instance.$el)
  

The process involved extending and creating an instance. However, in Vue3, this method has been removed. What alternative solutions are available?

Answer №1

import {defineComponent,createApp} from 'vue'

const customButton = defineComponent({
    extends: Button, data() {
        return {
            type: "1111"
        }
    }
})

const newDiv = document.createElement('div');
this.$refs.container.appendChild(newDiv);
createApp(customButton).mount(newDiv)

Answer №2

I found a great solution for creating a component using the options API in Vue. Simply define the component within a method like this:


import { defineComponent } from "vue"

createCustomComponent() {
    var customComponent = {
        data() {
            return {
                greeting: 'Hello',
            }
        },
        template: `<div>{{greeting}}</div>`
    }

    var customInstance = defineComponent(customComponent);
}

Once you have instantiated the component, you can use it in your template as follows:

<component :is="customInstance" v-if="customInstance"/>

Answer №3

When I switched from using Element UI to Element Plus, I encountered a change in how prefix/suffix icons are handled. Now, I had to pass them as components instead of classname strings. Since I prefer using a single custom icon component, I needed to create a vnode and customize it with props before passing it in as the icon prop.

To simplify this process, I decided to create a plugin:

import { createVNode, getCurrentInstance } from 'vue'

export const createComponent = (component, props) => {
  try {
    if (component?.constructor === String) {
      const instance = getCurrentInstance()
      return createVNode(instance.appContext.components[component], props)
    } else {
      return createVNode(component, props)
    }
  } catch (err) {
    console.error('Unable to create VNode', component, props, err)
  }
}

export default {
  install(APP) {
    APP.$createComponent = createComponent
    APP.config.globalProperties.$createComponent = createComponent
  }
}

With this plugin, I can now use it for globally registered components like this:

<component :is="$createComponent('my-global-component', { myProp1: 'myValue1', myProp2: 'myValue2' })" />

And for locally imported components:

<component :is="$createComponent(MyComponent, { foo: 'bar' }) />

Alternatively, I can do this within a data method:

data() {
  return {
    customComponent: $createComponent(MyComponent, { foo: 'bar' })
  }
}

<template>
  <component :is="customComponent" />
  <MyOtherComponent :customizedComponent="customComponent" />
</template>

Answer №4

Experiment with expanding the Button component and then adding its root element $el to the specified container:

import Button from 'Button.vue'


const ExtendedButton = {
  extends: Button
}

this.$refs.container.appendChild(ExtendedButton.$el)

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

The `.append()` function includes HTML content as plain text

I am using JavaScript to dynamically add HTML elements to my webpages. I have created a loop that iterates through all the projects, each containing multiple pictures. The first step involves generating the project title and adding it within a div element ...

What are the steps to showcase the content of a Typescript file on an HTML webpage?

We are looking to create a sample gallery with source code examples. Including typescript, html, and HTML files to showcase similar to the Angular.io component samples pages. Is there a way to extract the source code from a typescript file within our pro ...

Error: Module 'electron-prebuilt' not found

I am encountering an issue with my Electron app that utilizes Nightmare.js after compiling it into an .exe file using electron-packager. Everything functions properly until I click a button that triggers Nightmare.js, at which point I receive the followi ...

jQuery animation for expanding accordion headers

I want to create a cool animation for my accordion headers that mimics a ribbon being dragged onto the wrapper when hovered over, and then dragged out when the hover ends. Everything was working fine in this initial jsFiddle, but as soon as I tried to ani ...

"Enhanced visuals with parallax scrolling feature implemented on various sections for an engaging

With 4 sections, each featuring a background image and text in the middle, I encountered an issue when attempting to have them fixed while scrolling. The goal was for the section below the first one to overlap the one above it along with its text as we scr ...

Unable to execute an Angular 2 application within Visual Studio 2015

I encountered an error while trying to set up an environment on VS 2015 with Angular2. Whenever I run the command "npm start," I receive the following error message. I attempted using "npm cache clean --force" before running "npm start," but the error pers ...

What causes the Vue.http configuration for vue-resource to be disregarded?

I am currently utilizing Vue.js 2.3.3, Vue Resource 1.3.3, and Vue Router 2.5.3 in my project while trying to configure Vue-Auth. Unfortunately, I keep encountering a console error message that reads auth.js?b7de:487 Error (@websanova/vue-auth): vue-resour ...

The function for the "load next page" action in ngInfiniteScroll is continuously triggered

After attempting to implement infinite scrolling using the "loading remote data" example from the ngInfiniteScroll website, I am facing a problem. The function nextPage() is being called continuously until all records have been loaded (controlled by an of ...

How to Calculate the Time Interval Between Two CORS Requests Using jQuery AJAX

When using jQuery's $.ajax to make a CORS request to a web service, there is typically a pre-flight request followed by the actual POST request. I have observed that when there is a time gap between making two web service calls, both a pre-flight and ...

Is there a way to prevent a user who is already logged in from accessing their account on a different browser or tab

My current stack consists of reactjs, nodejs, and redux for user authentication. I am utilizing aws cognito to handle the user authentication process. The main functionality of my app is uploading files from users to an s3 bucket. One of my goals is to p ...

"Comparison: Java Installation vs. Enabling Java in Your Web Browser

Is there a method to determine if Java is currently running on your system or if it has been disabled in your browser? Our application relies on Java applets, and we typically use "deployJava.js" to load the applet. However, even when Java is disabled in t ...

Vue unit testing for reactive state functions

Unit testing is a new concept for me, especially when dealing with reactive state in components. I am looking to write unit tests for a component that contains reactive state. Below is an example of the test component: <script setup lang="ts" ...

(basic) Issue with Jquery ajax request not receiving data

The alert box is not displaying anything and is not returning any data from the specified URL, even though it should show the Google page! Any suggestions? I am using the POST method because I need to send querystring data as well. $.ajax({ ...

The JWT Cookie has successfully surfaced within the application tab and is now being transmitted in the request

When sending a JWT token to an authorized user in Express, the following code is used: The cookie-parser module is utilized. module.exports.getUser = async (req, res, next) => { console.log('i am in getuser'); const { SIT } = req.query; ...

Performing mathematical operations in JavaScript, rounding to the nearest .05 increment with precision up to two

Apologies in advance. After reviewing multiple posts, it seems like the solution involves using the toFixed() method, but I'm struggling to implement it. $('.addsurcharge').click(function() { $('span.depositamount&ap ...

What is the method to show text on hover in angularjs?

I'm a beginner in AngularJS and I'm looking to show {{Project.inrtcvalue}} when the mouse hovers over values. Can anyone guide me on how to achieve this using AngularJS? <table ng-table="tableParams" show-filter="true" class="table" > ...

Ways to transfer information to a child component using the <input> tag and v-model

Trying to pass a value from a parent component to a child component, the code below shows how the property in the child component is bound to v-model. <input :value="refInputModel" @input="refInputModel = $event.target.value" ...

Hover shows no response

I'm having trouble with my hover effect. I want an element to only be visible when hovered over, but it's not working as expected. I've considered replacing the i tag with an a, and have also tried using both display: none and display: bloc ...

How can I properly integrate multer with Node and Express in this situation?

I've been working on setting up a route for uploading photos, but after making some changes, it has stopped functioning and I'm not sure how to fix it. const multer = require('multer'); // MULTER STORAGE const multerStorage = multer.di ...

The resolution of the Ajax call promise remains elusive

When I make an AJAX call to a REST API in my JavaScript code, the purpose is to fetch a JSON file. The structure of the AJAX call resembles something like this: $.ajax(ajaxObj).then(function(response) {}).catch(function(err) {}); The network monitor refl ...