0

I'm trying to make my own version of the https://vuetifyjs.com/en/components/expansion-panels.

How can I get it so the emit inside of ExpansionPanel can then call a function inside of ExpansionPanels without having to change anything inside of App.vue?

It currently looks something like:

<!-- ExpansionPanels.vue -->
<template>
  <div>
    <slot @open:panel="openPanel" />
  </div>
</template>

<script setup>
const openPanel = () => {
...
}
</script>
<!-- ExpansionPanel.vue -->
<div>
  <slot />
    ...
  <button @click="$emit('open:panel')" />
</div>
<!-- App.vue -->
<expansion-panels>
  <expansion-panel v-for="...">
    ...
  </expansion-panel>
</expansion-panels>
Velocity
  • 11
  • 1

1 Answers1

0

Solved, thanks to Augustin Riedinger's answer

const { createApp  } = Vue;

const expansionPanels  = {
  setup() {  
    const openPanel = (event) => {
      console.log(`openPanel: ${event}`)
    }
    return { openPanel }
  },
  template: `<div><slot name="default" :on="{'open': openPanel}" /></div>`  
}

const expansionPanel  = {
  props: ['panel'],
  emits: ['open'],
  template: `<div>Panel {{panel.id}} &nbsp; <slot /><button @click="$emit('open', panel.id)">open</button></div>`
}


const App = { 
  components:  {expansionPanel, expansionPanels },
  data() {
    return { panels: [ 
      { id: 1 },
      { id: 2 },
      { id: 3 }
    ]}
  }
}

const app = createApp(App)
const vm = app.mount('#app')
#app { line-height: 2; }
[v-cloak] { display: none; }
<div id="app" v-cloak>
 <expansion-panels>
   <template v-slot:default="{on}">
      <expansion-panel v-for="panel in panels" :panel="panel" :key="panel" v-on="on">
      </expansion-panel>
  </template>
</expansion-panels>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
Tolbxela
  • 4,767
  • 3
  • 21
  • 42