Search code examples
vue.jscomponentsvue-componentcode-reuse

How can one access the state of other instances of a reusable component in Vue.js


Being new to Vue, came across the following use-case. I have an accordion component that is reused across the application. The accordion simply hides and reveals anything wrapped inside it.

How can I enable closing any other open instance when I open an instance? e.g if prototype accordion is open, then functions and objects accordion is clicked, prototype accordion should close.

const vue = Vue.createApp({});

vue.component('accordion', {
  data() {
    return {
      open: false,
    }
  },
  methods: {
    toggle() {
      this.open = !this.open;
    },
  },
  template: `
    <div class="accord">
      <p @click="toggle" class="accord-header">Click me to open and close!</p>
      <div v-if="open" class="accord-body">
        <slot></slot>
      </div>
    </div>
  `,
})

vue.mount('#main-app');
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

#main-app {
  width: 50%;
  margin: 0 auto;
}

.accord {
  padding: 4px;
  cursor: pointer;
}
.accord-header {
  text-align: center;
  padding: 4px 0;
}
.accord-body {
  background-color: #eee;
  padding: 8px;
}
<script src="https://unpkg.com/vue@next"></script>

<div id="main-app">
  <accordion>
    <p class="accord-text">Javascript Proptotypes and inheritance</p>
  </accordion>
  <accordion>
    <p class="accord-text">Scopes and Closures</p>
  </accordion>
  <accordion>
    <p class="accord-text">Functions and Objects</p>
  </accordion>
</div>


Solution

  • You can change open to be a prop, then you can do something like activeAccordianId: 1 in the parent and have the prop be

    <accordian :open="activeAccordianId === 1" />
    <accordian :open="activeAccordianId === 2" />
    ...