Home > Blockchain >  Vue JS 3 Parent Calling Multiple Children methods
Vue JS 3 Parent Calling Multiple Children methods

Time:07-01

I have a parent page for FAQ and child component that collapses the Q&A. But on the FAQ page we have a button to expand all the FAQs. So I am trying to call a method on the child components which we will have a dozen or so of these. But when I click on view all it only opens the last child component. Why is it only hitting the last component and not all of them?

import CollapsiblePanel from '@/components/CollapsiblePanel';

// Imports
import { ref } from 'vue';

const collapsiblePanelRef = ref();

function expand() {
    collapsiblePanelRef.value.expandAll()
}

Then the mark up with the child ref...

 <a @click="expand">View All</a>
 <CollapsiblePanel ref="collapsiblePanelRef">
     <template v-slot:title>
         Sample title 1
     </template>
     <template v-slot:content>
        Lorem ipsum 1
     </template>
 </CollapsiblePanel>
 <CollapsiblePanel ref="collapsiblePanelRef">
     <template v-slot:title>
         Sample title 2
     </template>
     <template v-slot:content>
        Lorem ipsum 2
     </template>
 </CollapsiblePanel>

Then the CollapsiblePanel looks like...

function expandAll() {
    isActive.value = true;
}

defineExpose({
    expandAll
})

CodePudding user response:

I do not know the exact answer to why only the last opens, but I would rather do this with a prop. In the parent template:

<a @click="expandAll">View All</a>     
<CollapsiblePanel :open="openAll">
    ...
</CollapsiblePanel>
<CollapsiblePanel :open="openAll">
    ...
</CollapsiblePanel>

Function for the button in the parent:

const openAll = ref(false);

function expandAll() {
    openAll.value = !openAll.value;
}

And than in the CollapsiblePanel script setup:

const props = defineProps({openAll: Boolean});
const currentOpen = ref(false);

/// Call with click on child:
const toggleIndividual = () => {
    currentOpen.value = !currentOpen.value;
}
/// If prop changes (expand all button is clicked) open child
watch(props.openAll) {
   currentOpen.value = true;
}

And in the CollapsiblePanel template a v-if="currentOpen" on the div that needs to open and close. You can put @click="toggleIndividual" on the element that you want to click to expand it.

Now if you toggle expand all, all childs will expand. If you click an individual child it will collaps.

Hope this helps.

  • Related