从 vue.js 中的 slot 访问组件数据在外围不声明模板

问题描述

正在创建用于无框窗口的菜单组件。但我不知道如何将事件绑定到插槽中。我想建立这样的结构

在 WindowBar.vue 中

<template>
  <div>
    <app-menu-bar>
      <app-menu label="File"></app-menu>
    </app-menu-bar>
  </div>
</temaplte>

在 AppMenuBar.vue 中(名称是 app-menu-bar)

<template>
  <section>
    <slot
      v-bind:onSelected="onSelected"
      v-on:doClick="doClick"
    >
    </slot>    
  </section>
</template>

<script>
export default {
  name: 'app-menu-bar',data () {
    return {
      onSelected: ''
    }
  }
}
</script>

在 AppMenu.vue 中(名称是 app-menu)

<template>
  <section class="menu">
    <button 
      v-on:click="doClick"
      v-bind:class="isSelected"
    >
    {{ label }}
    </button>
  </section>
</template>

<script>
export default {
  name: 'app-menu',props: {
    label: String
  },computed: {
    isSelected () {
            // This is binding data from AppMenuBar
      return this.onSelected == this.label ? 'selected' : ''
    }
  },methods: {
    doClick () {
      this.$emit('doClick',this.label)
    }
  },mounted () {
    console.log(this.onSelected)  // it is undefined
  }
}
</script>

我如何将数据绑定到槽中,比如 this.onSelected?

解决方法

您无法监听 <slot> 上的事件。您可以在此处阅读更详细的答案https://github.com/vuejs/vue/issues/4332

在您的情况下,我建议将所有业务逻辑放在父组件(即 WindowBar.vue)中。之后,您可以控制孩子的组件事件和道具。或者,如果有一些特定情况,并且您想通过嵌套组件传递事件,您可以使用事件总线。您可以在此处阅读有关事件总线的更多信息:https://www.digitalocean.com/community/tutorials/vuejs-global-event-bus