将事件从组件发送到 router-view - 糟糕的代码味道

Emitting events from components to router-view - bad code smell

我正在试用 Vue Router,但我闻到了难闻的气味。需要与社区确认我做的事情是否正确。

在 Vue Router 之前,我有一个组件作为 parent 从其 child 接收事件并更新我的主要应用程序数据 属性:

<number-pad v-on:button-click="updateTotal($event)"></number-pad>

不用担心细节,但它确实有效。

当我将其移动到 Vue Router 中时,它现在看起来像这样...

const pageOne = {
    name: "page-one",
    template: `
    <div>
        <number-pad v-on:button-click="updateTotal($event)"></number-pad>
    </div>  `
};

...在我的 HTML 中包含以下内容:

<router-view></router-view>

还有很多我遗漏了,但你明白了要点。

无论如何,这会很好地呈现并更新组件的内部结构,当然,但是该指令不会再与主要数据通信 属性 除非我调整一些代码以发出数据更上一层到 <router-view> 组件:

<router-view v-on:button-click="updateTotal($event)"></router-view>

它现在可以工作了(连同其他代码调整,为了简洁起见我没有写出来)。

换句话说,当谈到组件关系时,我从 Vue Router 之前的 parent -> child 关系变成了 parent -> parent -> child 之后的关系。

我真的必须将我的所有绑定和指令复制到这个新的 <router-view> grandparent 以便与主要数据 属性 通信吗?

这对我来说很难闻,也是一种巨大的痛苦。

我可以做些什么来改善这种情况?答案是:Vuex!或者答案是:不,你笨蛋,你忽略了一些简单的事情。

谢谢。

Vuex 是答案之一,但你也可以定义一个事件总线,即:

/src/event-bus.js

import Vue from 'vue'
export const EventBus = new Vue()

将其导入正在发射的组件中:

import EventBus from '@/event-bus'

你会发出这样的事件:

EventBus.$emit('button-click', payload)

现在在接收事件的组件中导入 EventBus,并在挂载的钩子中添加监听器:

mounted() {
  EventBus.$on('button-click', payload => {
    // handle event
  })
}

这适用于整个应用程序。

您可以简单地这样做:

<template>
  <div id="app">
    ...
    <router-view @child-event="handleChildEvent" />
    ...
  </div>
</template>

您可以了解更多here