无法将事件绑定到对象方法

cannot bind event to object method

我有一个 vue 单文件组件,它有一个自定义的 class 实例作为 属性:现在我想将一个事件绑定到这个 class 实例的方法但是我我有问题,我的代码文件有一个简化版本

VueJS 单文件组件

    <template>
        <div @click="class_prop.method"></div>
    </template>

    export default {
      data() {
        return {
            class_prop: new CustomClass(),
        };
      },
    }

自定义类

    class CustomClass {
        constructor(){
            this.prop = 'default_value';
        }

        method(){
            this.prop = 'new_value';
            console.log(this.prop);
        }
    }

错误

单击页面元素时出现此错误:

[Vue warn]: Error in v-on handler: "TypeError: Cannot read property 'prop' of null"

但是当我尝试从浏览器控制台调用自定义 class 方法时(我使用 Chrome 和 Vue Devtools 扩展)我没有收到任何错误,它工作正常:

$vm0.class_prop.method()

因为我的代码有两种不同的行为,所以我无法判断是我的 class 错误、vue 单文件组件还是其他原因。

你看到的不是 Vue 的错,它只是普通的 JavaScript。

引用自great JS learning resource

The consequences of unbound this

If you come from another programming language, then you are probably used to the idea of a "bound this", where methods defined in an object always have this referencing that object. In JavaScript this is “free”, its value is evaluated at call-time and does not depend on where the method was declared, but rather on what object is “before the dot”.

这是上述段落的后果的非常简单的示例(以及为什么您的代码不起作用):

class CustomClass {
  constructor() {
    this.prop = 'default_value';
  }

  method() {
    this.prop = 'new_value';
    console.log(this.prop);
  }
}

let instance = new CustomClass()

instance.method() // this works OK

let f = instance.method

f() // this does not! f is "unbound" ....have no "this"

在幕后,Vue 以某种方式 使用 null 调用或应用了您的方法。因此你提到的错误:

Error in v-on handler: "TypeError: Cannot read property 'prop' of null"


如何解决该问题?

您可以使用 lambda 表达式,这样您就可以完全控制 method 的对象所有者,如下所示:

<div @click="() => class_prop.method()"></div>

您也可以在这样的方法中使用 class 实例:

export default {
  data: () => ({
    foo: new CustomClass(),
  }),
  methods: {
    bar() {
      this.foo.method();
    },
  },
}

然后在您的模板中:

<div @click="bar">{{ foo.prop }}</div>