我对何时在vue.js中使用“this”这个词感到有点困惑。例如,在下面的代码中,我使用“vm”而不是“this”代码不起作用。
我也看过一些使用“self”的例子,但我不是一个javascript大师,这真的很混乱。
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;
}
},
})
答案 0 :(得分:22)
我通常会将此问题标记为重复,但是,我觉得这个具体问题需要更多解释,因为总体上对SELECT COALESCE(@maybe_col, null) AS norm_col FROM database;
的总体困惑,以及如何在Vue中特别使用它。 / p>
通常,Vue中的内部方法或计算属性或生命周期处理程序,您将使用this
来引用方法/计算/处理程序所附加的组件。 this
指的是函数当前正在执行的上下文。
使用this
遇到麻烦的地方是在当前函数的上下文中声明一个新函数时,就像在回写一个promise(this
,{{1}时发生的那样})。请考虑以下代码:
axios.post
在上面的代码中,第一个注释可以替换为使用axios.get
来获取数据属性或调用Vue(AddTicket: function () {
// "this", on this line, refers to the Vue
// and you can safely use "this" to get any of the
// data properties of the Vue
axios.post('/api/Tickets', ...)
.then(function (response) {
// "this" HERE, does NOT refer to the Vue!!
// The reason why explained below
})
}
)方法的代码。然而,第二条评论是里面一个新的函数上下文,this
不会引用Vue。这是因为在Javascript中使用this.tickets
语法声明一个新函数时,该函数有自己的函数上下文,它与声明它的函数不同。
有几种方法可以在Javascript中处理这个问题。这些天最常见的是使用闭包来捕获正确的this
,或者使用箭头函数。请考虑以下代码:
function() {}
请注意,在此示例中,使用箭头函数(this
)定义回调。箭头函数不会创建自己的函数上下文并使用声明它们的上下文。这也被称为具有词汇范围。
另一个最常见的解决方法是使用闭包。
AddTicket: function () {
// As before, "this" here is the Vue
axios.post('/api/Tickets', ...)
.then((response) => {
// "this" HERE is ALSO the Vue
})
}
最后,您可以使用bind method创建一个具有特定() => {}
的函数,但现在这种情况并不常见,因为箭头函数可用。
AddTicket: function () {
const self = this // Here we save a reference to the "this" we want
axios.post('/api/Tickets', ...)
.then(function(response){
// and HERE, even though the context has changed, and we can't use
// "this", we can use the reference we declared (self) which *is*
// pointing to the Vue
self.tickets = response
})
}
在几乎所有情况下,你真的应该在你的问题中做你做的事情,这是在变量this
中保存对Vue的引用,并在Vue中使用该变量对象本身。这是一种不好的做法。
在任何情况下,许多帖子throughout the internet和here on StackOverflow都会详细介绍如何使用正确的AddTicket: function () {
axios.post('/api/Tickets', ...)
.then(function(response){
this.tickets = response
}.bind(this)) // NOTE the ".bind(this)" added to the end of the function here
}
。
最后,以下是修订过的问题中的代码,以便正确使用vm
。
this
答案 1 :(得分:4)
最后,很简单。在您不完全了解其工作原理之前,请遵循以下简单规则:
在Vue对象中的任何地方使用this
,并在外部使用其引用标识符:
var vm = new Vue({
// Use "this" inside
el: '#app',
data: {
something: true
},
created: function () {
this.something = false // like here
}
})
// Here, outside, use reference iditentifier,
// as you have no other choice
vm.something = null
永远不要在引用的对象本身内使用引用名称。在Vue对象之外,您别无选择,只需使用引用名称。
在Vue内部,this
内容可能会有所不同。还会。它只是在每个函数/对象中自动创建的另一个对象。因此,您需要第二条规则:在深入了解嵌套的二级函数之前,将this
保存到引用/变量。原因:
var vm = new Vue({
el: '#app',
data: {
something: true
},
created: function () {
// You are in first level function,
// you can use "this"
axios.get('/uri').then(function () {
// Here you are in nested, second level
// function. It will have own "this" object
this.something = false // no error here but...
// You did not changed "something" value in data object,
// you just created new property also called "something",
// but in this nested "this" object.
})
}
})
如上所述,每个函数都获得它自己的this
对象。因此,使用' this.something = false'你刚刚创造了新的物业'在'这个'嵌套的二级函数中的对象,而不是改变这个'在第一级功能。换句话说,在嵌套函数中,您从第一级函数中丢失了对先前this
的引用,因为它的内容在嵌套函数创建过程中被新创建的内容覆盖。因此,如果您需要在嵌套函数中使用this
对象形式的第一级函数,只需将其保存在另一个名称中,该名称不会被覆盖:
var vm = new Vue({
el: '#app',
data: {
something: true
},
created: function () {
var anyName = this // Save reference to this under another name
axios.get('/uri').then(function () {
this.something = false // no error here, but you are still creating new property
anyName.something = false // NOW you are really changing "something" value in data
})
}
})
如您所见,您可以使用任何名称保存它。但请按照便利性将其命名为self
。不是vm
,因为此名称可能会再次让您感到困惑,是否会与var vm = new Vue()
发生冲突。它不会,但不会让自己感到困惑,只需将其命名为self
。
不试用箭头功能,不要使用bind。只需按照这个简单的规则。稍后,您将更有经验,您可以(并且应该)使用它们,但是现在,享受编码,而不是调试:)