问题描述
我有一个 vue 单文件组件,它有一个自定义类实例作为属性:现在我想将一个事件绑定到这个类实例的一个方法,但我遇到了问题,我的代码文件有一个简化版本
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"
但是当我尝试从浏览器控制台调用自定义类方法时(我使用 Chrome 和 Vue Devtools 扩展)我没有收到错误,它可以正常工作:
$vm0.class_prop.method()
因为我的代码有两种不同的行为,所以我无法判断是我的类错了,vue 单文件组件错了,还是其他什么。
解决方法
你看到的不是 Vue 的错,它只是普通的 JavaScript。
这是来自great JS learning resource
的引文未绑定this
的后果
如果您来自另一种编程语言,那么您可能已经习惯了“绑定 this”的概念,其中定义在对象中的方法总是 this
引用该对象。
在 JavaScript 中,this
是“免费的”,它的值在调用时计算,不取决于方法的声明位置,而是取决于“点之前”的对象。
以下是上述段落后果的非常简单示例(以及为什么您的代码不起作用):
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
调用或应用您的方法。因此你提到的错误:
v-on 处理程序中的错误:“TypeError:无法读取 null 的属性 'prop'”
你能做些什么来解决这个问题?
您可以使用 lambda 表达式,因此您可以完全控制 method
的对象所有者,如下所示:
<div @click="() => class_prop.method()"></div>
你也可以在这样的方法中使用类实例:
export default {
data: () => ({
foo: new CustomClass(),}),methods: {
bar() {
this.foo.method();
},},}
然后在您的模板中:
<div @click="bar">{{ foo.prop }}</div>