本篇介紹在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,並根據傳入的country和status建立[新訂單]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>
測試
在[出口業務]頁面點選[新增訂單]按鈕前往[新增訂單]頁面。
沒有留言:
張貼留言