I'm trying to use the Tailwind PrimeVue v3 Stepper component and I need to perform some actions before moving between each StepperPanel.
For example, I want to perform a simple console.log("before panel change")
from inside the <script setup lang='ts'>
area before each panel changes.
How can that be done?
From the docs I can see that the PrimeVue Stepper
component has update:activeStep
and step-change
emits but those are triggered after the panels change. And I need to do the script actions before the panel changes.
The docs also show the use of prevCallback
and nextCallback
for moving between panels, so I assume I need to hook into those somehow. But those are provided inside the template and I have no idea how to access them inside the script tag area.
Here is a live URL to try with: https://stackblitz.com/edit/nuxt-starter-k97nc8?file=app.vue
<template>
<div class="card flex justify-center">
<Stepper>
<StepperPanel header="Header I">
<template #content="{ nextCallback }">
<div class="flex flex-col h-[12rem]">
<div
class="border-2 border-dashed border-surface-200 dark:border-surface-700 rounded-md bg-surface-0 dark:bg-surface-950 flex-auto flex justify-center items-center font-medium"
>
Content I
</div>
</div>
<div class="flex pt-4 justify-end">
<Button
label="Next"
icon="pi pi-arrow-right"
iconPos="right"
@click="nextCallback"
/>
</div>
</template>
</StepperPanel>
<StepperPanel header="Header II">
<template #content="{ prevCallback, nextCallback }">
<div class="flex flex-col h-[12rem]">
<div
class="border-2 border-dashed border-surface-200 dark:border-surface-700 rounded-md bg-surface-0 dark:bg-surface-950 flex-auto flex justify-center items-center font-medium"
>
Content II
</div>
</div>
<div class="flex pt-4 justify-between">
<Button
label="Back"
severity="secondary"
icon="pi pi-arrow-left"
@click="prevCallback"
/>
<Button
label="Next"
icon="pi pi-arrow-right"
iconPos="right"
@click="nextCallback"
/>
</div>
</template>
</StepperPanel>
<StepperPanel header="Header III">
<template #content="{ prevCallback }">
<div class="flex flex-col h-[12rem]">
<div
class="border-2 border-dashed border-surface-200 dark:border-surface-700 rounded-md bg-surface-0 dark:bg-surface-950 flex-auto flex justify-center items-center font-medium"
>
Content III
</div>
</div>
<div class="flex pt-4 justify-start">
<Button
label="Back"
severity="secondary"
icon="pi pi-arrow-left"
@click="prevCallback"
/>
</div>
</template>
</StepperPanel>
</Stepper>
</div>
</template>
<script setup lang="ts">
// Do something in here BEFORE moving between stepper panels
// For example, do a console.log("before panel change")
// I assume I need to use nextCallback and prevCallback from the template
// But I don't know how to access those callbacks here inside script
</script>
<style scoped>
.p-stepper {
flex-basis: 50rem;
}
</style>
This is reasonably common situation, and a possible implication for such a requirement could be that an action is asynchronous; this couldn't be handled with Stepper
events because Vue events don't have a mechanism to wait for asynchronous side effect in event handlers.
Third-party libraries aren't generally expected to cover this range of requirements, they need to provide enough flexibility through callbacks; this what Stepper
already did here. Since step action is triggered in the same component "before" action needs to be performed, a developer has full control over their execution:
<template #content="{ nextCallback }">
...
<Button
@click="changeStep($event, nextCallback)"
/>
</div>
...
<script setup lang="ts">
function changeStep(event: MouseEvent, callback: (event: Event) => void) {
// Do some actions
callback(event);
}
</script>
Notice that original mouse event is passed as is in case the implementation depends on it.