Vue - 从不同组件调用方法(使用 vue-routes)

Dra*_*Dev 1 javascript vue.js vuejs2

这是我的基地App.vue,里面有router-view

<template>
<div>
    <Navbar/>

    <div class="container-fluid">
        <router-view></router-view>
    </div>
</div>
</template>

<script>
import Navbar from './components/Navbar.vue';

export default {
    name: 'App',
    components: {
        Navbar
    }
}
</script>
Run Code Online (Sandbox Code Playgroud)

在 中Navbar.vue,我有一个方法:

methods: {
    getLoggedStatus(){
        console.log('asdasd')
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,我有一个Login.vue加载到router-view. 我想getLoggedStatus()Navbar.vue内部进入Login.vue。我怎样才能实现这个目标?

Navbar我尝试在以下位置添加对标签的引用App.vue

<Navbar ref="navvy"/>
Run Code Online (Sandbox Code Playgroud)

并调用Login.vue

this.$refs.navvy.getLoggedStatus()
Run Code Online (Sandbox Code Playgroud)

但这不起作用。

Ser*_*eon 5

裁判只对儿童有效。您正在<Navbar>应用程序内进行渲染,因此您无法从登录中调用该引用。您只能this.$refs.navvy从访问App.vue

\n

您的问题有多种解决方案。

\n
    \n
  1. 从 Login 向 App 发出事件,因此 App 从 ref 调用该方法。

    \n
  2. \n
\n

您可以在路由器视图中设置监听器,如下所示:

\n
<router-view  @loggedStatus="callLoggedStatus"  />\n
Run Code Online (Sandbox Code Playgroud)\n

在您的登录中,当您想要调用导航栏时getLoggedStatus,您可以发出该事件:

\n
this.$emit(\'loggedStatus\')\n
Run Code Online (Sandbox Code Playgroud)\n

然后在 App.vue 中,您将定义一个callLoggedStatus调用 ref 的方法:

\n
callLoggedStatus() {\n  this.$refs.navvy.getLoggedStatus();\n}\n
Run Code Online (Sandbox Code Playgroud)\n

假设您将 ref 添加到<Navbar>APP 模板中的组件中。

\n

这个解决方案可以说是与您提出的代码最相似的,但我认为它很混乱,您应该避免它,因为您最终可能会在 App.vue 中监听许多不同的事件。

\n
    \n
  1. 使用Vuex

    \n
  2. \n
\n

我不知道具体是什么getLoggedStatus什么,但如果你想改变用户登录时导航栏的行为,你可能应该设置一个 vuex 商店,这样无论用户是否登录,你都在那里注册。然后,在导航栏组件中,您可以根据用户是否登录有条件地呈现内容。

\n

@Lana 的答案遵循了这个想法,并且可能是最接近 Vue 中 Thins 的官方方法。

\n
    \n
  1. \xc2\xa0使用事件发射器

    \n
  2. \n
\n

如果您想在不属于同一系列的组件之间直接通信,我认为事件发射器是一个合理的选择。您可以在创建应用程序后设置应用程序范围的事件发射器:

\n
const app = new Vue({...});\nwindow.emitter = new Vue();\n
Run Code Online (Sandbox Code Playgroud)\n

(在示例中,我们使用新的 Vue 作为事件发射器。还有“events”模块允许使用 EventEmitter)

\n

然后任何组件都可以使用它来发送消息,因此 Login 可以这样做:

\n
window.emitter.$emit(\'user-logged\', myCustomPayload);\n
Run Code Online (Sandbox Code Playgroud)\n

另一方面,导航栏可以做到:

\n
window.emitter.$on(\'user-logged\', function() {\n  this.getLoggedStatus();\n})\n
Run Code Online (Sandbox Code Playgroud)\n

最后一个选项在 Vue 社区中没有得到充分考虑 - Vuex 是首选 - 但对于小型应用程序,我认为它是最简单的。

\n
    \n
  1. 肮脏的黑客

    \n
  2. \n
\n

您始终可以将组件导出到窗口。在导航栏created挂钩中,您可以执行以下操作:

\n
created() {\n  window.Navbar = this;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

然后在 Login.vue 中您可以随时:

\n
window.Navbar.getLoggedStatus()\n
Run Code Online (Sandbox Code Playgroud)\n

它会起作用的。然而,这肯定是一种反模式,如果您开始使用多个组件执行此操作,可能会对项目的可维护性造成很大损害。

\n