首页 > 解决方案 > Vue 的 'v-on' 指令和 vue.$on 有什么区别?

问题描述

假设我有两个兄弟组件,如下所示:

<div id="root2">
    <some-component>First</some-component>
    <some-component>Second</some-component>
</div>

...这些组件的定义如下:

Vue.component('some-component', {
    template: '<button @click="doSomething" @somethingwasdone="this.reactToSomething" :disabled="this.isDisabled"><slot /></button>',
    methods: {
        doSomething() {
            Event.$emit('somethingWasDone');
        },

        reactToSomething() {
            this.isDisabled = true;
        }
    },
    data() {
        return {
            isDisabled: false,
        }
    },
    created() {
        Event.$on('somethingWasDone', () => this.reactToSomething());
    }
});

假设我的目标是在按下其中任何一个按钮时禁用这两个按钮。我特意包含了两个事件监听器,一个是“v-on”指令的形式,一个是在 Vue 实例上定义的 $on 方法的形式。我无法让前者工作,我不确定为什么。

我的猜测是它必须与发出事件的范围有关。但是,即使我单击的组件在使用 v-on 指令时也不会监听它发出的事件。任何帮助是极大的赞赏!

问候,

瑞安


更新:我在我的代码中发现了一个错误,其中 v-for 指令 (@) 正在侦听的事件是“componentclicked”而不是“somethingwasdone”。修复错误时,我注意到这两种方法实际上都有效。

标签: javascriptvue.jsvuejs2

解决方案


每个 Vue 实例(包括根实例)都有 $on 和 $emit 方法,它们允许发送和接收事件。在处理事件时,您必须牢记发出事件的范围。

在您的示例中,您似乎正在尝试在同一组件中发出和捕获事件。为此,您将需要使用组件实例 $emit 和 $on 方法。通过这种方式,事件在组件中发出并保持在此范围内。本例中使用的语法是 this.$emit() 和 this.$on(),this定义了组件实例。

Vue.component('some-component', {
    template: '<button @click="doSomething" @somethingWasDone="this.reactToSomething" :disabled="this.isDisabled"><slot /></button>',
    methods: {
        doSomething() {
            this.$emit('somethingWasDone');
        },

        reactToSomething() {
            this.isDisabled = true;
        }
    },
    data() {
        return {
            isDisabled: false,
        }
    },
    created() {
        this.$on('somethingWasDone', () => this.reactToSomething());
    }
});

v-on 是模板中用于从父组件侦听相同事件的语法。

<div id="root2">
     <some-component v-on:somethingWasDone="doSomething">First</some-component>
    <some-component v-on:somethingWasDone="doSomething">Second</some-component>
</div>

如果您使用的是根实例 Vue.$on 和 Vue.$emit,那么您将在全局级别发出/监听事件。


推荐阅读