/ Gists / Form composable
On gists

Form composable

Vue.js

Old.js Raw #

// https://cdruc.com/form-composable

const router = useRouter();

const form = ref({
  title: "",
  content: "",
});

const isProcessing = ref(false);
const error = ref(null);

async function handleSubmit() {
  if (isProcessing.value) return;

  error.value = null;
  isProcessing.value = true;

  try {
    await axios.post("/api/posts", form.value);
    await router.push("/");
  } catch (err) {
    error.value = err;
  }

  isProcessing.value = false;

  if (error?.status === 403) {
    await router.replace("/login");
  }
}

useForm.js Raw #

import {reactive} from "vue";

export default function useForm(fields) {
  const form = reactive({
    fields,
    error: null,
    processing: false,
    async submit(submitter) {
      if (this.processing) return;

      this.error = null;
      this.processing = true;

      try {
        await submitter(this.fields);
      } catch (err) {
        this.error = err;
      }

      this.processing = false;
    },
  });

  return form;
}

// -------------- Usage: -------------- 
const router = useRouter();
const form = useForm({
  title: "",
  content: "",
});

async function handleSubmit() {
  await form.submit(async (fields) => {
    await axios.post("/api/posts", fields);
    await router.push("/");
  });

  if (form.error?.status === 403) {
    await router.replace("/login");
  }
}