【问题标题】:Vue.js <MyButton @click="click(event)">Click</MyButton> is not working, however, $event works, why?Vue.js <MyButton @click="click(event)">Click</MyButton> 不工作,但是, $event 工作,为什么?
【发布时间】:2020-04-06 12:37:49
【问题描述】:

请看这个最小的例子:

我有一个最小的自定义按钮,叫做MyButton,就像这样

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

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

现在,我像这样使用&lt;MyButton /&gt;

<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 变量将其传递给方法:

但是,如您所见,&lt;MyButton /&gt; 已经发出了event 作为有效载荷,我为什么还要使用$event 版本,这让我很困惑。

我的 Codesandbox 链接

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

【问题讨论】:

    标签: javascript vue.js vuejs2


    【解决方案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()"

    【讨论】:

      【解决方案2】:

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

      另见MDN window.event:

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

      要了解为什么 window.event 在 Vue 事件处理程序中无法访问,即使您的浏览器仍然支持它,您必须了解 JavaScript 事件循环和 Vue.js 在内部是如何工作的。 window.event 只能在由事件本身引起的事件循环的一次迭代中访问。但是 Vue.js 并没有在该迭代中传递事件。相反,它将超时 0ms 并导致它自己的迭代。解释原因太复杂了,没有兴趣。

      【讨论】:

        猜你喜欢
        • 2017-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多