由于复杂的 js 函数无法访问此对象 - Vuejs

Can't access this object due to complex js function - Vuejs

我正在为一个 VueJs 项目使用流行的 vue-select 组件。我想自定义一个 keyDownEvent 并查看了文档以了解如何实现这一点。我遇到了一个结合了现代 JS 技术的神秘示例。

<template>
  <v-select
          taggable
          multiple
          no-drop
          :map-keydown="handlers"
          placeholder="enter an email"
  />
</template>

<script>
export default {
  name: 'CustomHandlers',
  data: {
      variableIwantAccessTo: []
  },
  methods: {
    handlers: (map, vm) => ({
      ...map, 50: e => {
        e.preventDefault();
        if( e.key === '@' && vm.search.length > 0 ) {
          vm.search = `${vm.search}@gmail.com`;
        }
      },
    }),
  },
};
</script>

我理解 if 块中的简单逻辑,但我不理解导致它的所用技术的组合。我的自定义实现遇到的主要问题是丢失 this 对象的上下文。我想要这样的东西:

    handlers: (map, vm) => ({
  ...map, 50: e => {
    e.preventDefault();
    if( e.key === '@' && vm.search.length > 0 ) {
      console.log(this.variableIwantAccessTo);
    }
  },

我不知道如何通过这个实现传递它。 这是对文档的引用:https://vue-select.org/guide/keydown.html#mapkeydown

让我们分解一下这个函数:

  1. 您正在声明一个名为 handlers 的箭头函数,它接受名为 mapvm 的两个参数。

您失去上下文的原因是因为您使用箭头函数作为方法,如果将该箭头函数更改为常规函数,您将能够访问 this.

话虽这么说,它似乎是故意这样设计的,并且通过查看代码,我可以假设您应该将上下文作为第二个参数传递 - vm.

  1. 您正在 return 创建一个对象:在对象的第一部分,您正在使用扩展运算符来扩展 map 参数,据此我们可以假设 map也是一个对象,您想要 return 一个包含对象映射本身的对象。 (通过使用扩展运算符,您实际上是将 map 合并到您正在 return 的对象中。

您 returning 对象的第二部分是名称为 50 的 属性,此 属性 是一个接收事件的方法,在该事件上调用 preventDefault(),然后有一个 if 语句,如果该 if 语句通过,它将 vm.search 分配给某个值。

由于我们假设 vm 代表上下文,这与分配 this.search 相同,因此它实质上是在上下文中为变量分配特定值。

希望现在更清楚了:)

如你所见,这个案例实际上有两层功能,处理函数的原始样式省略了{},所以你没有地方定义一个self(引用this)外部函数。

在vue组件中,外层的this会指向组件,所以我们在这里声明self,然后在内层使用self作为闭包变量

我想这会奏效,请尝试一下。

export default {
  name: 'CustomHandlers',
  methods: {
    // handlers: (map, vm) => {
    // if it is arrow function,it can't do the trick 
    // thanks to  Yair Cohen
       handlers(map, vm) {
        const self = this;
        return {
          ...map, 50: e => {
            e.preventDefault();
            if( e.key === '@' && vm.search.length > 0 ) {
              vm.search = `${vm.search}@gmail.com`;
              // self will be this here
              const self2 = self;
            }
          },
        };
    },
  },
};

更新:代码已更改,外部函数从箭头函数变为普通函数,