简体   繁体   English

使用 eventbus 接收到事件时,Vue.js 视图不会更新

[英]Vue.js view doesn't update when an event is received using an eventbus

I'm new to Vue.js 2 and am building my first (vue) web application.我是 Vue.js 2 的新手,正在构建我的第一个 (vue) Web 应用程序。 The application uses two components, one header component and one login component.该应用程序使用两个组件,一个标题组件和一个登录组件。 When the login is succesfull a "loggedIn"-flag variable will be toggled in a singleton authentication service.当登录成功时,“loggedIn”标志变量将在单例身份验证服务中切换。 This service is responsible to emit an event to the header component (and maybe other listening components) to notify that the user is logged in. The header in turn should update it's view and display the username.该服务负责向标头组件(也可能是其他侦听组件)发出一个事件以通知用户已登录。标头又应更新其视图并显示用户名。

Everything works as described, events are generated and emitted/received using a global event bus.一切都按照描述进行,使用全局事件总线生成和发送/接收事件。 However, when the event is received by the header component it's unable to update the view.但是,当标头组件接收到事件时,它无法更新视图。

I already tried different approaches: basic subscriber pattern, vuex and now the event bus.我已经尝试过不同的方法:基本订阅者模式、vuex 和现在的事件总线。 Nothing seems to work.似乎没有任何效果。 Does anyone know what the problem might be?有谁知道问题可能是什么?

EventBus.js:事件总线.js:

import Vue from 'vue'
var eventBus = new Vue()
export default eventBus

SessionService.js会话服务.js

import eventBus from '../util/EventBus'

class SessionService {
  loggedIn=false
  constructor () {
    if (this.isValid(this.getSessionToken())) {
      this.loggedIn = true
    }
  }
  setSessionToken (token) {
    localStorage.setItem('token', token)
    if (this.isValid(token)) {
      eventBus.$emit('LOGGEDIN')
    } else {
      eventBus.$emit('LOGGEDOUT')
    }
  }
  getSessionToken () {
    return localStorage.getItem('token')
  }
  isValid (token) {
    return token !== undefined && token != null && token !== ''
  }
}
var sessionService = new SessionService()
export default sessionService

Header.vue: Script Header.vue:脚本

  import eventBus from '../../services/util/EventBus'
  var loggedIn = false
  var m = this
  eventBus.$on('LOGGEDIN', function () {
    console.log('RECEIVED')
    m.loggedIn = true
  })

  export default{
    name: 'Header',
    data () {
      return {loggedIn}
    }
  }

Header.vue: HTML Header.vue:HTML

<template>
  <div>
  <nav class="navbar navbar-expand-lg ap-top-nav">
    <div class="container" >
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarSupportedContent">

        <form class="form-inline my-2 my-lg-0 mr-auto">
          <div class="ap-searcher">
            <input class="ap-search" type="text" placeholder="Search" aria-label="Search"/>
            <i class="fa fa-search"></i>
          </div>

        </form>
        <div class="logo ml-auto mr-auto">
          <img src="../../assets/images/logo.png"/>
        </div>
        <ul class="navbar-nav ml-auto">
          <li class="nav-item ap-button blue wide">
            <router-link to="/login">Login: {{loggedIn}}</router-link>
          </li>
          <li class="nav-item ap-button light-blue wide">
            <router-link to="/registration">Register</router-link>
          </li>
          <li class="nav-item ap-button blue-border">
            <a href="#">EN <i class="fa fa-sort-desc" aria-hidden="true"></i></a>
          </li>
        </ul>
      </div>

    </div>
  </nav>
    <nav class="navbar navbar-expand-lg ag-bottom-nav">
      <div class="container">
        <div class="collapse navbar-collapse " id="navbarNav">
          <ul class="navbar-nav ml-auto">
            <li class="nav-item active">
              <router-link class="nav-link ap-link" to="/">Auctions</router-link>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">Lots</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">About</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">Organize your own auction</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">Contact </a>
            </li>
          </ul>
        </div>
      </div>

    </nav>
    <div class="ap-line">
    </div>
  </div>
</template>

In your Header.vue component, when you are registering the 'LOGGEDIN' listener, you are trying to access the Vue instance via this outside the scope of the Vue instance.在您的Header.vue组件中,当您注册'LOGGEDIN'侦听器时,您正在尝试通过 Vue 实例范围之外的this访问 Vue 实例。

Move that logic inside the created hook of the component so that the eventBus listener is still registered when the component is instantiated, but so that this is referencing the Vue instance:移动至内部的逻辑created的组件的钩子,使得eventBus听者仍然注册当组件被实例化,但使得this被引用的Vue实例:

import eventBus from '../../services/util/EventBus'

export default {
  name: 'Header',
  data() {
    return { loggedIn: false }
  },
  created() {
    let self = this;
    eventBus.$on('LOGGEDIN', function () {
      console.log('RECEIVED')
      self.loggedIn = true
    })
  }
}

You have some weird structure of Header component code, but I think it should be like this:你有一些奇怪的 Header 组件代码结构,但我认为它应该是这样的:

  export default{
    name: 'Header',
    data () {
      return { loggedIn: loggedIn }
    }
  }

Old, But the answer is '=>' ARROW_Function旧,但答案是 '=>' ARROW_Function

  eventBus.$on('LOGGEDIN', (playload)=>{
  console.log('RECEIVED')
  self.loggedIn = true
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM