Vue JS:this。$ on事件不包含传递的参数

约瑟夫·霍维克

这是我的组件。我已经成功地将参数从子组件传递给父组件,但没有从父组件传递给子组件。console.log('In initDetail()');行触发,这表示$on事件已触发,但param未定义。我想知道为什么。

父组件:

components: {
  "child-component": ChildComponent
}
methods: {
  loadDetail() {
    this.$emit('loadDetailEvent', 'test');
  }
}

子组件:

mounted() {
  this.$on('loadDetailEvent', this.initDetail(param)); 
}
methods: {
  initDetail(param) {
    console.log('In initDetail()');
    console.log(param);
  }
}

我也尝试过立即调用函数。无论是console.log('$on event');也不console.log(param);行打印。

this.$on('loadDetailEvent', function(param){
  console.log('$on event');
  console.log(param);
});
感谢:D

正如注释中指出的那样,您的代码中存在一些误解:

  1. 调用loadDetailEventloadDetail方法时,您的父组件正在发出事件您的子组件也在侦听一个loadDetailEvent事件,但是只有在其自己的Vue实例发出该事件时,它才会处理该事件如果父级的Vue实例发出事件,则子级将不知道该事件。

  2. 您正在尝试loadDetailEvent通过触发initDetail事件并将参数传递给该方法来处理。但是,在您的代码中,您只是将loadDetailEvent处理程序设置this.initDetail(param)为在mounted挂钩范围内调用的结果在这种情况下,您想要做的是指定一个匿名函数作为处理程序,该函数接收该param值并将其传递给this.initDetail

     this.$on('loadDetailEvent', (param) => this.initDetail(param))
    

但是,要弄清问题的根源:似乎您想在调用父方法时调用子方法。您可以通过几种不同的方式执行此操作:

  1. 正如@Ohgodwhy所建议的那样,您可以创建一个单独的全局Vue实例以用作事件总线。
  2. 您可以在父模板的子组件标签上设置一个ref(say ref="child"),然后直接通过调用子组件的方法this.$refs.child.initDetail('test')
  3. 正如@ B.Fleming建议的那样,您可以在子组件上设置一个观察者,以对父组件传递的不断变化的prop值做出反应。这有点棘手,因为您将需要保持作为prop传递的变量的值(我将使用.sync修饰符,如下所示)。

以下是上述解决方案的示例片段:

使用事件总线:

let EventBus = new Vue();

Vue.component('child', {
  template: `<div>Child</div>`,
  mounted() {
    EventBus.$on('loadDetailEvent', (param) => this.initDetail(param)); 
  },
  methods: {
    initDetail(param) {
      console.log('In initDetail()');
      console.log(param);
    }
  }
});

new Vue({
  el: '#app',
  methods: {
    loadDetail() {
      EventBus.$emit('loadDetailEvent', 'test');
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>

<div id="app">
  <child></child>
  <button @click="loadDetail">load</button>
</div>

使用ref

Vue.component('child', {
  template: `<div>Child</div>`,
  methods: {
    initDetail(param) {
      console.log('In initDetail()');
      console.log(param);
    }
  }
});

new Vue({
  el: '#app',
  methods: {
    loadDetail() {
      this.$refs.child.initDetail('test');
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>

<div id="app">
  <child ref="child"></child>
  <button @click="loadDetail">load</button>
</div>

使用prop值和观察者:

Vue.component('child', {
  template: `<div>Child</div>`,
  props: { loading: String },
  methods: {
    initDetail(param) {
      console.log('In initDetail()');
      console.log(param);
    }
  },
  watch: {
    loading(val) {
      if (val) {
        this.initDetail(val);
        this.$emit('update:loading', '');
      }
    }
  }
});

new Vue({
  el: '#app',
  data() {
    return { payload: '' }
  },
  methods: {
    loadDetail() {
      this.payload = 'test';
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>

<div id="app">
  <child :loading.sync="payload"></child>
  <button @click="loadDetail">load</button>
</div>

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章