如何从组件发出并从另一个组件中收听?

时间:2021-04-13 19:50:52

标签: vue.js

我在 Layout.vue 组件中有一 TheSidebarTheHeaderTheHeader 中有一个按钮可以打开 TheSidebar 组件中的侧边栏。

当我点击标题中的按钮时,我需要打开侧边栏:

我的尝试:

TheHeader中:

methods: {
  openSidebar() {
    this.$root.$emit("open-sidebar");
  },
},

TheSidebar

data() {
  return {
    sidebarOpen: false,
  };
},
mounted() {
  this.$root.$on("open-sidebar", (this.sidebarOpen = true));
},

我使用的是 VUE 3,所以我在控制台中收到此错误:TypeError: this.$root.$on is not a function so How can communication ?

3 个答案:

答案 0 :(得分:2)

你可以使用像 tiny emitter 这样的东西,它工作正常并且不关心父子关系

var emitter = require('tiny-emitter/instance');
 
emitter.on('open-sidebar', ({isOpen}) => {
 //
});
 
emitter.emit('open-sidebar', {isOpen : true} );

答案 1 :(得分:1)

你只能将 props 传递给直接的子组件,并且

您只能向直接父级发出事件。但是

你可以provide and eject从任何地方到任何地方

答案 2 :(得分:0)

根据另一个答案,提供和弹出可能是您在 Vue 3 中的最佳选择,但我创建了一个简单的示例来说明如何使用 props/events 来实现。使用 Vue 2 构建,因为我还没有使用 3,但应该也可以在 Vue 3 中使用。

Parent.vue

<template>
  <div class="parent">
    <div class="row">
      <div class="col-md-6">
        <h4>Parent</h4>
        <hr>
        <child-one @show-child-two-event="handleShowChildTwoEvent" />
        <hr>
        <child-two v-if="showChildTwo" />
      </div>
    </div>
  </div>
</template>

<script>
  import ChildOne from './ChildOne.vue'
  import ChildTwo from './ChildTwo.vue'

  export default {
    components: {
      ChildOne,
      ChildTwo
    },
    data() {
      return {
        showChildTwo: false
      }
    },
    methods: {
      handleShowChildTwoEvent() {
        this.showChildTwo = true;
      }
    }

  }
</script>

ChildOne.vue

<template>
  <div class="child-one">
    <h4>Child One</h4>
    <button class="btn btn-secondary" @click="showChildTwo">Show Child Two</button>
  </div>
</template>

<script>
  export default {
    methods: {
      showChildTwo() {
        this.$emit('show-child-two-event');
      }
    }
  }
</script>

ChildTwo.vue

<template>
  <div class="child-two">
    <h4>Child Two</h4>
  </div>
</template>
相关问题