Passing a Vue 2 property to a custom web component built with Vue 3

I have a very specific question regarding Vue2 and Vue3 integration.

In my main project, I am using Vue2 and I have included my Vue3 web components project as an npm library. The issue I am facing is that when I pass an object as a property to the Vue3 web component from the Vue2 project and then make changes to that object (e.g., push a new value into an array), the watcher or computed property inside the Vue3 web component does not detect the change. The only way to see the change reflected is by copying the object, which is not ideal. Interestingly, when I use Vue3 for both projects, everything works perfectly fine.

Can someone provide assistance or explain why this behavior occurs?

Below is the code snippet for the Vue2 project where deep watching is implemented to detect changes:

<template>
  <div>
    <problem
        :testObject.prop="testObject"
        @testEmit="pushArray"
    />
    {{ testObject }}
  </div>
</template>

<script>
export default {
    data()
    {
        return {
            testObject: null,
        };
    },
    created()
    {
        this.testObject = {
            objectArray: [1, 2],
        };
    },
    methods:
    {
        pushArray()
        {
            this.testObject.objectArray.push(5);
        },
    },
    watch: {
       testObject:
       {
           handler(newVal)
           {
               console.log('View watcher triggered', newVal);
           },
           deep: true,
       },
   },
};
</script>

And here is the code snippet for the Vue3 web component where watchers/computed properties are not detecting the prop change:

<template>
    <div>
        Prop Object {{ testObject }}
        <hr>
        Ref Object {{ objectWithArray }}
        <br>
        <button @click="pushArray">
            Push array
        </button>
    </div>
</template>

<script lang="ts">
import {defineComponent, watch, computed} from 'vue'

export default defineComponent(
{
    props: {
        testObject: {
            type: Object,
            default: () => (null),
        }
    },
    emits: ['testEmit'],
    setup(props, ctx)
    {
        const objectWithArray: any = computed(() => 
        {
            console.log('Computed triggered');
            return props.testObject;
        })

        const pushArray = () =>
        {
            ctx.emit('testEmit');
        }
        

        watch(
            () => props.testObject,
            (newVal) => 
            {
                console.log('Component watcher triggered', newVal);
            },
            {deep: true}
        )

        return {
            pushArray,
            objectWithArray
        }
    }
})
</script>

Answer №1

The standard behavior of props in Vue 2

By default, props do not automatically watch for changes at deeper levels.

In Vue 2, there are two suggested solutions outlined in the documentation: https://vuejs.org/guide/essentials/watchers.html#deep-watchers

1. Explicitly monitor specific properties

watch: {
    'some.nested.key'(newValue) {
      // ...
    }
}

2. Enable deep-watching on the entire prop

export default {
  watch: {
    someObject: {
      handler(newValue, oldValue) {
        // Note: `newValue` will be equal to `oldValue` here
        // on nested mutations as long as the object itself
        // hasn't been replaced.
      },
      deep: true
    }
  }
}

Refer to @yoduh's insightful point below regarding Vue 3 composition API inherently supporting deep watching.

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

How to retrieve only the last value from a JSON object using jQuery's .html

I'm having an issue with jQuery("#someID").html. It seems to only display the last name from the JSON data. Here is the javascript code: <div class="row" id="fetchmember"> <script type="text/javascript"> jQuery('#group').cha ...

Improving the Performance of DisplayField Binding in ExtJS 5

When I trigger a window to create a new item, there is a noticeable lag when passing in the record for the bound fields. The record is essentially a blank one with default values provided by the framework. In this demo, there are 3 buttons: The first but ...

Trouble with escape sequences in regular expressions within jQuery Terminal for JavaScript

I'm experimenting with special character functionality in jQuery terminal. While I was successful in implementing the backspace functionality, I encountered an issue when trying to execute the escape functionality. Below is the code snippet I used: ...

Animating a Canvas to Follow Mouse Coordinates

I am looking for a way to animate a circle moving towards specific coordinates, similar to the game . I have attempted using the jquery animate() function, but it is too slow due to the constant updating of the target coordinates. Is there a faster metho ...

Ways to grab the outermost element when a click event happens

When I click on a div, I want to retrieve the innermost element like so: <div id="show_trash_id" class="switch switch-xs"> <input type="checkbox"/> <span class="slider round"> <span cl ...

