[Vuejs]-How can I create a reusable form component for each resource I create and/or update (Vue 3, vue-router, Pinia)

1👍

If the form’s UI is mainly expected to stay the same except for a few small differences (e.g. the button text), you could make the form emit a custom "submit" event and then handle that event from the parent component where you render the form (i.e. on the update page you have <ApplicationForm @submit="updateApplication"> and on the create page you have <ApplicationForm @submit="createNewApplication" />:

// ApplicationForm.vue
<template>
  <section class="columns">
    <div class="column">
      <div v-if="error" class="notification is-danger">{{ error }}</div>
      <div class="field">
        <label class="label">Name</label>
        <input v-model="application.name" class="input" type="text" />
      </div>
      <div class="field">
        <label class="label">Location</label>
        <input v-model="application.location" class="input" type="text" />
      </div>
      <div class="control">
        <button @click="$emit('submit')" class="button">{{ buttonText }}</button>
      </div>
    </div>
  </section>
</template>

As for the text, you can pass that as a prop (e.g. buttonText) to the ApplicationForm component. If some sections of the form are more substantially different than just different text between the "Update" and "Create" form, that’s when you’d use slots.

I wouldn’t recommend making the <ApplicationForm /> component responsible for reading the route parameters; that should generally be done only by the Vue component responsible for rendering the page (and then it should pass that data through props so that the component is as re-usable as possible)

So your parent component could look something like this:

<ApplicationForm v-if="application" @submit="updateApplication" />
<ApplicationForm v-else @submit="createNewApplication" />

Leave a comment