Vue watch[胖箭头范围]提供了错误的上下文[重复]

Posted

技术标签:

【中文标题】Vue watch[胖箭头范围]提供了错误的上下文[重复]【英文标题】:Vue watch[fat arrow scope] providing wrong this context [duplicate] 【发布时间】:2017-10-31 22:44:43 【问题描述】:

我正在使用 lodash 对函数调用进行去抖动,但我想知道为什么我的 this 值没有像我预期的那样继承范围。

这些是我的 Vue 组件的相关部分。

import debounce from 'lodash/debounce';

watch: 
    query: debounce(() => 
        this.autocomplete();
    , 200, 
        leading: false,
        trailing: true
    ),

上述情况不起作用,因为我的 this 值没有指向 Vue 组件,而是显示了这样的 Object:

Object
    __esModule: true
    default: Object
    __proto: Object

我的箭头语法不是应该继承this 的上下文吗?

以下似乎工作正常:

query: debounce(function test() 
    this.autocomplete();
, 200, 
    leading: false,
    trailing: true
)

这可能有一个简单的答案,但我希望有人可以在这里帮助我。

【问题讨论】:

如果您需要 Vue this 上下文,请使用常规函数而不是箭头函数。你可以在 Vue 的文档中找到它。 您可能应该阅读箭头函数的工作原理。例如。 exploringjs.com/es6/ch_arrow-functions.html @nils 它们的工作方式完全符合我的预期,只是显然不适用于 Vue。下面的答案解释了更多。 是的,这就是我想要指出的。很容易对箭头函数的当前作用域做出错误的假设(这与 vue 无关)。 我将发布一个单独的答案。 【参考方案1】:

见https://vuejs.org/v2/guide/instance.html#Properties-and-Methods

不要在实例属性或回调上使用箭头函数(例如vm.$watch('a', newVal => this.myMethod()))。由于箭头函数绑定到父上下文,this 不会像您期望的那样是 Vue 实例,this.myMethod 将未定义。

由于同样的限制适用于观察者,你必须使用这样的东西:

watch: 
    query: function() 
        return debounce(() => 
            this.autocomplete();
        ,
        200,
        
            leading: false,
            trailing: true
        );
   

【讨论】:

我应该阅读更多文档。谢谢,这正是我要找的! 额外参考gist.github.com/JacobBennett/7b32b4914311c0ac0f28a1fdc411b9a7【参考方案2】:

这只是解释箭头函数中this的误解的补充答案。

这在箭头函数中是如何工作的?

this 在词法函数中总是指周围的作用域。可以是:

    最近的周边函数 最近的周边模块 全球范围

如果我们查看您的代码,并假设您使用的是 ES6 模块(从 import/export 语句判断):

import debounce from 'lodash/debounce';

export default 
    watch: 
        query: debounce(() => 
            this.autocomplete();
        , 200, 
            leading: false,
            trailing: true
        ),
    
;

让我们来看看列表:

1.最近的环绕函数

您的箭头函数没有环绕函数。一个例子是:

var obj = 
    a: function() 
        return () => 
            console.log(this);
        
    
;

obj.a()(); // `this` refers to `obj`, because `this` refers to `obj` in the surrounding function `a`

2。最近的周边模块

由于在这种情况下我们处于(假)模块中,this 在模块范围内被定义为伪模块对象(可能是 babel 或 webpack 对象?)。

Object
    __esModule: true
    default: Object
    __proto: Object

好像是因为Vue默认绑定了这些属性、方法和事件

没错,它是 vue 的一个非常有用的特性。但在这种情况下它对我们没有帮助,因为 this 不能在箭头函数中被覆盖,它总是指向周围的范围

请查看以下链接以更深入地了解箭头功能:http://exploringjs.com/es6/ch_arrow-functions.html#_variables-that-are-lexical-in-arrow-functions

【讨论】:

谢谢,但我认为 str 的回答更准确,因为它实际上解决了您的问题。我只提供上下文。

以上是关于Vue watch[胖箭头范围]提供了错误的上下文[重复]的主要内容,如果未能解决你的问题,请参考以下文章

vue箭头函数注意事项

使用胖箭头(放屁)语法定义函数时,vim中的JSlint错误

vue之watch篇

vue 细节注意

如果在胖箭头函数内

vue 学习笔记