This commit introduces the foundational structure and core features for the item management application. Key features implemented: - **Item Listing:** A main page displaying all items in a searchable UTable. - **Item Creation:** An "Add Item" modal with a UForm for input and validation using Zod. - **State Management:** A `useItemsStore` composable built with `@vueuse/core`'s `useLocalStorage` to persist item data in the browser. - **UI Framework:** Integrated Nuxt UI for components like tables, modals, forms, and the overall layout. - **Application Shell:** Established a default layout with a header, navigation menu, and placeholders for Export and History pages. - **Project Setup:** Configured pnpm workspace, Tailwind CSS, and VSCode editor settings for an improved development experience.
62 lines
1.6 KiB
TypeScript
62 lines
1.6 KiB
TypeScript
import { useLocalStorage, createSharedComposable } from "@vueuse/core";
|
|
|
|
// 类型定义
|
|
export type Item = {
|
|
id: number;
|
|
name: string;
|
|
imageUrl?: string | null;
|
|
description?: string | null;
|
|
tags?: string[] | null;
|
|
createdAt: Date;
|
|
updatedAt: Date;
|
|
};
|
|
|
|
const _useItems = () => {
|
|
const items = useLocalStorage<Item[]>("item-database", [], {
|
|
serializer: {
|
|
read: (v) => {
|
|
const parsed = JSON.parse(v);
|
|
return parsed.map((item: any) => ({
|
|
...item,
|
|
createdAt: new Date(item.createdAt),
|
|
updatedAt: new Date(item.updatedAt),
|
|
}));
|
|
},
|
|
write: (v) => JSON.stringify(v),
|
|
},
|
|
});
|
|
|
|
const stats = {
|
|
totalItems: computed(() => items.value.length),
|
|
addedThisMonth: computed(() => {
|
|
const now = new Date();
|
|
const thisMonth = now.getMonth();
|
|
const thisYear = now.getFullYear();
|
|
|
|
let count = 0;
|
|
for (const item of items.value) {
|
|
const date = item.createdAt;
|
|
if (date.getMonth() === thisMonth && date.getFullYear() === thisYear) {
|
|
count++;
|
|
}
|
|
}
|
|
return count;
|
|
}),
|
|
latestId: computed(
|
|
() => (items.value[items.value.length - 1]?.id ?? 0) + 1
|
|
),
|
|
};
|
|
|
|
const isNameAvailable = (name: string) =>
|
|
!items.value.some((item) => item.name === name);
|
|
|
|
const addItem = (item: Item) => items.value.push(item);
|
|
|
|
const removeItem = (id: number) =>
|
|
(items.value = items.value.filter((i) => i.id !== id));
|
|
|
|
return { items, stats, isNameAvailable, addItem, removeItem };
|
|
};
|
|
|
|
export const useItemsStore = createSharedComposable(_useItems);
|