Vue组件this指向问题解析:为何需保存this调用组件方法?
this指向的疑问解答 这个问题的核心其实是JavaScript中this的绑定规则,跟Vue本身关系不大,咱们一步步拆解:
1. 为什么直接用this.methodName1会返回undefined?
在你的代码里,rp(options).then(function () { ... })里的回调函数是一个普通函数。JavaScript里普通函数的this指向是在函数被调用时决定的,而不是定义的时候。
当then方法执行这个回调函数时,它的调用上下文并不是你的Vue组件实例——在浏览器环境下,普通函数如果没有明确的调用者,this会指向全局对象window(严格模式下是undefined)。这个this根本不是你组件里的那个实例,自然找不到methodName1方法,所以会返回undefined。
2. 为什么var context = this后调用context.methodName1能正常工作?
在methodName2这个方法里,外层的this是指向Vue组件实例的——因为Vue会把methods里的方法绑定到组件实例上,当你调用this.methodName2()时,方法内部的this就是实例本身。
你把这个指向实例的this赋值给了context变量,然后在回调函数里通过闭包访问context。闭包会保留外层作用域的变量引用,所以context始终指向你的Vue组件实例,调用context.methodName1()自然就能找到对应的方法了。
3. 修改DOM元素时为什么需要保存this变量?
道理和上面一样:当你需要在回调里操作DOM相关的内容(比如通过this.$refs获取DOM元素,或者修改组件数据来更新DOM),如果回调里的this不是组件实例,你就没法访问Vue实例上的$refs、data里的变量或者其他方法。
保存context = this后,你就能通过context拿到组件实例,进而操作DOM相关的资源。
额外小技巧:用箭头函数简化代码
其实ES6的箭头函数可以帮你省去存context的步骤,因为箭头函数的this是继承自外层作用域的this,不会自己绑定新的上下文。比如你可以把代码改成这样:
methodName2: function () { rp(options).then(() => { this.methodName1() // 这里的this和外层methodName2的this一致,指向Vue实例 return null }).catch(err => { console.log(err) }) }
这样就不用额外声明context变量了,代码更简洁~
内容的提问来源于stack exchange,提问作者user9170426

