Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple VueJS issue (setting $data in mounted)

Edit

The Component.vue provided was part of a larger web app so I ripped out the relevant code for this question. What I didn't notice was a VERY tiny change I made in ripping out the code that had a very big impact.

There's a difference between:

mounted() {
    // ....
}

and:

mounted: () => {
    // ....
}

Upon careful investigation this morning I found this mistake in my code and I've updated the question to reflect the actual code that was failing.

Question

I may just be tired, but before going to bed I wanted to ask for help here and see if someone can find my issue. I have a very simple Vue component that isn't working:

Component.vue:

<template>
    <div>
        <p v-for="item in items">{{ item.text }}</p>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                items: []
            };
        },
        mounted: () => {
            var _this = this;
            $.ajax("/items.json").done(result => {
                _this.items = result;
            });
        }
    };
</script>

items.json

[
    {"text": "ABC"},
    {"text": "XYZ"}
]

The paragraphs are never rendering. Upon inspection it looks like _this.items doesn't exist prior to setting it in the AJAX handler (I expect it to be an empty array) and _this.$data also doesn't exist

~Is the value of this different in the mounted method than elsewhere in Vue?~ Or did I make a simple mistake?

Writing the mounted function in this way (with the colon) causes the value of this to be different. Why is that?

like image 805
stevendesu Avatar asked Jun 29 '26 14:06

stevendesu


1 Answers

Upon further research, I have learned of the subtle difference between normal functions and arrow functions. I previously thought the latter was just a short-hand, but it also does not have its own context.

The method mounted: () => {} utilizes an arrow function, and therefore

...does not have its own this, arguments, super, or new.target

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Here is a simple example demonstrating the difference which can be tested in the Chrome console

let testFunc = function() { console.log(this); }
testFunc(); // Window {...}
testFunc.bind("test")(); // String {"test"}
testFunc = () => { console.log(this); }
testFunc(); // Window {...}
testFunc.bind("test")(); // Window {...}

When utilizing an arrow function, it becomes impossible to bind a value to this. This means that in the Vue internals they are unable to bind the Vue instance to this.

The method mounted() { } is only utilizing the ES6 short-hand for objects, and not an arrow function (therefore it does have its own context and you can bind the this variable)

like image 128
stevendesu Avatar answered Jul 01 '26 04:07

stevendesu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!