Is there a way to modify Vue component properties using plain JavaScript code?

I am currently working on a Vue 2 project developed using Vue CLI, and my goal is to package it as a library. I want to create a wrapper script that abstracts away dependencies and Vue syntax to enable easy interaction like the examples below:

// Mounting the component on a plain JS webpage
const myComponent = new MyComponent('#my-component');

// Handling events from the component in vanilla JS
myComponent.on('load', someHandler);

// (A.) Calling a component method and getting a return value
const processedData = myComponent.process(123);

// (B.) Accessing/mutating reactive component data properties
myComponent.setMessage('Hello world!');

I have attempted to modify the "build target" according to the instructions in the Vue documentation to build a Library or Web Component. While I can successfully mount the library component and handle events, there is no mention of how to interact with the component data externally from the Vue VM (referencing comments A and B).

What is the best approach to accessing Vue component methods and data properties from outside the Vue VM using vanilla JavaScript?

Answer №1

If you want to access the properties and methods of a Vue component outside of the Vue instance, you can use a "template ref" to mount it like this:

const vm = new Vue({
    components: {
        MyComponent,
    },

    template: `
        <my-component
            ref="myComponent"
        />
    `,
}).$mount('#mount-element");

After mounting, you can call its methods as follows:

vm.$refs.myComponent.someFunction();

This will allow you to retrieve values and manipulate reactive properties inside the Vue instance. To implement the class syntax mentioned in the original question, you can create a simple class that encapsulates the Vue component:

// Import the Vue CLI-built component using the "library" build target
// (exports `MyComponent` globally)
import './MyComponent.umd.min.js'; 

import Vue from 'https://unpkg.com/vue@2/dist/vue.esm.browser.min.js';

export default class {
    constructor(mountElement) {
        // Mount the Vue VM with a template ref for property access
        const thisClass = this;
        this.vm = new Vue({
            components: {
                MyComponent,
            },

            template: `
                <my-component
                    ref="myComponent"
                />
            `,
        }).$mount(mountElement);

        this.component = this.vm.$refs.myComponent;
    }

    // Define methods that can invoke this.component's functions
    someFunction() {
        // Perform actions
        return this.component.someFunction()
    }

}

This method works effectively. One potential enhancement could involve building the component library using a different tool, since Vue CLI v3 (for Vue v2 projects) does not support ESM module file output, resulting in a global UMD module definition.

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

Discovering if an ID already exists in a Firebase real-time database with React.js

https://i.sstatic.net/i1QVd.png Currently, I am engaged in a React inventory project. In order to avoid duplication when pushing data into the progress.json file, I need to ensure that the data is not already present by checking for the unique id associat ...

Steps to have the initial link redirect to a designated webpage

I am working with tables that have links defined in the HTML. I want to modify the behavior so that the first link opens a different URL, for example: john.com. Is it possible to achieve this? Specifically, I want the link associated with the first name ( ...

JavaScript: A guide to solving systems of equations

I'm attempting to perform algebraic operations in JavaScript using certain conditions and known variables. However, I lack proficiency in mathematics as well as JavaScript to comprehend how to articulate it. Here are the conditions: var w1 = h1/1.98 ...

Generate three random names from an array and assign them to an element

This website is amazing! I've interacted with so many awesome people here! Currently, I have successfully implemented code to get one random name from an array. However, I now want to display three different names each time, and I'm facing a roa ...

Insert fresh user information into the div

Learning JavaScript is a challenge I'm tackling. I have a question that may seem trivial, but any assistance would be greatly appreciated. I currently have this code: Javascript <script type="text/javascript"> function fn(){ var Name = ...

When you define a parent route in Vue Router with no specified path, it automatically matches the root route of the application

I'm currently setting up a Vue Router with a homepage having a path of '/'. Additionally, I have a parent template consisting of a header and footer with children. I intend for only the children to have paths, not the parent. However, when I ...

Argument-based recursive method

Why is the script only printing 'Hello' and not 'Good bye' as well, even though both are passed as arguments on the function call? What could be causing this issue? Note: The script used to work before. It stopped working after adding ...

Tips to prevent the webpage from scrolling to the top when clicking on an anchor with an ID

I have developed a CSS/HTML carousel that consists of 4 slides. The goal is to display the selected slide when clicking on the bottom button (a href). However, I am facing an issue where every time I click on a link, the selected slide appears as intended ...

Ingesting RSS feed into an Express server

I've been searching for hours, but I just can't seem to find a solution. I was able to figure things out when working on the client side, but now that I'm trying to load posts on the server and render them in the view, I'm hitting a roa ...

JavaScript does not function properly with dynamically loaded content

Trying to load the page content using the JQuery load() method. See below for the code snippet: $(window).ready(function() { $('#content').load('views/login.html'); }); .mdl-layout { align-items: center; justify-content: center ...

Personalized HTML selection list

When a select option is too long, it stretches the container to accommodate its length. I have created a truncate function to limit the display to 20 characters and add ellipses to prevent this stretching. I have been searching for a way to show the entir ...

Node.js: How to handle spaces when running a UNIX command

Currently, I am utilizing the following command to compress files in node.js: var command = '7z a ' + dest + ' ' + orig; exec( command, function(err, stdout, stderr) { ...}); An issue arises when a file containing spaces is involved, ...

Adjusting the width of the rail in Material UI's vertical Slider component in React

After attempting to adjust the width and height of the rail property on the material ui slider I obtained from their website demo, I have encountered an issue with changing the thickness. import React from "react"; import { withStyles, makeStyles } from " ...

The checkbox is not updating as anticipated

I'm currently developing a basic widget that allows the user to change the value of either the check box OR the entire div by selecting them. Below is the code I have implemented: $(document).ready(function() { $(document).on("click", ".inputChec ...

Using PHP to dynamically update image source upon clicking an upload button:

Is it possible to dynamically display a new image after uploading it using an ajax-upload script on a 'edit product' page for a shop products? On load, all thumbnails are fetched from the DB but when a user uploads a new file, I want the new imag ...

Having trouble with Angular's ng-class performance when dealing with a large number of elements in the

I've encountered a performance issue while working on a complex angular page. To demonstrate the problem, I've created a fiddle that can be viewed here. The main cause of the performance problem lies in the ng-class statement which includes a fu ...

I'm experiencing very slow page load times in dev mode with Next.js (30s+). What could be the reason behind this sluggishness?

QUESTION: Encountering a similar issue (but with different files): https://github.com/vercel/next.js/discussions/17977 I've already tried all the suggestions provided in that discussion. This is what the page load process looks like in development ...

Uh-oh! Angular 6 has encountered an unexpected error with template parsing

I am currently working on an Angular application where I have integrated the FormsModule from '@angular/forms' in my app.module.ts. However, despite this, I keep encountering the error message No provider for ControlContainer. Error log: Uncaug ...

How can I use Angular to dynamically open a video that corresponds to a clicked image?

I need assistance with a functionality where clicking on an image opens a corresponding video on the next page. The issue is that all images have the same ID, making it difficult to link each image to its respective video. Below is the data I am working ...

Is it possible to incorporate a combination of es5 and es2015 features in an AngularJS application?

In my workplace, we have a large AngularJS application written in ES5 that is scheduled for migration soon. Rather than jumping straight to a new JS framework like Angular 2+ or React, I am considering taking the first step by migrating the current app to ...