Vue.js父组件事件处理方法无法正常访问自己的数据

Posted

技术标签:

【中文标题】Vue.js父组件事件处理方法无法正常访问自己的数据【英文标题】:Vue.js parent component event handler method can't access it's own data normally 【发布时间】:2018-01-03 20:05:19 【问题描述】:

简述发生了什么

在父组件中,我将一个数组传递给子组件,当用户选择该数组的一个元素时,子组件会发出一个事件,传递所选项目,该事件在父组件中处理。我想获取选定的元素(在父级的事件处理程序中),并将其推送到 不同的数组在父级中。我可以很容易地访问/console.log 在发射期间传递的对象,但是在 parent 的 事件处理方法中, this.currentlySelectedAdvertisements

当我console.log(this.currentlySelectedAdvertisements)(如下所示)时,控制台告诉我它是 __ob__: Observer currentlySelectedAdvertisements,它会显示一个空数组[]。另外,在父母的事件处理方法中,如果我使用[].push.call(this.currentlySelectedAdvertsiements, payload.chosen),我就不会出错。但是,我似乎无法遍历 this.currentlySelectedAdvertisements 并影响子项的呈现方式。我对此感到很困惑,我哪里做错了?我对 Vue.js 很陌生,这只是我使用它的第二个项目。请帮助我达到启蒙/理解。

包含代码示例的完整信息

我有一个 父组件,它的 data 属性中有一个数组,就像这样

// **** PARENT COMPONENT JS ****
import Advertisement from './Advertisement.vue';

export default 
  name: 'Column2',
  data() 
    return 
      columns: 2,
      currentlySelectedAdvertisements: [] // <--- clearly defined as an Array
    ;
  ,
  props:  
    adPool: Array,
    positions: Array
  ,
  components: 
    'advertisement': Advertisement,
  ,
  methods: 
    handleSelection(payload)  // <--- event handler method

      console.log("in column2 component and advert selected was ", payload);
      // this.currentlySelectedAdvertisements.push(payload.chosen);

      console.log(this.currentlySelectedAdvertisements);

      //  right here ^ now shows as '__ob__: Observer' in the console ****

    
  
;

我正在使用这个数组来渲染 子组件 advertisement 就像这样(这里是模板部分)

<!-- *** PARENT COMPONENT TEMPLATE FOR RENDERING CHILD COMPONENTS *** -->
<template>
   <div class="column2">
      <div v-for="(ad, index) in currentlySelectedAdvertisements" class="column2__column">
         <advertisement :position="positions[index]" :adPool="adPool" :image="ad.image"></advertisement>
      </div>
      <div v-for="i in (columns - currentlySelectedAdvertisements.length)" class="column2__column column2__column--dashed">

         <advertisement @advertisement-selected="handleSelection" :position="positions[i-1]" :adPool="adPool"></advertisement>

     <!-- here is the listener ^ ****** -->

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

现在在 子组件中我有一个选择元素,它呈现用户的选择以供选择(这里是模板的一部分)

 <!-- *** CHILD COMPONENT TEMPLATE *** -->
 <div class="advertisement__chooser">

    <select v-model="selected" @change="advertisementSelected(selected)" :name="ad_position">

     <!-- here is the change listener ^ for when the user picks an option ***** -->

      <option value="">Please Choose</option>
      <option v-for="ad in adPool" :data-img="ad.image" :value="ad.id">ad.name</option>
    </select>
  </div>

这里是找到所选项目的方法,并发出事件供父级收听

 // *** PART OF CHILD COMPONENT JS ***
 methods: 

  advertisementSelected(id, event)  // <--- event handler in child

    var chosen_advert = this.findAdById(id);
    var event_payload = ;
    if ( chosen_advert ) 
      event_payload = 
        position: this.ad_position,
        chosen: chosen_advert
      ;
      console.log('In Advertisement.vue ', event_payload);

      this.$emit('advertisement-selected', event_payload);

      // and here ^ is the emission of the event ******

    
  ,
  findAdById(id) 
    for ( var i in this.adPool ) 
      if ( this.adPool[i].id === id ) 
        return this.adPool[i];
      
    
    return -1;
  

这是console.log(this.currentlySelectedAdvertisements)父事件处理程序中的截图screenshot

【问题讨论】:

Vue 中的所有数据值都转换为观察值。这就是 Vue 的响应式工作原理。 $on 是在哪里定义的? 其实我觉得没关系。看起来观察到的数据值已正确推送到数组中(尽管您已在代码中将其注释掉)。 ^ 无论如何,注释掉数组推送,抛出一个非常奇怪的错误说invalid array length,所以这很奇怪,我不能在不使用数组的情况下推送到那个数组。原型,我无法遍历数组并在每次迭代时渲染子组件。 我认为这不是发生错误的地方。我认为它更有可能发生在您的模板逻辑中。如果您在小提琴/钢笔中对问题进行了一个小演示,将会很有帮助。 【参考方案1】:

好的,所以最后,这以某种方式自行解决了...... 我今天回家了,当我今天早上回来并再次启动 webpack 开发服务器时,没有错误,没有问题,它完全按照我昨天的预期工作。我不明白,我很沮丧,但我很高兴我没有失去理智,这就是我想要的方式。

【讨论】:

以上是关于Vue.js父组件事件处理方法无法正常访问自己的数据的主要内容,如果未能解决你的问题,请参考以下文章

发出的事件不会调用 Vue JS 组件中的父方法

无法在 Vue.JS 上捕获自定义事件

vue 组件内 数组无法正常渲染$set

VUe.js 父组件向子组件中传值及方法

Vue.js 实例方法

vue.js(19)--vue中子组件调用父组件的方法