【问题标题】:listen to events from dynamic vue components监听来自动态 Vue 组件的事件
【发布时间】:2019-10-15 14:33:56
【问题描述】:

如何监听动态创建的组件实例发出的事件?

在示例中,顶部组件是在 DOM 中添加的,而第二个组件是在 javascript 中动态创建的。

Vue.component("button-counter", {
  data: function() {
    return {
      count: this.initial_count
    }
  },
  props: ['initial_count'],
  methods: {
    add: function() {
      this.count++
        this.$emit('myevent', this.count)
    }
  },
  template: '<button v-on:click="add">You clicked me {{ count }} times.</button>'
})

let app = new Vue({
  el: "#app",
  data() {
    return {
      initial_count: 10,
    }
  },
  mounted: function() {
    let initial_count = this.initial_count

    let ButtonCounterComponentClass = Vue.extend({
      data: function() {
        return {}
      },
      render(h) {
        return h("button-counter", {
          props: {
            initial_count: initial_count
          }
        })
      }
    })
    let button_counter_instance = new ButtonCounterComponentClass()
    button_counter_instance.$mount()
    button_counter_instance.$on('myevent', function(count) {
      console.log('listened!')
      this.say(count)
    })
    this.$refs.container.appendChild(button_counter_instance.$el)
  },
  methods: {
    say: function(message) {
      alert(message)
    }
  }
})
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>

<div id="app">
    <button-counter initial_count=20 v-on:myevent="say"></button-counter>
    <div ref='container'></div>
</div>

【问题讨论】:

    标签: vue.js dynamic vuejs2 vue-component


    【解决方案1】:

    如果我明白你想要什么,那么你只需要在内部组件上监听事件并传递它。

    我在几个地方使用了箭头函数来避免this 绑定的问题。否则,我会尽量让您的代码保持不变。用**** 标记的更改。

    Vue.component("button-counter", {
      data: function() {
        return {
          count: this.initial_count
        }
      },
      props: ['initial_count'],
      methods: {
        add: function() {
          this.count++
            this.$emit('myevent', this.count)
        }
      },
      template: '<button v-on:click="add">You clicked me {{ count }} times.</button>'
    })
    
    let app = new Vue({
      el: "#app",
      data() {
        return {
          initial_count: 10,
        }
      },
      mounted: function() {
        let initial_count = this.initial_count
    
        let ButtonCounterComponentClass = Vue.extend({
          data: function() {
            return {}
          },
          render(h) {
            return h("button-counter", {
              props: {
                initial_count: initial_count
              },
              // **** Added this ****
              on: {
                myevent: count => {
                  this.$emit('myevent', count);
                }
              }
              // ****
            })
          }
        })
        let button_counter_instance = new ButtonCounterComponentClass()
        button_counter_instance.$mount()
        // **** Changed the next line ****
        button_counter_instance.$on('myevent', count => {
          console.log('listened!')
          this.say(count)
        })
        this.$refs.container.appendChild(button_counter_instance.$el)
      },
      methods: {
        say: function(message) {
          alert(message)
        }
      }
    })
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
    
    <div id="app">
        <button-counter initial_count=20 v-on:myevent="say"></button-counter>
        <div ref='container'></div>
    </div>

    了解button_counter_instance 不是button-counter 组件的实例很重要。您已将其包装在另一个组件中,尽管该组件不会添加任何额外的 DOM 节点。所以监听 wrapper 组件和监听 button-counter 是不一样的。

    你可以传递给h的文档:https://vuejs.org/v2/guide/render-function.html#The-Data-Object-In-Depth

    【讨论】:

      猜你喜欢
      • 2021-12-27
      • 2016-01-09
      • 2017-02-25
      • 2020-06-25
      • 2020-03-27
      • 2020-08-11
      • 1970-01-01
      • 2021-08-03
      • 2019-07-20
      相关资源
      最近更新 更多