首页 > 解决方案 > 如何在 Vue Router 中的命名视图之间传递数据和事件?

问题描述

我有这样的布局:

.------------------------+----------------.
|  Current Tab Title     |      Controls  |
+------------------------+----------------+
|  Tab1 Tab2 [Tab3]                       |
+-----------------------------------------+
|  Main Content                           |
|                                         |
'-----------------------------------------'

“控件”字段内容在逻辑上应该属于当前选项卡。但是我不能把它放在同一个 Vue 组件中,因为它应该在应用程序模板的不同位置呈现。此外,选项卡标题应取决于当前选择的选项卡。

我做Tab1了一个<router-link>组件。因为 Current Tab Title我滥用了这个$route.name领域。我可以使用命名视图来显示Controls.

但是我无法理解如何在Controls块中设置一些控件,这些控件将取决于并影响当前选项卡中的状态。

例如, Tab1我们想要显示一个复选框,它会影响选项卡的某些行为。所以它的状态应该存储在Tab1组件中,而不是Tab1Controls组件中。但是我怎样才能连接它们,即将实例的当前值传递到实例,并将事件从checkbox实例Tab1 传递回实例?Tab1ControlsTab1ControlsTab1

这显然可以解决,Vuex但我想避免它。

一般建议是将状态向上移动,但我认为路由器不可能。无论如何,它会让事情变得一团糟,因为checkbox数据应该属于Tab1or  Tab1Controls,并且与其他选项卡无关。

标签: javascriptvue.jsvue-router

解决方案


这是我想到的一种方法。它远非理想,但至少它有效并且允许我保持它应该属于的状态。

首先,我创建了一个BaseTemplate包含应用程序大部分标记的组件。即App组件仅保留最低限度,并且大部分主体(包括不可变部分)被移动到BaseTemplate

// BaseTemplate.vue
<template>
<div>
  <header>
    <slot name="title">{{ title }}</slot>
    <slot name="controls"/>
  </header>
  <nav>
    <router-link ...>
    <router-link ...>
  </nav>
  <main>
    <slot/>
  </main>
</div>
</template>

<script>
export default {
  props: ['title'],
};
</script>
// Tab1.vue
<template>
  <BaseTemplate title="First Tab">
    <template #controls>
      ...
    </template>

    main content goes here...
  </BaseTemplate>
</template>
...

这样,所有与 Tab1 相关的 props 都属于 Tab1 组件,同时公共标记被移动到单独的组件中。

现在来看看缺点。与通用控件/导航位于路由视图之外的“正常”设置不同,在此设置中,它们实际上是每个选项卡的不同组件实例。所以他们在切换时会闪烁。不确定它是否可以以某种方式缓解。


推荐阅读