I am a little confused on when to use the "this" word in vue.js. For example, in the code below everywhere I use "vm" instead of "this" the code does not work.
I have also seen some examples using "self", however I am not a javascript guru and this is really confusing.
var vm = new Vue({
el: '#app',
data: {
tickets: [],
top: 100,
search: '',
showAdd: false,
},
mounted: function () {
this.$nextTick(function () {
console.log('mounted');
this.GetTickets(100);
})
},
methods: {
GetTickets: function (top) {
axios.get('/api/Tickets', {
params: {
Top: top
}
})
.then(function (response) {
vm.tickets = response.data;
})
.catch(function (error) {
console.log(error);
});
},
ClearTicket: function () {
var t = {
"ticketSubject": '',
"contactName": '',
"createdAt": moment()
}
vm.ticket = t;
vm.showAdd = !vm.showAdd;
},
AddTicket: function () {
//vm.tickets.unshift(vm.ticket);
axios.post('/api/Tickets', vm.ticket)
.then(function (response) {
console.log(response);
vm.GetTickets(100);
})
.catch(function (error) {
console.log(error);
});
vm.showAdd = false;
}
},
})
I would typically mark this question as a duplicate, however, I feel this specific question merited a little more explanation because of the overall confusion about
this
in general, and how it should be used in Vue specifically.Typically, inside methods, or computed properties or lifecycle handlers in Vue, you will use
this
to refer the component to which the method/computed/handler is attached.this
refers to the context in which the function is currently executing.Where you get into trouble using
this
is when a new function is declared in the context of the current function, as happens when you write a callback to a promise (axios.post
,axios.get
). Consider this code:In the above code, the first comment could be replaced with code that uses
this
to get data properties or call methods of the Vue (this.tickets
). The second comment, however is inside a new function context, andthis
will NOT refer to the Vue. This is because in Javascript when you declare a new function using thefunction() {}
syntax, that function has its own function context which is different from the function in which it is declared.There are several ways to deal with this in Javascript. The most common these days are to either use a closure to capture the correct
this
, or to use an arrow function. Consider this code:Note that in this example, the callback is defined using an arrow function (
() => {}
). Arrow functions do NOT create their own function context and use the context in which they are declared. This is also known as having a lexical scope.The other most common workaround is using a closure.
Finally, you can use the bind method to create a function with a specific
this
, though this is not as common these days with arrow functions available.In almost no case, should you really be doing what you do in your question, which is save a reference to the Vue in the variable
vm
and use that variable inside the Vue object itself. That's a bad practice.In any case, how to use the correct
this
is covered in detail in numerous posts throughout the internet and here on StackOverflow as well.Finally, here is the code from the question revised such that
this
should be used correctly.In the end, it is simple. Until you do not fully understand how it works, just follow these simple rules:
Use
this
everywhere in Vue object, and use its reference identifier outside:Never use reference name inside the referenced object itself. Outside the Vue object you have no other choice, you just must use the reference name.
Inside Vue,
this
content may vary. And will. It is just another object, automatically created within each function/object. So you need this second rule: before you dive to nested, second level function, savethis
to reference/variable. Why:As mentioned above, every function obtains it's own
this
object. So, with 'this.something = false' you just created new property 'something' in 'this' object in nested, second level function, instead of changing 'this' in first level function. In other words, in nested function you lost reference to previousthis
from first level function, as it's content was overwrited with newly created content in process of nested function creation. So, if you need to usethis
object form first level function in nested function, just save it under another name, which will be not overwrited:As you can see, you can save it under any name. But follow the convenience and name it as
self
. Notvm
, as this name can confuse you again, whether it will collide withvar vm = new Vue()
, or not. It will not, but doesn't confuse yourself and just name it asself
.Does not experiment with arrow functions, do not use bind. Just follow this simple rules. Later, you will be more experienced, you can (and should) use them, but for now, enjoy the coding, not debugging :)