AdSense

網頁

2026/1/24

Vue Nuxt 3 新增訂單資料(表單 + POST API)

本篇介紹在Vue Nuxt 3專案使用表單和POST API新增資料。


目前專案[出口業務]頁面只能查詢[查詢訂單API]中寫死的[訂單]資料,接下來會建立[新增訂單]頁面讓使用者可以新增[訂單]資料。


事前要求

參考「Vue Nuxt 3 分頁」。


建立共享資料介面

Nuxt的shared目錄中的程式可被前後端引用。新增shared/types/order.ts,建立Order介面讓前後端可以共用。

shared/types/order.ts

export interface Order {
  id: number;
  country: string;
  status: string;
}


修改訂單API介面

修改types/api/orders.get.ts,把Order刪除,改從shared/types/orders.ts匯入;建立CreateOrderResponse做為[新增訂單API]的回應資料介面。

stypes/api/orders.ts

import type { Order } from "~/shared/types/order";
export interface OrdersResponse {
  data: Order[];
  total: number;
  totalPages: number;
  page: number;
  pageSize: number;
}

export interface CreateOrderResponse {
  success: boolean;
  order: Order;
}


建立訂單資料

新增server/data/orders.ts,把server/api/orders.get.ts中的[訂單資料]搬到這裡,並指定型態為shard/types/order/Orders

server/data/orders.ts

import type { Order } from "~/shared/types/order";

export const orders: Order[] = [
  { id: 10001, status: "pending", country: "US" },
  { id: 10002, status: "done", country: "JP" },
  { id: 10003, status: "pending", country: "CN" },
  { id: 10004, status: "done", country: "KR" },
  { id: 10005, status: "pending", country: "VN" },
  { id: 10006, status: "done", country: "US" },
  { id: 10007, status: "pending", country: "JP" },
  { id: 10008, status: "done", country: "CN" },
  { id: 10009, status: "pending", country: "KR" },
  { id: 10010, status: "done", country: "VN" },
];


修改查詢訂單API

修改server/api/orders.get.ts,如上述把[訂單資料]搬移到server/data/orders.ts並匯入為資料源。


建立新增訂單API

新增server/api/orders.post.ts為[新增訂單API] [POST] /api/orders

使用readBody取得請求主體資料body,並根據傳入的countrystatus建立[新訂單]newOrder,[訂單編號]id為最後一筆[訂單]的[訂單編號] + 1。

然後將[新訂單]newOrder放入[訂單資料]server/data/orders.orders

server/api/orders.post.ts

import type { Order } from "~/shared/types/order";
import { orders } from "~/server/data/orders";

export default defineEventHandler(async (event) => {
  const body = await readBody<Omit<Order, 'id'>>(event);
  const newOrder: Order = {
    id: getNewId(),
    country: body.country,
    status: body.status,
  };
  orders.push(newOrder);

  return {
    success: true,
    order: newOrder,
  };
});

function getNewId(): number {
  return orders.length ? orders[orders.length - 1].id + 1 : 1;
}


建立新增訂單頁面

建立pages/home/export/create.vue/code>為[新增訂單]頁面。

<form>為表單資料,有[訂單狀態]輸入欄位<input v-model="status"和[出口國家下拉選單元件]<CountrySelect v-model="country" />,分別以v-model綁定ref物件。

點選[儲存]按鈕<button type="submit">會觸發save函式將表單欄位中的資料傳入後端[新增訂單API]來新增一筆[訂單]。

點選[返回]按鈕觸發navigateTo('/home/export')導向[出口業務]頁面。

pages/home/export/create.vue

<template>
  <div>
    <h1>新增訂單</h1>
  </div>
  <form @submit.prevent="save">
    <label>
      訂單狀態:
      <input v-model="status" placeholder="pending/done" />
    </label>
    <br />
    <label>
      出口國家:
      <CountrySelect v-model="country" />
    </label>
    <br />
    <button type="submit">儲存</button>
    <button type="button" @click="navigateTo('/home/export')">返回</button>
  </form>
</template>
<script setup lang="ts">
import type { CreateOrderResponse } from "~/types/api/orders";

const status = ref("");
const country = ref("");

async function save() {
  if (!status.value || !country.value) {
    alert("請填寫所有欄位");
    return;
  }

  const response = await $fetch<CreateOrderResponse>("/api/orders", {
    method: "POST",
    body: {
      status: status.value,
      country: country.value,
    },
  });

  if (response.success) {
    alert('新增訂單成功!');
    navigateTo("/home/export");
  }
}
</script>


修改出口業務頁面

在[出口業務]頁面pages/home/export/index.vue新增導向至[新增訂單]頁面的[新增訂單]按鈕。

<button @click="navigateTo('/home/export/create')">新增訂單</button>

github



測試

在[出口業務]頁面點選[新增訂單]按鈕前往[新增訂單]頁面。



沒有留言:

AdSense