0

When a function is used outside the vue instance and passed inside method mounted, why is the reference to 'vm' lost?

https://jsfiddle.net/z9u39hgu/5/

var vm = new Vue({
    el: '#app-4',
    data: {
        isLoading: true
    },
    mounted: function() {
        hello();
    }
});


function hello() {
    console.log(JSON.stringify(vm));
    //vm.isLoading = true;
    setTimeout(function() {
        console.log(JSON.stringify(vm, replacer));
        //vm.isLoading = false;
    })
}

//Extra code ignore
seen = []; 

var replacer = function(key, value) {

if (value != null && typeof value == "object") {
    if (seen.indexOf(value) >= 0) {
        return;
    }
    seen.push(value);
}
return value;

};
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.js"></script>
<div id="app-4">
    <p v-if="isLoading">Vuejs loading...</p>
</div>

1 Answer 1

4

It seems that mounted() is fired from the Vue constructor, i.e. before the vm variable can be even assigned. So the vm reference is not lost, but it is still undefined when hello() is called.

The timeout() callback is called later when the Vue constructor already returned and vm variable is assigned. The chronology of these events is also visible in the console.

var vm = new Vue({
    el: '#app-4',
    data: {
        isLoading: true
    },
    mounted: function() {
        hello();
    }
});


function hello() {
    console.log("before timeout: " + typeof(vm));
    //vm.isLoading = true;
    setTimeout(function() {
        console.log("after timeout: " + typeof(vm));
        //vm.isLoading = false;
    })
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.js"></script>
<div id="app-4">
    <p v-if="isLoading">Vuejs loading...</p>
</div>

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks to explain. So what is the best Vue way to write this code? I don't like the idea of using setTimeout. In a second try I passed the 'this' as parameter in the hello function and worked, but err.. Shouldn't Vue deal with it in a better way?
Maybe you could make the hello() function a method within the Vue instance. Then you do not even need to assign vm and you can just refer to this... v1.vuejs.org/guide/events.html
Yeah, I could do that or call it outside of the Vue instance. Either way, it will work. Probably I need to change my mind and roll like that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.