Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to assign a value to a vue component data member in mounted event [duplicate]

I have been reading the vue documentation and starting to write some code to test my knowledge. I have tried to write a component that sets a data member when mounted but it seems not to work as expected. The component data member "profiles" is always empty. My intuition says it could be something about scope but not sure:

Vue.component('profile-grid', 
{
    template: '<section> {{profiles}} </section>',
    //Data es la parte privada del documento. Props la parte publica que se deberia de pasar desde la instancia Vue
    data: () =>
    {
        return {
            profiles: []
        };
    },
    methods:
    {
    },
    created: () =>
    {
        //console.log("I was just created")
    },
    mounted: () =>
    {
        //console.log("I was just mounted")
        this.profiles = ['1', '2', '3'];     
    }

})

//Vue instance
new Vue(
{
    el:'main',
    data:
    {
    },
    methods:
    {
    },
    mounted: () =>
    {
    }

});

HTML Page

//HTML Page
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Page Title</title>
</head>

<body>
    <main>
        <profile-grid></profile-grid>
    </main>
</body>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="main.js"></script>

</html>

Do anybody know what is happening?

Thanks in advance.

like image 524
Notbad Avatar asked Aug 31 '25 17:08

Notbad


2 Answers

Don't declare Vue hooks, methods and etc as arrow functions. Arrow function use this from parent context.

An arrow function does not have its own this; the this value of the enclosing execution context is used.

You should use method definition syntax or function declaration to be able use this as Vue instance:

mounted: function() {
    //do something
}

OR

mounted() {
    //do something
}

See Vue docs notice in the bottom of the section.

like image 105
Max Sinev Avatar answered Sep 02 '25 07:09

Max Sinev


You have stumbled upon one of vuejs reactivity caveats. Basically you are replacing the original profiles in a way that Vuejs cant react to, thus it is not getting updated.

One way to notice the change in the array is to first assign the data property as null and assign a Array in the mounted method later. Another way you can update a reactive Array later is to use array mutation method like push or non mutation method like map to generate a new array and replace the older array with new one.

Vue.component('profile-grid', {
    template: `
        <section> 
          <div>{{profiles && profiles.length ? profiles : ''}} </div>
          <div>{{profilesTwo && profilesTwo.length ? profilesTwo : ''}}</div>
        </section>`,
    data () {
        return {
            profiles: null,
            profilesTwo: []

        };
    },
    created () {
        //console.log("I was just created")
    },
    mounted () {
        //console.log("I was just mounted")
        this.profiles = ['1', '2', '3'];  
        this.profilesTwo = ['5', '4', '6'].map(item => item)   
    }

});

new Vue({
    el:'#app',
    data () {
      return {}
    },
    mounted () {
      console.log('vue instance mounted');
    } 
});
<script src="https://unpkg.com/vue"></script>

<main id="app">
    <profile-grid></profile-grid>
</main>
like image 30
slumbergeist Avatar answered Sep 02 '25 07:09

slumbergeist