使用Vue.js能否触发事件?

71

我刚开始使用 Vue.js,但在某些情况下仍需要使用jQuery。最近,我尝试模拟触发事件(例如点击或失焦事件),但没有成功。

我知道在jQuery中可以这样做:

$('#my-selector').trigger('click');

但是如何使用Vue.js来实现这一点呢?我想尽可能地减少使用jQuery。

以以下内容为例:

<div id="my-scope">
    <button type="button" v-on="click: myClickEvent">Click Me!</button>
</div>

<script>
new Vue({
    el: "#my-scope",
    data: {
        foo: "Hello World"
    },
    methods: {
        myClickEvent: function(e) {
            console.log(e.targetVM);
            alert(this.foo);
        },
        anotherRandomFunciton: function() {
            this.myClickEvent();
        }
    }
});
</script>
如果我调用 anotherRandomFunciton 函数,我希望它能够模拟(或触发)上面的点击事件。然而,当我尝试这样做时,事件(或上面示例中的 e)永远不会传递到该函数。
Vue.js 是否有一种实现这个功能的方法?

1
你是否可以使用纯JavaScript? - Luminous
我猜是这样,但如果是这种情况,我可能会直接使用jQuery。我只是认为可能有更好的方法可以使用Vue.js来完成这个任务。 - Nick Law
1
你有查看实例方法吗?你可以在那里调用事件并以更类似于jQuery的方式监听事件。http://vuejs.org/api/instance-methods.html - Luminous
你正在尝试模拟点击事件,所以那个链接可能也不会有帮助。 - Luminous
3个回答

88

你需要使用v-el来获取你的按钮的引用,方法如下:

<button type="button" @click="myClickEvent" v-el:my-btn>Click Me!</button>

然后,在你的方法中:

function anotherRandomFunction() {
    var elem = this.$els.myBtn
    elem.click()
}

这只是一个本地 DOM 点击事件。请查看 v-el 文档

或者使用 Vue 2.x 版本:

<template>
    <button type="button" @click="myClickEvent" ref="myBtn">
        Click Me!
    </button>
</template>

<script>
export default {
    methods: {
        myClickEvent($event) {
            const elem = this.$refs.myBtn
            elem.click()
        }
    }
}
</script>

由于Vue仅使用并监听本机DOM事件。您可以使用Element#dispatchEvent来触发本机DOM事件,如下所示:

var elem = this.$els.myBtn; // Element to fire on

var prevented = elem.dispatchEvent(new Event("change")); // Fire event

if (prevented) {} // A handler used event.preventDefault();

这并不是最理想或最佳的做法。理想情况下,您应该有一个处理内部逻辑的函数和一个调用该函数的事件处理程序。这样,您可以在需要时随时调用内部逻辑。


9
在Vue2中它已被替换:https://vuejs.org/v2/guide/migration.html#v-el-and-v-ref-replaced。现在应该使用[#ref](https://vuejs.org/v2/api/#ref)。 - oliverpool

42
如果有人偶然发现这个问题,这是我解决方法:
当使用 this.$refs.myBtn.click() 时,会得到“Uncaught TypeError: this.$refs.myBtn.click不是一个函数”的错误。
将其更改为:this.$refs.myBtn.$el.click() 需要说明的是:“$el” 必须添加才能正常工作。

1
我认为这可能取决于您的代码和/或Vue版本。this.$refs.filterGroupLegend.click()与2.5.16版本一起对我有效。 - the_dude_abides
4
这取决于您是处理组件的单击还是本机DOM元素的单击。对于本机元素,请使用$el。顺便说一句,好棒的用户名! - James
3
谢谢@james.brndwgn! - the_dude_abides
我试图触发组件的 @remove 事件,但是 this.$refs.pictureInput.remove() 显示错误,说它不是一个函数,正如你所说的那样。因此,当使用 this.$refs.pictureInput.$el.remove() 时,它调用了本地的 remove() 并从视图中删除了该元素。有什么建议可以避免这种情况吗? - Rakibul Haq
好的,我试图调用一个方法,但是方法名写错了,是我的问题!在把方法名改正后,它就可以工作了。 - Rakibul Haq
对我来说,没有 $el 部分也可以工作,但可能有些变化。 - jean d'arme

-8
Vue的本质是专注于特定领域-它旨在与其他包(例如jQuery)一起使用,以实现除DOM操作之外的jQuery功能。如果要使用jQuery的trigger方法,我认为这是可以的。
然而,如果你想在不使用jQuery的情况下创建自己的事件,请查看dispatchEvent方法。

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent

或者,针对click的特定情况,您可以使用DOM元素上的一种方法:

https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click


11
我不认为这个说法是正确的...
它的意图是希望其他像jQuery这样的包与它一起使用。
- Grant
从你只想让Vue修改DOM的角度来看,你是正确的。但总的来说,Vue的焦点相当狭窄,很容易集成其他包,比如Sortable.js,这样你就可以得到类似Vue.Draggable的东西。 - David K. Hess
6
这个回答是完全错误的。Vue旨在取代jQuery。在Vue中使用jQuery最多只能算作一种hack,而且绝对是不好的做法。 - Hybrid web dev
4
Vue并不是用来替代jQuery的,Vue是用来替代直接操作DOM的。jQuery可以用于更多的操作,而不仅仅是DOM操作。 - David K. Hess
2
绝对不可以 - 在任何现代SPA JS框架中使用jQuery都是你没有正确使用该框架的明显迹象。 - Keith Jackson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接