Vue手表[胖箭范围]提供错误的上下文

Ste*_*n-v 3 javascript ecmascript-6 vue.js vue-component vuejs2

我正在使用lodash去抖动函数调用,但我想知道为什么我的this值不像我期望的那样继承范围.

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

import debounce from 'lodash/debounce';

watch: {
    query: debounce(() => {
        this.autocomplete();
    }, 200, {
        leading: false,
        trailing: true
    }),
Run Code Online (Sandbox Code Playgroud)

上面的情况不起作用,因为我的this值不指向Vue组件,而是显示如下的Object:

Object
    __esModule: true
    default: Object
    __proto: Object
Run Code Online (Sandbox Code Playgroud)

我的箭头语法是不是要继承上下文this

以下似乎工作正常:

query: debounce(function test() {
    this.autocomplete();
}, 200, {
    leading: false,
    trailing: true
})
Run Code Online (Sandbox Code Playgroud)

对此可能有一个简单的答案,但我希望有人可以帮助我.

str*_*str 7

请参阅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
        });
   }
}
Run Code Online (Sandbox Code Playgroud)


nil*_*ils 7

这只是解释this箭头函数误解的另一个答案.

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

this在词汇函数中总是指周围的范围.那可以是:

  1. 最近的周边功能
  2. 最近的周边模块
  3. 全球范围

如果我们看一下你的代码,我们假设你正在使用ES6模块(从import/export语句判断):

import debounce from 'lodash/debounce';

export default {
    watch: {
        query: debounce(() => {
            this.autocomplete();
        }, 200, {
            leading: false,
            trailing: true
        }),
    }
};
Run Code Online (Sandbox Code Playgroud)

我们来看看清单:

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`
Run Code Online (Sandbox Code Playgroud)

2.最近的周边模块

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

Object
    __esModule: true
    default: Object
    __proto: Object
Run Code Online (Sandbox Code Playgroud)

似乎因为Vue默认绑定了这些属性,方法和事件

这是真的,这是vue非常有用的功能.但是在这种情况下它并没有帮助我们,因为this不能在箭头函数中重写,它总是指周围的范围.

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