diff --git a/claude.md b/claude.md new file mode 100644 index 0000000..e19f357 --- /dev/null +++ b/claude.md @@ -0,0 +1,254 @@ +# noob-components + +## Project Overview + +A Vue 3 component library built with TypeScript and Vite, providing reusable UI components and composables for management applications. The library extends Element Plus with custom components, layouts, and utilities. + +## Technology Stack + +- **Framework**: Vue 3 (Composition API) +- **Language**: TypeScript +- **Build Tool**: Vite +- **Base UI Library**: Element Plus +- **Styling**: SCSS with scoped styles +- **State Management**: Vuex (for consuming applications) +- **Internationalization**: vue3-i18n +- **Package Manager**: npm/bun + +## Project Structure + +``` +noob-components/ +├── packages/ +│ ├── base/ # Base UI components +│ │ ├── data/ # Data display components (ListTable, etc.) +│ │ ├── item/ # Form input components (Input, Select, DateTime, etc.) +│ │ └── layout/ # Layout components +│ ├── manage/ # Management-specific components +│ │ ├── common/ # Common components (login forms, etc.) +│ │ └── router/ # Router layout components (index.vue, zhuBeiDong.vue) +│ └── app.ts # Main export file +├── plugs/ +│ ├── composables/ # Vue composables +│ │ ├── useListTable.ts # Table data management +│ │ ├── useModifyForm.ts # Form modification logic +│ │ └── ... +│ ├── http/ # HTTP utilities and API client +│ ├── element/ # Element Plus utilities +│ └── utils/ # General utilities +├── dist/ # Build output +│ ├── noob-mengyxu.js +│ ├── noob-mengyxu.css +│ └── style.css +└── vite.config.ts # Vite configuration +``` + +## Key Components + +### Router Layouts (`packages/manage/router/`) + +Two main layout components for management applications: + +- **index.vue**: Standard layout with horizontal/vertical menu support +- **zhuBeiDong.vue**: Alternative layout with specific styling + +Both components: +- Provide app structure with header, aside, and main content areas +- Support theme switching (via `state.style`) +- Support size adjustments (via `state.size`) +- Handle user authentication checks +- Use **scoped CSS** with `:deep()` for child component styling + +### Login Components (`packages/manage/common/`) + +- **login2.vue**: Login form with vertical layout (labels above inputs) + +### Data Components (`packages/base/data/`) + +- **list-table.vue**: Table component with pagination, sorting, filtering + - Uses TypeScript interface-based props + - Integrates with `useListTable` composable + - Supports Element Plus table features + +### Form Components (`packages/base/item/`) + +- **input.vue**: Text input wrapper +- **select.vue**: Select dropdown wrapper +- **datetime.vue**: Date/time picker wrapper +- **modify-form.vue**: Form modification component + +All form components: +- Support `.full` class for 100% width +- Have default constrained width via `.form-item` +- Use scoped styles + +## Key Composables + +### useListTable (`plugs/composables/useListTable.ts`) + +Manages table data with pagination and filtering. + +**Important implementation details:** +- Uses `deepCopy(toRaw(example))` to avoid infinite reactivity loops +- Automatically manages pagination params (`page`, `size`) +- Supports both array and paginated response (`{ data: [], total: N }`) +- Has `disableAutoQuery` option to disable automatic queries + +**Interface:** +```typescript +interface TableColumn { + code: string; // Property path (supports nested like "task.name") + name?: string; // Display name + i18n?: string; // i18n key + type?: string; // Column type + width?: string | number; + fixed?: boolean | 'left' | 'right'; + align?: 'left' | 'center' | 'right'; + slot?: boolean; // Use custom slot + dict?: string; // Dictionary for value mapping + timestamp?: boolean; // Format as timestamp + filesize?: boolean; // Format as file size +} +``` + +### useModifyForm (`plugs/composables/useModifyForm.ts`) + +Manages form state for add/edit operations. + +## Styling Conventions + +### CSS Scoping + +- **Router components** (`index.vue`, `zhuBeiDong.vue`): + - Split into unscoped (for `body`) and scoped blocks + - Use `:deep()` for child components from library + - Example: `:deep(.head-icon)`, `:deep(.el-input)` + +- **Form components** (`input.vue`, `select.vue`, etc.): + - Use scoped styles + - Support `.full` class to override width + +### CSS Variables Binding + +Components use `v-bind()` to bind Vuex state to CSS: +```scss +color: v-bind("state.style.color"); +background-color: v-bind("state.style.bodyBg"); +font-size: v-bind("state.size.fontSize"); +height: v-bind("state.size.headHeight"); +``` + +### State Structure + +```typescript +state.style = { + color: string; + bodyBg: string; + headBg: string; + itemBg: string; + selectionBg: string; + selectionColor: string; +} + +state.size = { + fontSize: string; + headHeight: string; + asideWidth: string; + mainHeight: string; + tableHeight: string; + headIconSize: string; + size: 'small' | 'default' | 'large'; +} +``` + +## Build Configuration + +### Library Build (`vite.config.ts`) + +- Entry: `packages/app.ts` +- Output: `dist/noob-mengyxu.js` and `dist/noob-mengyxu.css` +- CSS is extracted separately (not injected into JS) +- Vue is externalized (peer dependency) + +### Development Workflow + +1. **Local development with linking:** + ```bash + bun link + cd ../s6a_manage + bun link noob-mengyxu + ``` + +2. **Important**: When using `bun link`, JS/templates load from source but CSS loads from `dist/` + - After CSS changes, must rebuild: `npm run build:lib` + +## Common Issues and Solutions + +### Issue: CSS Conflicts from Multiple Router Components + +**Problem**: Multiple unscoped CSS rules causing variable conflicts + +**Solution**: +- Use scoped styles with `:deep()` for child elements +- Split into unscoped (body only) and scoped blocks + +### Issue: Infinite Loop in useListTable with deepCopy + +**Problem**: `deepCopy(example)` inside `watchEffect` establishes reactive dependencies + +**Solution**: Use `deepCopy(toRaw(example))` for deep non-reactive clone + +### Issue: Form Input Width Issues + +**Problem**: `.form-item` class collision between components + +**Solution**: +- Add `.full { width: 100%; }` to base components +- Remove conflicting styles from router components +- Use `:deep()` when needed to style library components + +### Issue: Header Icons Not Styled + +**Problem**: After scoping, library components don't have scoped attribute + +**Solution**: Change `.head-icon` to `:deep(.head-icon)` in router components + +## TypeScript Conventions + +- Use interface-based prop definitions: `defineProps()` +- Use `withDefaults()` for default values +- Prefer `undefined` over `null` for optional props (simplifies types) +- Use `() => []` or `() => ({})` for array/object defaults + +## Exports + +Main export file: `packages/app.ts` + +Exports are organized into modules: +- `Element`: Element Plus utilities +- `NoobHead`: Header components +- `NoobInput`, `NoobButton`, etc.: Form components +- `ListTable`, `ModifyForm`: Data components +- `Api`: HTTP client +- `Styles`, `Size`: Theme utilities +- Composables: `useListTable`, `useModifyForm`, etc. + +## Recent Changes + +1. **TypeScript Conversion**: Converted list-table.vue to interface-based props +2. **CSS Scoping**: Fixed conflicts by scoping router component styles +3. **Reactivity Fix**: Changed to `deepCopy(toRaw(example))` in useListTable +4. **Form Layout**: Fixed login form to use vertical layout (labels above inputs) +5. **Pagination**: Fixed handling of paginated responses `{ data: [], total: N }` + +## Dependencies + +Key dependencies: +- `vue`: ^3.x +- `element-plus`: UI library +- `vue3-i18n`: Internationalization +- `vuex`: State management (for consumers) +- `axios`: HTTP client +- `js-md5`: Password hashing +- `@vueuse/core`: Vue utilities +- `lodash-es`: Utility functions