Reactivity in Vue 3 with globalProperties

When attempting to migrate a Vue 2 plugin to Vue 3, I encountered an issue in the install function. In Vue 2, I had code that looked like this:

install(Vue, options) {
  const reactiveObj = {
    // ...
  };

  Vue.prototype.$obj = Vue.observable(reactiveObj);
}

This allowed me to access this.$obj in any component and have it reactively update when reactiveObj changed. However, in Vue 3, my attempt to replicate this behavior resulted in:

import {reactive} from 'vue';

install(app, options) {
  const reactiveObj = reactive({
    // ...
  });

 app.config.globalProperties.$obj = reactiveObj;
}

In this case, while I can access this.$obj, it is now a Proxy object and does not reactively update when reactiveObj changes. How can I achieve reactivity in this scenario?

Answer №1

Whenever I update the value of $obj in my component, I like to share the working codes that have helped me figure out potential issues in my code. Below is the snippet from my "myPlugin.js" file where the plugin is defined:

myPlugin.js:

import {reactive} from 'vue';

export default {
    install(app, options) {
        const reactiveObj = reactive({
            id: 1,
            name: "my-name"
        });

        app.config.globalProperties.$obj = () => {
            return reactiveObj
        };
    }
}

The next step involves registering the plugin in my main.js file as shown below:

import { createApp } from 'vue'

import App from './App.vue'

import myPlugin from "./plugins/myPlugin"

const app = createApp(App)

app.use(myPlugin);
app.mount('#app')

Finally, here's a glimpse of the code within my component that allows users to change the values of $obj by clicking a button while highlighting its reactive nature:

component.vue:

<template>
  <div>
    <p>{{ $obj() }}</p>
    <button @click="myFunc">click to change</button>
  </div>
</template>

<script>
import {getCurrentInstance, reactive} from "vue";
export default {
  setup() {
    const thisApp= getCurrentInstance()
    const reactiveObj1 = reactive({
      id: 2,
      name: "new-name"
    });

    const myFunc = function () {
      thisApp.appContext.config.globalProperties.$obj().name = reactiveObj1.name
      thisApp.appContext.config.globalProperties.$obj().id = reactiveObj1.id
    }

    return {
      reactiveObj1,
      myFunc
    }

  }
}
</script>

Incorporating getCurrentInstance in my component has been essential due to my preference for using the composition API style. However, if you are more inclined towards the "options API" style, you may not need to utilize it.

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

Is it possible to wait for two asynchronous actions using only one await statement?

I have a situation where I am dealing with a node module that exports a promise to resolve a database connection. Once this connection is resolved, I then need to use it to query records which involves another asynchronous operation. Is it possible to hand ...

A Guide to Handling Errors while Converting a Map to a Promise in Typescript

I am attempting to capture errors if any of the asynchronous code within my map function fails. It seems to enter the error block but does not log anything, as the error variable remains null. Is there an alternative method for handling errors within map ...

Issue with error handling in Node and MongoDB when using Express, Mongoose, and the 'mongoose-unique-validator' plugin

I am facing an issue with the 'mongoose-unique-validator' plugin when trying to handle Mongo ValidationError in my custom error handler. Despite other errors being handled correctly, this specific one is not triggering the desired response from m ...

Obtain a multiline match using regular expressions

Is there a way to use regex to match only multi-line strings without matching single-line strings as well? Here is the current regex I am using: Regex ('|"|`)[\s\S]*?(\1) Test string "not a match" "need to match&qu ...

Display an additional HTML page without altering the existing one

First of all, I would like to apologize for my poor English. Attending a French school didn't provide much opportunity to practice other languages. I have a header.html on my website that I am unable to modify because it is not owned by me. However, ...

How to send parameters to the jquery .css() method

I'm attempting to create hyperlinks that can dynamically set inline styles for different elements on a webpage. I have managed to save the element and attribute settings in hidden span elements and retrieve them to display in an alert dialog. However, ...

Resolving problems with jQuery auto-populating select dropdowns through JSON data

I am facing an issue with auto-populating a select dropdown using jQuery/JSON data retrieved from a ColdFusion CFC. Below is the code snippet: $(function(){ $("#licences-add").dialog({autoOpen:false,modal:true,title:'Add Licences',height:250,wid ...

Incorporating external script into React website's functional component

I have invested countless hours on this particular issue, which appears to be quite trivial, yet I am unable to pinpoint where my mistake lies. I recently purchased terms and conditions from Termly.com and now wish to showcase these terms and conditions o ...

Encountering Uncaught Syntax Error when attempting a request with JSON parameters

Currently, I am using Fetch to send a post request to my server while including some additional information. Here's the code snippet: var rating = document.getElementById("rating"); var ratingValue = rating.innerHTML; fetch("/films",{ method: "po ...

Issue with React conditional display not functioning properly post user input into a form

Thank you in advance for your help. I am working on a component that displays a button based on the const results. However, I noticed that when I insert "Balaton," the button only appears after I add another character to the string. So the string becomes ...

Guide to seamlessly navigating to an element using a hash in NuxtJS

My aim is to create a smooth scrolling anchor link menu using Nuxt.js, where the user can click on a link and be directed to the corresponding page section. However, I'm facing a dilemma as there are multiple approaches to achieve this functionality, ...

JavaScript utilized to create a fully immersive full-screen webpage

I have been trying to implement a code for creating a full-screen website that works on all browsers. Unfortunately, my current code only seems to be functioning properly on Mozilla browser. When I try to view the site in Chrome and make it full screen, it ...

Struggling with loading react storybook

I am having trouble getting my storybook app to start. It is stuck in a loading state with no errors showing in the console. Can anyone help me figure out what I am doing wrong? Check out the screenshot here storybook/main.js const path = require(' ...

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 ...

Ways to activate the built-in HTML5 form validation without actually submitting the form

I have a form in my application that I plan to submit using AJAX. However, I would like to implement HTML5 for client-side validation. Is it possible to trigger form validation without actually submitting the form? Here is an example of the HTML code: &l ...

Controlled Material-UI v5 DateTimePicker triggers input focus upon closure

Is there a way to have 2 DateTimePicker components as siblings, and when I click on the second one while the first one is still open, it should open a new DateTimePicker with focus on it? Can someone help me achieve this? Link to code example I want the ...

Why isn't the Nunjucks extends directive functioning when the template is stored in a different directory and being used

I have successfully integrated nunjucks templating into my express app. Below is the directory structure of my project: . nunjucks-project |__ api |__ node_modules |__ views |__ templates |__ layouts |__ default.html ...

The onload function in jQuery is not functioning properly when the page is refreshed

I'm just starting out with jquery and I have a simple project in mind. The idea is to have two pictures stacked on top of each other, but I want the page to start showing the second picture first (at a specific scroll point). Then as the user scrolls ...

Encountering npm error code 1 during npm installation in a Vue.js project

Recently, I installed VueJS Material Dashboard (with Laravel), but encountered an issue with the npm install command on this VueJS template. The error message displayed was related to gyp and python39. Even when running the node.js command prompt as admini ...

Is it possible to use AngularJS to show additional information between rows when a table row is clicked in HTML

I'm currently working on an html table where the <tbody> is generated using angular's ng-repeat. Take a look at my html: <tbody ng-repeat="car in carList | filter:tableFilter"> <tr> <td><a target="_blank" h ...