javascript - 当事件 $emit 发出时,Vue $on 不运行我的函数,即使我可以看到在 Vue 控制台中触发的事件

标签 javascript events vue.js vuejs2

我正在尝试测试我的 $on 函数是否正常工作。我可以清楚地看到 Vue 控制台正在接收事件发出,但 $on 中预定义的回调函数没有被调用。

代码如下:

<template lang="html">
  <div class="test">
    <Filters></Filters>
  <div>
    <ul class="o-list c-stores">
      <Result v-bind:total="filteredRestuarants.length" v-bind:open="isOpen" v-on:toggle="toggleRestaurantList"></Result>
      <li v-for="(restaurant, index) in filteredRestuarants" class="c-stores__location" :class="{'first': isFirst(index), 'last': isLast(index, restaurants)}">
        <Location :index="index" :store="restaurant" :link="() => setCurrentRestaurant(restaurant)"></Location>
      </li>
    </ul>
  </div>
  </div>
</template>

<script>
import eventHub from './../../event-hubs/storefinder'
import Location from './Location'
import Filters from './Filters'
import Result from './Result'

export default {
  props: ["restaurants", "isOpen", "currentSearch"],
  data() {
    return {
      attributes : [],
    }
  },
  head: {
    title: function () {
      return {
        inner: this.$t('storefinder.overview')
      }
    },
    meta: function functionName() {
      return [{
          name: 'og:title',
          content: this.$t('storefinder.overview') + ' - ' + this.$t('storefinder.name'),
          id: "og-title"
        },
        {
          name: 'description',
          content: this.$t('storefinder.description'),
          id: "meta-description"
        },
        {
          name: 'og:description',
          content: this.$t('storefinder.description'),
          id: "og-description"
        },
      ]
    }
  },
  components: {
    Location,
    Filters,
    Result
  },
  computed: {
    filteredRestuarants(rest) {
      let restaur = rest || this.restaurants;
      return this.restaurants;
    }
  },
  methods: {
    startEvents(){
      eventHub.$on('addFilterTheRestaurants', (attribute) => {console.log("test")});
      eventHub.$on('removeFilterTheRestaurants', (attribute) => {console.log("test")});
    },
    toggleRestaurantList() {
      eventHub.$emit('showRestaurantList');
    },
    setCurrentRestaurant(restaurant) {
      this.trackRestaurantSelect(restaurant.publicNameSlug);
      this.$router.push({
        name: "store",
        params: {
          restaurant: restaurant.publicNameSlug
        }
      });
    },
    trackRestaurantSelect(restaurantName) {
      dataLayer.push({
        'event': 'GAEvent',
        'eventCategory': 'restaurants',
        'eventAction': 'clickResult',
        'eventLabel': restaurantName,
        'eventValue': undefined,
        'searchTerm': this.currentSearch && this.currentSearch.toLowerCase(),
        'amountSearchResults': 1
      });
    },
    created() {
      this.startEvents()
      // eventHub.$on('addFilterTheRestaurants', (attribute) => this.filteredRestuarants.value = this.restaurants.forEach(rest => {console.log(rest)}));
      // eventHub.$on('addFilterTheRestaurants', (attribute) => {console.log("test")});
      // eventHub.$on('removeFilterTheRestaurants', (attribute) => {console.log("test")});
    },
    beforeDestroy () {
      bus.$off('addFilterTheRestaurants')
      bus.$off('removeFilterTheRestaurants')
    },
    isLast: function (idx, list) {
      return idx === list.length - 1;
    },
    isFirst: function (idx) {
      return idx === 0;
    },
  }
}
</script>

Adn 在这里发出:

<template lang="html">


<div class="c-filters">
    <div class="c-filters-list">
  // Here I call the function to $emit my event
      <div class="c-filters__item" v-for="item in filters" @click="(e) => {toggleClass(e); addFilter(item)}"> 
        {{$t(`storefinder.store.attributes.${item}`)}}
      </div>
    </div>
  </div>
</template>

<script>
import {getKeys} from './../../i18n/'
import eventHub from './../../event-hubs/storefinder'
import notificationHub from './../../event-hubs/notification'
import GLSApi from './../../api/gls'

export default {
  data() {
    return {
      attributes: null,
      filters : [
        "WIFI",
        "TABLESERVICE",
        "MCCAFE",
        "INDOORDINING",
        "DRIVETHRU",
        "BREAKFAST",
        "MALEFEMALEHANDICAPACCESSIBLE",
        "BABYCHANGING",
        "BIRTHDAYPARTIES",
        "SELFORDERKIOSK",
        "OUTDOORPLAYGROUND",
        "INDOORPLAYGROUND",
        "JUNIORCLUB"
      ]
    }
  },
  computed: {
    getAttributes() {
      let arr = this.attributes.map(elem => elem.storeAttributes.attribute)
      return arr.map((el,index, array) => array[index].map(obj => obj.type))
    }
  },
  methods: {
    toggleClass(e){
      e.target.classList.contains("add-filter") ? e.target.classList.remove("add-filter") : e.target.classList.add("add-filter") ;
    },
 // here it the $emit happening
    addFilter (item) {
      eventHub.$emit('addFilterTheRestaurants', item);
    },
    deleteFilter (item) {
      eventHub.$emit('removeFilterTheRestaurants', item);
    }
  },
  beforeCreate() {
    eventHub.$on('attributesLoaded', (params) => this.attributes = params);
  }
}
</script>

最佳答案

您正在计算属性中注册 addFilterTheRestaurants 事件。但是,除非引用计算属性,否则不会调用计算属性的函数。由于您从未引用 this.startEvents,因此该函数永远不会执行。

您可以全天发出 addFilterTheRestaurants 事件,但不会发生任何事情,因为您尚未注册该事件。

只需在 created Hook 中注册 $on 处理程序即可。或者将 startEvents 设为方法而不是计算属性,并在 created Hook 中调用它。但是,请确保您指定的是 created 生命周期 Hook ,而不是名为 created 的方法。

关于javascript - 当事件 $emit 发出时,Vue $on 不运行我的函数,即使我可以看到在 Vue 控制台中触发的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45962986/

相关文章:

javascript - d3.js 是否提供了一种将我的数据集扩展到图表原点的方法?

c# - 存储要取消订阅的事件处理程序列表

javascript - 在调用 html() 之前是否需要执行 unbind() 或 off()

vue.js - 如何从 DOM 卸载 vuejs 实例

ruby-on-rails - Vue.js 在 if 评估后清除数据

javascript - OL3 中可点击的 map 覆盖?

javascript - 使用 $.ajax 在 PHP 中获取空数组

javascript - 如何使用 Greasemonkey 重新组织 <ul> 列表?

multithreading - Delphi 当应用程序在线程等待事件时终止时会发生什么?

javascript - Vue - 如何从复选框事件获取当前实例?