如何在未嵌套的组件之间传递数据?
How to pass data between unnested components?
我有一个由 vue 组件组成的 vue
应用程序。基本页面是 App.vue
并且是这样的:
<template>
<div id="app">
<site-header></site-header> <!-- This is a vue component -->
<div>
<router-link :to="{ path: '/new'}">New Post</router-link>
<router-view></router-view> <!-- newpost.vue will be loaded here -->
</div>
<site-footer></site-footer> <!-- This is a vue component -->
</div>
</template>
当用户单击 New Post
link 时,会加载一个视图,其中包含一个允许用户创建新 post 的单个文件 component
。这个component
叫做newpost.vue
.
site-header
组件有一个 div
区域,需要在应用程序中显示可能来自任何其他 component
... 的错误,因为 site-header
是出现在所有页面上:
siteheader.vue
<template>
<header>
<div id="global-error">
<p> {{globalErrorMessage}} </p> <!-- Need to display error messages here -->
</div>
</header>
</template>
所以我的问题是:
- 为了让
{{globalErrorMessage}}
工作,我是否需要在 siteheader.vue 中为此数据创建一个 prop
?
- 如果我需要创建一个
prop
,我如何将数据从任何 <router-view>
加载的组件传递到 siteheader.vue 道具?
- 以上似乎不可能,因为 newpost.vue 永远不会与 siteheader.vue[=55= 建立 parent/child 关系].它们是同一级别的兄弟,那么一个组件如何监听另一个组件的 emit 事件?
- 鉴于此,我是否在 siteheader.vue 中创建
data(){ return {globalErrorMessage: "" } }
,然后使用可以更改此数据的 computed
方法?如果是,newpost.vue如何访问siteheader.vue中的方法来更改错误消息的数据字段?
- 最后,以上都是废话吗?
Vuex
状态管理是正确的选择吗?这似乎也不对,因为每个错误对于该访问者来说都是独一无二的。不必为错误维护状态。
我不知道如何解决这个问题,因此出现了上述问题。
虽然 Vuex
是优雅的选项,尤其是当应用程序变得更复杂时,您可以使用 event-bus
将消息从第一个组件发送到第二个组件:
事件-bus.js:
import Vue from 'vue';
export const EventBus = new Vue();
newpost.vue:
import { EventBus } from './event-bus.js';
...
EventBus.$emit('set-global-error-message', 'Something went wrong');
siteheader.vue:
import { EventBus } from './event-bus.js';
...
created() {
EventBus.$on("set-global-error-message", this.setGlobalErrorMessage);
},
methods: {
setGlobalErrorMessage(errorMessage) {
this.globalErrorMessage = errorMessage;
},
},
- 是的,如果您希望您的组件不依赖于全局状态并且只显示提供它的消息。如果你觉得它是一个像 vuex 一样访问全局状态的组件,那么就不需要 prop 了。你甚至可以为这个组件在 vuex 中注册自定义模块。
- 无法直接将数据从子级向上传递给父级,您需要更新子级更新数据和父级显示数据的中央状态,或者您需要从子级发出事件,父级监听和更新它的兄弟或通过自定义事件总线。
- 您可以通过他们的父级执行此操作,App.vue 将需要管理该数据流。
- 在组件外部更改组件的本地状态并不好,即使您可以随意修改。您应该将数据作为道具传递。
- Vuex 仅存在于内存中,例如它是每个浏览器选项卡,除非您选择 localStorage 作为持久存储,即使那样也是每个访问者。意思是,人们不会共享彼此浏览器的 vuex 状态。
这些就在我脑海中。
我有一个由 vue 组件组成的 vue
应用程序。基本页面是 App.vue
并且是这样的:
<template>
<div id="app">
<site-header></site-header> <!-- This is a vue component -->
<div>
<router-link :to="{ path: '/new'}">New Post</router-link>
<router-view></router-view> <!-- newpost.vue will be loaded here -->
</div>
<site-footer></site-footer> <!-- This is a vue component -->
</div>
</template>
当用户单击 New Post
link 时,会加载一个视图,其中包含一个允许用户创建新 post 的单个文件 component
。这个component
叫做newpost.vue
.
site-header
组件有一个 div
区域,需要在应用程序中显示可能来自任何其他 component
... 的错误,因为 site-header
是出现在所有页面上:
siteheader.vue
<template>
<header>
<div id="global-error">
<p> {{globalErrorMessage}} </p> <!-- Need to display error messages here -->
</div>
</header>
</template>
所以我的问题是:
- 为了让
{{globalErrorMessage}}
工作,我是否需要在 siteheader.vue 中为此数据创建一个prop
? - 如果我需要创建一个
prop
,我如何将数据从任何<router-view>
加载的组件传递到 siteheader.vue 道具? - 以上似乎不可能,因为 newpost.vue 永远不会与 siteheader.vue[=55= 建立 parent/child 关系].它们是同一级别的兄弟,那么一个组件如何监听另一个组件的 emit 事件?
- 鉴于此,我是否在 siteheader.vue 中创建
data(){ return {globalErrorMessage: "" } }
,然后使用可以更改此数据的computed
方法?如果是,newpost.vue如何访问siteheader.vue中的方法来更改错误消息的数据字段? - 最后,以上都是废话吗?
Vuex
状态管理是正确的选择吗?这似乎也不对,因为每个错误对于该访问者来说都是独一无二的。不必为错误维护状态。
我不知道如何解决这个问题,因此出现了上述问题。
虽然 Vuex
是优雅的选项,尤其是当应用程序变得更复杂时,您可以使用 event-bus
将消息从第一个组件发送到第二个组件:
事件-bus.js:
import Vue from 'vue';
export const EventBus = new Vue();
newpost.vue:
import { EventBus } from './event-bus.js';
...
EventBus.$emit('set-global-error-message', 'Something went wrong');
siteheader.vue:
import { EventBus } from './event-bus.js';
...
created() {
EventBus.$on("set-global-error-message", this.setGlobalErrorMessage);
},
methods: {
setGlobalErrorMessage(errorMessage) {
this.globalErrorMessage = errorMessage;
},
},
- 是的,如果您希望您的组件不依赖于全局状态并且只显示提供它的消息。如果你觉得它是一个像 vuex 一样访问全局状态的组件,那么就不需要 prop 了。你甚至可以为这个组件在 vuex 中注册自定义模块。
- 无法直接将数据从子级向上传递给父级,您需要更新子级更新数据和父级显示数据的中央状态,或者您需要从子级发出事件,父级监听和更新它的兄弟或通过自定义事件总线。
- 您可以通过他们的父级执行此操作,App.vue 将需要管理该数据流。
- 在组件外部更改组件的本地状态并不好,即使您可以随意修改。您应该将数据作为道具传递。
- Vuex 仅存在于内存中,例如它是每个浏览器选项卡,除非您选择 localStorage 作为持久存储,即使那样也是每个访问者。意思是,人们不会共享彼此浏览器的 vuex 状态。
这些就在我脑海中。