Javascript Vue-从其他组件调用方法(使用Vue路由)

Javascript Vue-从其他组件调用方法(使用Vue路由),javascript,vue.js,vuejs2,Javascript,Vue.js,Vuejs2,这是我的基本App.vue,其中包含路由器视图: <template> <div> <Navbar/> <div class="container-fluid"> <router-view></router-view> </div> </div> </template> <script> import Navbar from './c

这是我的基本
App.vue
,其中包含
路由器视图

<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>
最后,我有一个
Login.vue
,它被加载到
路由器视图中。我想从
Login.vue
中的
Navbar.vue
访问
getLoggedStatus()
。我怎样才能做到这一点

我尝试在
App.vue
中对
Navbar
标记进行引用:

<Navbar ref="navvy"/>

但它不起作用。

它看起来像是
getLoggedStatus
返回应用程序的一些全局状态。用于管理这些全局变量

创建一个如下所示的商店:

// Make sure to call Vue.use(Vuex) first if using a module system
const store = new Vuex.Store({
  state: {
    loggedStatus: 0
  },
  getters: {
    getLoggedStatus: state => {
      // to compute derived state based on store state
      return state.loggedStatus 
    }
  }
})

在任何Vue组件中使用
store.state.loggedStatus
访问全局状态,或者如果需要基于存储状态计算派生状态,则使用类似于
store.getters.getLoggedStatus的getter

引用仅适用于子级。您正在应用程序中呈现
,因此无法从登录名调用该ref。您只能从
App.vue
访问
this.$refs.navvy

您的问题有几种解决方案

  • 从登录到应用程序发出事件,因此应用程序从引用调用该方法。
  • 您可以在路由器视图中设置侦听器,如下所示:

    <router-view  @loggedStatus="callLoggedStatus"  />
    
    然后在App.vue中,您将定义一个调用ref的
    callLoggedStatus
    方法:

    callLoggedStatus() {
      this.$refs.navvy.getLoggedStatus();
    }
    
    假设您将ref添加到应用程序模板中的
    组件中

    这个解决方案可以说是最类似于您建议的代码,但我认为这是一个混乱,您应该避免它,因为您可能会在App.vue中收听许多不同的事件

  • 使用Vuex
  • 我不知道
    getLoggedStatus
    的确切功能,但是如果您想更改用户登录时导航栏的行为,您可能应该设置vuex存储,以便无论用户是否登录,都可以在那里注册。然后,在navbar组件中,根据用户是否登录,有条件地呈现内容

    @拉娜的回答遵循了这个想法,并且可能是最接近Vue中thins的官方方式

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

    const app = new Vue({...});
    window.emitter = new Vue();
    
    (在本例中,我们使用一个新的Vue作为事件发射器。还有允许使用EventEmitter的“events”模块)

    然后任何组件都可以使用它发送消息,因此登录可以执行以下操作:

    window.emitter.$emit('user-logged', myCustomPayload);
    
    window.emitter.$on('user-logged', function() {
      this.getLoggedStatus();
    })
    
    created() {
      window.Navbar = this;
    }
    
    另一方面,导航栏可以:

    window.emitter.$emit('user-logged', myCustomPayload);
    
    window.emitter.$on('user-logged', function() {
      this.getLoggedStatus();
    })
    
    created() {
      window.Navbar = this;
    }
    
    最后一个选项在Vue社区中没有得到很好的考虑-Vuex是首选-但对于小型应用程序,我认为它是最简单的

  • 肮脏的黑客
  • 您始终可以将组件导出到窗口。在导航栏
    created
    hook中,您可以执行以下操作:

    window.emitter.$emit('user-logged', myCustomPayload);
    
    window.emitter.$on('user-logged', function() {
      this.getLoggedStatus();
    })
    
    created() {
      window.Navbar = this;
    }
    
    然后在Login.vue中,您可以随时:

    window.Navbar.getLoggedStatus()
    

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

    因为
    参考文件
    在App.vue上下文中可用,即
    ,而不是在Login.vue中。“我怎么不认为把loggedStatus弄成这样是个好策略。@hamzox有什么建议吗?:/非常感谢!我试试这个。