Encountered unexpected character error while parsing JSON data

I am encountering the following error message: JSON.parse: unexpected character when I execute this code in firebug: JSON.parse({"balance":0,"count":0,"time":1323973673061,"firstname":"howard","userId":5383,"localid":1,"freeExpiration":0,"status":fals ...

The jQuery spoiler functionality is rather basic and only partly functional

I decided to create a very basic jQuery spoiler feature by using the code below: HTML: <a href="" onclick="return false" class="spoiler" content="spoiled content"> Reveal spoiler </a> jQuery / Javascript: $('a.spoiler').cli ...

Retrieve the prior position using the AngularJS ui-router

Utilizing fromState and fromParams within the $stateChangeSuccess event allows us to access all details regarding the previous location. This concept is elaborated in the following discussion: Angular - ui-router get previous state $rootScope.$on('$s ...

What is the best way to handle an AJAX request within an if-else statement?

Attempting to utilize an if-else condition in order to make a jQuery Ajax call to an API. Having trouble understanding why the ajax function is being called even though it should be in the else statement. Below is the code snippet: if (e.value == null | ...

Compatibility issues between XMLHttpRequest and curl

Today, I am attempting to create a small XHR in JavaScript, Java, and C#, but it's not working for some reason... Below is the code snippet: var xhr = new XMLHttpRequest(); function init(){ xhr.open("POST","http://www.opsu.gob.ve/portal/controles/ ...

Looking to transform the promise value within a chai-as-promised statement

There’s a promise that resolves to an object which has a method called .toString that needs to be tested. Unfortunately, the current expression fails because the promise is an object being compared to a string: chai.expect(mypromise).to.eventually.be.eq ...

Multiple AJAX Requests in JavaScript Are Providing Incorrect Data Simultaneously

My current challenge involves populating an array with strings from two separate ajax calls. These strings are then used to create div elements with IDs matching the string names, each containing data retrieved from twitch streamers via the ajax requests. ...

The incorporation of zoom disrupts the smooth scrolling capability of the menu

My landing page has a menu that scrolls users to the selected section. However, my client prefers the page at a 90% zoom level. To accommodate this request, I added the following line of code: body { zoom:90%; } Unfortunately, when I click on a menu o ...

What is the best way to utilize clip() in html canvas when using text as a path?

I have written the code below, which is close to what I am trying to achieve but doesn't quite get there. My goal is to fill text in multiple colors, currently it is only in #FF00FF. Check out the Playground I suspect the issue lies in my lack of kn ...

When working with JSON in Angular, the JSON pipe may display an empty string for values that are "undefined"

When utilizing the json pipe within Angular, it displays a blank for any undefined values. <pre>{{undefined | json}}</pre> The output on the DOM is as follows: <pre></pre> This behavior differs from the JSON stringify function. ...

What is the best way to implement Axios for data fetching in Gatsby's useStaticQuery function?

One way to fetch data in Gatsby is by using GraphQL, like in the following example: import { graphql, useStaticQuery } from "gatsby" const IndexPage = () => { const gatsbyRepoData = useStaticQuery(graphql` { github { repo ...

I am currently working on building a single-page application using React and Vite. However, I am facing an issue where the page is not rendering anything and just displaying a blank screen. Can anyone provide guidance on troubleshooting and

I am currently facing an issue while trying to build a react website using Vite. No matter what I do, nothing seems to render on the page. I even tried removing the react-router-dom and directly rendering the Home file, but still no luck. It appears that i ...

Encountering naming problem with ng-model, attempting to create an array but receiving a hash instead

Trying to create an array using ng-model, <div ng-repeat="n in [1, 2, 3]"> <input type="text" class="form-control" ng-model="headers[$index].key"> <input type="text" class="form-control" ng-model="headers[$index].value"> </div> ...

If a div element includes a specific text, then update that portion of the text without altering the value of any variables

Need help removing text without affecting variables Attempting to translate a specific line with JQuery Looking to change text only, leaving the content within the strong tag intact $('.content-box__row div:nth-child(3)').text('') ...

Developing a single page that caters to various users' needs

Greetings to all my friends, As a front end developer, I am in the process of implementing a dashboard for a project that involves different users with varying permissions. Each user should only have access to certain parts of the page, resulting in some ...