Vue.js <MyButton @ click =“ click(event)”> Click </MyButton>不起作用,但是$ event有效,为什么?

时间:2020-04-06 12:37:49

标签: javascript vue.js vuejs2

请参见以下最小示例:

我有一个名为MyButton的最小自定义按钮,

<template>
<button @click="click">
  <slot />
</button>
</template>

<script>
export default {
  methods: {
    click(event) {
      this.$emit('click', event)
    }
  }
};
</script>

现在,我像这样使用<MyButton />

<template>
  <div>
    <MyButton @click="click(event)">Click</MyButton>
  </div>
</template>

<script>
import MyButton from "./components/MyButton";

export default {
  components: {
    MyButton
  },
  methods: {
    click(event) {
      alert(
        JSON.stringify(event.currentTarget.getBoundingClientRect(), null, 2)
      );
    }
  }
};
</script>

此代码因以下控制台错误而中断

[Vue warn]: Property or method "event" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
[Vue warn]: Error in v-on handler: "TypeError: Cannot read property 'currentTarget' of undefined"
TypeError: Cannot read property 'currentTarget' of undefined

但是,如果我将@click="click(event)"更改为@click="click($event)",现在我的代码可以正常工作了!

为什么会这样?

doc

有时,我们还需要在内联语句处理程序中访问原始DOM事件。您可以使用特殊的$ event变量将其传递给方法:

但是,正如您所看到的,<MyButton />已经发出了event作为有效载荷,为什么我仍然使用$event版本,这对我来说很混乱。

我的代码和框链接

https://codesandbox.io/s/zen-platform-521d8

2 个答案:

答案 0 :(得分:1)

@click="click"实际上是@click="click($event)"的快捷方式,而$event是包含事件有效负载的变量的名称。

对于任何Vue.js事件都是如此,例如@custom-event="myMethod"@custom-event="myMethod($event)"相同,其中$ event是发射器传递的有效负载:this.$emit('custom-event', payload);

在大多数情况下,@click="click"足以满足您的需求,但是在某些情况下,您可能需要传递多个参数,因此您可以在其中使用$event

示例:

@click="click($event, true, 10)"可以使用这种功能来处理:

click(event, param1, param2) {
    // event is the payload
    // param1 is equal to true
    // param2 is equal to 10
}

您还可以决定忽略有效负载,因为您不需要它,并在不使用任何参数的情况下调用函数:@click="click()"

答案 1 :(得分:0)

window.event已过时。因为在Vue.js中您仍然需要某种方式,所以Vue开发团队通过引入$event来解决了它。参见Methods in Inline Handlers

另请参见MDN window.event

应该避免在新代码中使用此属性,而应使用传递到事件处理程序函数中的Event。此属性不受普遍支持,即使受支持也会给您的代码带来潜在的脆弱性。

要了解为什么window.event不能在Vue事件处理程序中访问,即使您的浏览器仍支持window.event,您也必须了解JavaScript事件循环和Vue.js如何在其中工作。 {{1}}仅可在由事件本身引起的事件循环的一次迭代中访问。但是Vue.js不会在该迭代中传递事件。相反,它将以0ms超时并导致其自身的迭代。解释其中的原因太复杂了,以至于没有引起人们的兴趣。