Crud
Crud 元件提供使用者介面,以與來自任何資料來源的資料互動。
透過 Crud
元件及其子元件,您可以輕鬆產生頁面,在這些頁面中,可以表格形式列出、個別顯示詳細資訊,或使用表單建立和編輯來自資料來源的項目。所有這些都只需從單一資料來源定義進行最少的設定。
Demo
Crud
元件會自動為您的資料來源產生 CRUD 頁面,並自動與您的路由解決方案整合。所有需要做的就是 dataSource
定義和 CRUD 頁面的 rootPath
。
頁面位於以下路由中
- 列表:
/${rootPath}
- 顯示:
/${rootPath}/:id
- 建立:
/${rootPath}/new
- 編輯:
/${rootPath}/:id/edit
這些預設路徑和其他開箱即用的設定可以被覆寫,並透過遵循下方的進階設定進行更詳細的配置。
建議包含 dataSourceCache
屬性,以便正確快取來自資料來源查詢方法的結果。請參閱下方關於資料快取章節以了解更多資訊。
或者,可以提供其他配置選項,例如用於分頁項目列表的 initialPageSize
,或用於在使用表單建立新項目時設定初始表單值的 defaultValues
。
資料來源
資料來源是一個具有特定形狀的物件,必須用於配置 Crud
元件或其子元件。它包含
一個
fields
屬性,它擴展了 Data Grid 欄位定義,您可以在其中為您的資料指定不同的欄位、標題名稱和欄位類型等等。id
欄位(字串或數字)是強制性的,以便可以識別個別項目。用於與資料互動的方法的屬性,例如
getMany
、getOne
、createOne
、updateOne
和deleteOne
。一個
validate
函數,用於在建立或編輯資料時進行表單驗證,它會為每個欄位傳回驗證錯誤。
以下是一個簡化的資料來源定義範例
const notesDataSource: DataSource<Note> = {
fields: [
{ field: 'id', headerName: 'ID' },
{ field: 'title', headerName: 'Title' },
{ field: 'text', headerName: 'Text' },
],
getMany: ({ paginationModel }) => {
const start = paginationModel.page * paginationModel.pageSize;
const end = start + paginationModel.pageSize;
const paginatedNotes = notesStore.slice(start, end);
return {
items: paginatedNotes,
itemCount: notesStore.length,
};
},
getOne: (noteId) => {
return notesStore.find((note) => note.id === noteId) ?? null;
},
createOne: (data) => {
const newNote = { id: notesStore.length + 1, ...data } as Note;
notesStore = [...notesStore, newNote];
return newNote;
},
updateOne: (noteId, data) => {
let updatedNote: Note | null = null;
notesStore = notesStore.map((note) => {
if (note.id === noteId) {
updatedNote = { ...note, ...data };
return updatedNote;
}
return note;
});
return updatedNote;
},
deleteOne: (noteId) => {
notesStore = notesStore.filter((note) => note.id !== noteId);
},
validate: (formValues) => {
let issues: { message: string; path: [keyof Note] }[] = [];
if (!formValues.title) {
issues = [...issues, { message: 'Title is required', path: ['title'] }];
}
if (!formValues.text) {
issues = [...issues, { message: 'Text is required', path: ['text'] }];
}
return { issues };
},
};
getMany
資料來源中的 getMany
方法可以用於檢索分頁、排序和篩選的項目,以便作為列表顯示,通常在表格中。
分頁、排序和篩選可以透過 paginationModel
、filterModel
和 sortModel
參數與您的資料獲取整合。這些參數遵循與 Data Grid 使用的分頁、排序 和 篩選模型相同的形狀。
此方法必須傳回一個物件陣列,其中包含要顯示的項目。
{
//...
getMany: async ({ paginationModel, filterModel, sortModel }) => {
// Fetch data from server
const data = await fetch('https://my-api.com/data', {
method: 'GET',
body: JSON.stringify({
page: paginationModel.page,
pageSize: paginationModel.pageSize,
sortModel,
filterModel,
}),
});
return data
},
// ...
}
getOne
資料來源中的 getOne
方法可以用於檢索單一特定項目並顯示其所有屬性。
此方法必須傳回一個對應於要顯示項目的物件。
{
//...
getOne: async (id) => {
// Fetch record from server
const record = await fetch(`https://my-api.com/data/${id}`, {
method: 'GET',
});
return record;
},
// ...
}
createOne
資料來源中的 createOne
方法可以用於建立新項目,通常是透過表單,在表單中可以指定其每個屬性的值。
此方法必須傳回一個對應於已建立新項目的物件。
{
//...
createOne: async (data) => {
// Create record in the server
const record = await fetch('https://my-api.com/data', {
method: 'POST',
body: JSON.stringify(data),
});
return record;
},
// ...
}
updateOne
資料來源中的 updateOne
方法可以用於更新現有項目,通常是透過表單,在表單中可以指定其每個屬性的值。
此方法必須傳回一個對應於已更新新項目的物件。
{
//...
updateOne: async (id, data) => {
// Update record in the server
const record = await fetch(`https://my-api.com/data/${id}`, {
method: 'PUT',
body: JSON.stringify(data),
});
return record;
},
// ...
}
deleteOne
資料來源中的 deleteOne
方法可以用於刪除現有項目。
此方法不需要傳回任何內容。
{
//...
deleteOne: async (id) => {
// Delete record in the server
await fetch(`https://my-api.com/data/${id}`, {
method: 'DELETE',
});
},
// ...
}
表單驗證
或者,可以在資料來源中包含 validate
函數,以便進行表單驗證。
此函數遵循 Standard Schema,因此它接受一個包含給定項目欄位值的物件,並且必須傳回每個欄位的相應錯誤,如範例所示
{
//...
validate: (formValues) => {
let issues = [];
if (!formValues.name) {
issues = [...issues, { message: 'Name is required', path: ['name'] }];
}
if (formValues.age < 18) {
issues = [...issues, { message: 'Age must be higher than 18', path: ['age'] }];
}
return { issues };
},
// ...
}
當使用者嘗試在 Crud
元件內提交表單或變更其任何欄位時,此函數會自動針對目前的值執行。
與外部 Schema 函式庫整合
validate
函數可以輕鬆地與任何遵循 Standard Schema 規格的 schema 函式庫整合,例如 zod
。
以下是使用 zod
的範例
import { z } from 'zod';
const dataSource = {
// ...
validate: z.object({
name: z
.string({ required_error: 'Name is required' })
.nonempty('Name is required'),
age: z
.number({ required_error: 'Age is required' })
.min(18, 'Age must be higher than 18'),
})['~standard'].validate,
// ...
};
資料快取
資料來源預設會快取已獲取的資料。這表示如果使用者查詢已獲取的資料,則不會再次呼叫 getMany
和 getOne
等查詢方法,以避免對伺服器進行不必要的呼叫。
成功呼叫 createOne
、updateOne
或 deleteOne
等變更方法會自動清除同一個資料來源中所有查詢的快取。
建議始終包含 dataSourceCache
屬性,以便在整個應用程式的範圍內快取資料,否則預設情況下,快取僅限於正在使用的元件的範圍。每個資料來源應該在整個應用程式中擁有自己的單一快取實例。
DataSourceCache
的實例可以用於快取,如上面的 demo 所示。DataSourceCache
是一個簡單的記憶體內快取,它將資料儲存在純物件中。
停用快取
若要停用資料來源快取,請將 null
傳遞給 dataSourceCache
屬性。
進階設定
為了獲得更大的自訂彈性,特別是如果您想要完全控制不同 CRUD 頁面的放置位置,您可以使用 List
、Show
、Create
和 Edit
子元件,而不是all-in-one 的 Crud
元件。
CrudProvider
元件是選用的,但可以用於輕鬆地將單一 dataSource
和 dataSourceCache
作為上下文傳遞給其中的 CRUD 子元件。或者,這些元件中的每一個都可以將自己的 dataSource
和 dataSourceCache
作為 props。
List
元件
顯示一個 Data Grid,列出資料來源中的項目,並支援分頁、排序和篩選,以及一些有用的控制項,例如重新整理資料。
如果為 onCreateClick
或 onEditClick
傳遞了 props,則會顯示用於觸發這些回呼的按鈕。
如果資料來源包含 deleteOne
,則可以直接從其各自的列中刪除項目。
與 Data Grid 整合
dataGrid
slot 和 slot props 可以用於將標準 Data Grid 替換為其任何 商業授權版本。
Show
元件
顯示從資料來源檢索的具有給定 id
的項目的詳細資訊。
如果為 onEditClick
傳遞了 prop,則會顯示一個用於觸發該回呼的按鈕。
如果資料來源包含 deleteOne
,則可以直接從此視圖中刪除項目。
Create
元件
顯示一個表單,用於為資料來源建立新項目,該表單會根據給定的 fields
和欄位 type
自動產生。
支援的欄位類型為 string
、number
、boolean
、date
、dateTime
和 singleSelect
。
表單驗證會自動與資料來源中的 validate
函數整合。
API
請參閱下方文件,以取得此處提及的元件可用的所有 props 和 classes 的完整參考。