Vue 2和具有多个组件的子组件事件

时间:2016-12-01 12:37:25

标签: events vue.js vue-component

我已经阅读了this个问题/答案,虽然在父级包含特定组件时有效,但在我的方案中,父级包含这个:

<component :is="currentView"></component>

并且currentView的值决定了哪个组件被加载&#39;在任何特定的时间。因此,在组件标记中使用v-on:event="handler"意味着所有子组件必须使用相同的事件名称:(。是否可以在父级的created()函数中设置特定的处理程序将被调用,无论当前哪个组件在视图中,以及它们各自可能发送不同的事件?例如,我有一个登录组件发送登录&#39;事件,以及发送“更新”事件的数据视图组件。在父级中,我想要这样的事情:

this.$on('login', doLogin)
this.$on('update', doUpdate)

然而,这是从他们自己而不是其孩子那里听事件。我也尝试给组件一个ref:

<component ref="main" :is="currentView"></component>

并使用this.$refs.main.$on('login', doLogin),但在初始渲染之前不会创建$refs对象,因此不能进入{{1} }}方法(太早了),在mounted()方法中,它会被重复调用,我肯定不是一个好主意......

2 个答案:

答案 0 :(得分:2)

您可以设置一个全局事件,然后将该操作的名称作为有效负载的一部分传递,即

const Login = {
  template: `<h1>Login</h1>`,
  mounted() {

    this.$emit('global-event', {
      action: 'login',
      data: {
        user: 'foo',
      },
    })

  },
}

const Update = {
  template: `<h1>Update</h1>`,
  mounted() {

    this.$emit('global-event', {
      action: 'update',
      data: {
        user: 'foo bar',
      },
    })

  },
}


new Vue({
  el: '#app',
  data: {
    called: {
      update: 0,
      login: 0,
    },
    currentView: 'login',
  },
  components: {
    Login,
    Update,
  },
  methods: {
    
    // within doSomething you would process the various events based on their payload.action
    doSomething (payload) {
      
      this.called[payload.action]++
      
    },
      
    toggleView () {
      
      this.currentView = this.currentView === 'login' ? 'update' : 'login'
      
    },
  
  },
})
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
  <component @global-event="doSomething" :is="currentView"></component>
  <button @click="toggleView">toggle view</button>
  <pre>{{ called }}</pre>
</div>

答案 1 :(得分:1)

尔加!经过多年的搜索,找不到任何东西,然后发布在这里,我当然会立即绊倒答案。

但这仅适用于,如果您可以控制子组件(我建立了所有组件)。在孩子身上,你只需:

this.$parent.$emit('login', {some: 'data'})

然后在this.$on('login', doLogin)方法中正常设置父级中created()的事件侦听器。

我确定会出现一种情况,即我使用的第三方组件只需拨打this.$emit(),目前我无法看到{的替代方案在父母身上{1}}。