Vue js广播不起作用

时间:2016-08-07 18:53:47

标签: javascript vue.js

我有这个Vue实例:

var vm = new Vue({
    el: '#app',
    data: {
        user: {
            email: '',
            password: '',
            passwordconfirm: '',
            bars: {},
            authentication_token: '',
            id: 0
        }
    },
    components: {
        dashboard: dashboard
    },
    events: {
        'onLoginSuccesfull': function(user) {
            // do stuff with user obj
            this.$broadcast('onUserLoggedIn');
        }
    }
}

它有一个“仪表板”组件:

var dashboard = Vue.extend({
    template: '#dashboard',
    data: function() {
        return {
            currentPage: 'main'
        }
    },
    components: {
        'dashboard-mainpage': dashboardmainpage
    }
    events: {
        'onUserLoggedIn': function() {
            alert('I should be firing bu I am not!');
        }
    }
});
Vue.component('dashboard', dashboard);

“信息中心”有一个“信息中心主页”组件:

var dashboardmainpage = Vue.extend({
    template: '#dashboard-mainpage',
    methods: {
        loadData: function() {
            this.$http.get('/dashboard/main.json', {
                authenticity_token: window._token
            }).then(function(response) {
                var data = JSON.parse(response.body);
                console.log(data);
            }, function(response) {
                console.log(response);
                this.$dispatch("onRequestUnauthorized");
            });
        }
    },
    events: {
        'onUserLoggedIn': function() {
            alert('I should be firing as well but I am not!');
            this.loadData();
        }
    }
});

问题是当在主Vue实例上触发'onLoginSuccesfull'事件时,在调用'this。$ broadcast('onUserLoggedIn')时,不会触发第1级和第2级后代上随后广播的'onUserLoggedIn'。 ;”

我知道事件回调必须返回true才能继续向下传播,但第一个事件回调(在“仪表板”上)甚至没有被触发。

我错过了什么?

谢谢!

=====编辑=====

主要应用:

<div id="app">
<dashboard v-if="currentStep == 'dashboard'" v-bind:appname="appName" v-bind:dashboard-vm="dashboard" v-bind:user="user" v-bind:bar.sync="bar"></dashboard>
</div>

仪表板模板:

<template id="dashboard">
    <div class="container body">
      <div class="main_container">
        <div class="col-md-3 left_col">
          <div class="left_col scroll-view">
            <div class="navbar nav_title" style="border: 0;">
              <a href="index.html" class="site_title"><span>The Bar</span></a>
            </div>

            <div class="clearfix"></div>

            <br />

            <!-- sidebar menu -->
            <div id="sidebar-menu" class="main_menu_side hidden-print main_menu">
            {{ user.email }} 
              <div class="menu_section">
                <ul class="nav side-menu">
                <li><a v-on:click="createNewBar"><i class="fa fa-plus"></i> Create new bar</a>
                  </li>
                  <li><a v-on:click="showDashboard"><i class="fa fa-bar-chart"></i> Dashboard</a>
                  </li>
                  <li><a v-on:click="showBars"><i class="fa fa-bars"></i> Bars</a>
                  </li>
                  <li><a><i class="fa fa-tachometer"></i> Settings <span class="fa fa-chevron-down"></span></a>
                  <ul class="nav child_menu">
                      <li><a v-on:click="showProfile">Profile</a></li>
                      <li><a v-on:click="showPaymentsPlans">Plan & payments</a></li>
                    </ul>
                  </li>
                  </ul>
              </div>

            </div>
            <!-- /sidebar menu -->
          </div>
        </div>

        <!-- top navigation -->
        <div class="top_nav">
          <div class="nav_menu">
            <nav>
              <div class="nav toggle">
                <a id="menu_toggle"><i class="fa fa-bars"></i></a>
              </div>              

              <ul class="nav navbar-nav navbar-right">
                <li class="">
                <a v-on:click="$parent.logoutUser" style="cursor: pointer">Log out</a>
                </li>
              </ul>
            </nav>
          </div>
        </div>
        <!-- /top navigation -->

        <!-- page content -->
        <div class="right_col" role="main">
          <dashboard-mainpage v-if='currentPage == "main"' v-bind:vm="dashboardVm"></dashboard-mainpage>

          </div>
        </div>
        <!-- /page content -->

        <!-- footer content -->
        <footer>
          <div class="pull-right">
            &copy; <%= Time.now.year %> The Bar
          </div>
          <div class="clearfix"></div>
        </footer>
        <!-- /footer content -->
      </div>
    </div>
</template>

控制板-炫魅:

<template id="dashboard-mainpage">
<div class="col-md-12 x_title">
                  <div>
                    <div class="btn-group pull-right">
  <button type="button" class="btn btn-info"><span class="fa fa-calendar" aria-hidden="true"></span> Today</button>
  <button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
    <span class="caret"></span>
    <span class="sr-only">Toggle Dropdown</span>
  </button>
  <ul class="dropdown-menu">
    <li>
      <a href="#">Today</a>
    </li>
    <li>
      <a href="#">Yesterday</a>
    </li>
    <li>
      <a href="#">Last 7 days</a>
    </li>
    <li>
      <a href="#">Last 30 days</a>
    </li>
    <li>
      <a href="#">Last year</a>
    </li>
    <li>
      <a href="#">All</a>
    </li>
  </ul>
</div>
                  <span class="pull-right">Filter:</span>
</div>
                  </div>
<!-- top tiles -->
            <div class="row top_tiles">
              <div class="animated flipInY col-lg-4 col-md-4 col-sm-6 col-xs-12">
                <div class="tile-stats">
                  <div class="icon"><i class="fa fa-bars"></i></div>
                  <div class="count">{{ vm.totalBars }}</div>
                  <h3>Total bars</h3>
                  <p>All you active bars</p>
                </div>
              </div>
              <div class="animated flipInY col-lg-4 col-md-4 col-sm-6 col-xs-12">
                <div class="tile-stats">
                  <div class="icon"><i class="fa fa-eye"></i></div>
                  <div class="count">{{ vm.totalViews }}</div>
                  <h3>Total views</h3>
                  <p>Total number of bar views</p>
                </div>
              </div>
              <div class="animated flipInY col-lg-4 col-md-4 col-sm-6 col-xs-12">
                <div class="tile-stats">
                  <div class="icon"><i class="fa fa-mouse-pointer"></i></div>
                  <div class="count">{{ vm.totalClicks }}</div>
                  <h3>Total clicks</h3>
                  <p>Total number of clicks</p>
                </div>
              </div>
            </div>
          <!-- /top tiles -->

          <div class="row">
            <div class="col-md-12 col-sm-12 col-xs-12">
              <div class="dashboard_graph">

                <div class="row x_title">
                  <div class="col-md-6">
                    <h3>Statistics</h3>
                  </div>
                  <div class="col-md-6">
                    <div id="reportrange" class="pull-right" style="background: #fff; cursor: pointer; padding: 5px 10px; border: 1px solid #ccc">
                      <i class="glyphicon glyphicon-calendar fa fa-calendar"></i>
                      <span>December 30, 2014 - January 28, 2015</span> <b class="caret"></b>
                    </div>
                  </div>
                </div>

                <div class="col-md-12 col-sm-12 col-xs-12">
                <div class="x_title">
                    <h2>Sub title</h2>
                    <div class="clearfix"></div>
                  </div>
                  <p>stats here</p>
                </div>

                <div class="clearfix"></div>
              </div>
            </div>

          </div>
          <br />
</template>

2 个答案:

答案 0 :(得分:2)

确定。对于任何想要徘徊在这个“问题”上的人。这是修复。

我在正在收听'onUserLoggedIn'事件的孩子身上使用'v-if'属性。 'v-if'的文档说:

  

有条件地渲染元素基于的真实性   表达价值。元素及其包含的数据绑定/   在切换期间,组件被销毁并重新构建。如果   element是一个元素,其内容将被提取为   条件块。

因此,当某个子组件的'v-if =“false”'时,它实际上不存在,因此无法做任何事情或对任何事情作出回应,包括事件。

当使用'v-show'代替'v-if'来有条件地切换某些组件时,该组件保持“活着”并且能够响应。

答案 1 :(得分:0)

有些事情正在发生:

  • 如果您在另一个组件中定义组件(正如您在app组件中所做的那样,则无需全局定义此组件(https://vuejs.org/guide/components.html#Registration-Sugar)。
  • 如果组件未在另一个组件的模板中“调用”,则永远不会在它们之间建立父子关系。我看不到App组件的模板,所以我假设没有。
  • 缺少一些代码,但我认为onLoginSuccesfull永远不会在App组件上实际调用!
  • 正如您所说,如果您希望事件在第一次触发后传播,则此触发函数必须返回true

这是一个有基础知识的工作jsfiddle:https://jsfiddle.net/e85ekxk1/2/

祝你好运!