import {Meta} from '@storybook/addon-docs/blocks'

<Meta title='@dxtmisha/vi/functional/Classes/DesignComponents - Trình quản lý thành phần cơ sở'/>

# Lớp DesignComponents

Lớp cơ sở để làm việc với các thành phần kết nối (connected components) và quản lý logic render của chúng trong hệ thống thiết kế. Nó cho phép đăng ký thành phần, sửa đổi các thuộc tính mặc định và tạo VNode một cách linh hoạt.

## Các tính năng chính

- **Quản lý thành phần** — đăng ký và truy xuất các thành phần Vue một cách tập trung.
- **Sửa đổi động** — hỗ trợ áp dụng các sửa đổi thuộc tính toàn cục hoặc cụ thể cho các thành phần trước khi render.
- **Render linh hoạt** — cung cấp nhiều phương thức (`render`, `renderOne`, `renderAdd`) để tạo Vue VNode với tính năng tự động liên kết thuộc tính (binding).
- **Tối ưu hóa hiệu suất** — sử dụng bộ nhớ đệm nội bộ với các thuộc tính `computed` của Vue cho các sửa đổi thuộc tính.

## Khởi tạo

Tạo một thực thể `DesignComponents` mới. Lớp này kết hợp các thành phần và các sửa đổi của chúng vào một cơ chế quản lý hiển thị duy nhất.

### Ràng buộc Generic (Generic Constraints)

Lớp này sử dụng các generic để đảm bảo cấu hình kiểu render linh hoạt:
- `COMP extends ConstrComponent` — Một đối tượng chứa danh sách các thành phần có sẵn. Xác định cấu trúc mà `DesignComponents` sẽ sử dụng để tìm kiếm và trả về các thành phần để render.
- `P extends ConstrItem` — Kiểu thuộc tính (props) được sử dụng để định kiểu cho các sửa đổi và dữ liệu được truyền trong quá trình render.

**Tham số:**
- `components: COMP = {}` — danh sách các thành phần được kết nối (một đối tượng trong đó khóa là tên và giá trị là các thành phần Vue).
- `modification?: ConstrComponentMod<P>` — một đối tượng sửa đổi cho phép ghi đè các thuộc tính (props) cho mỗi thành phần.

```typescript
import { DesignComponents } from '@dxtmisha/functional'
import MyButton from './MyButton.vue'
import MyInput from './MyInput.vue'

// 1. Đăng ký thành phần
const components = {
  button: MyButton,
  input: MyInput
}

// 2. Xác định các sửa đổi (props mặc định)
const modification = {
  button: { size: 'large', color: 'primary' },
  input: { focus: true }
}

const design = new DesignComponents(components, modification)
```


## Các phương thức Render

### `render`

Render một thành phần theo tên và trả về một mảng chứa một `VNode` duy nhất. Điều này hữu ích cho Vue, nơi thường yêu cầu các mảng nút.

**Tham số:**
- `name: string` — Tên của thành phần đã đăng ký.
- `props: object` — Các thuộc tính được truyền cho thành phần.
- `children: any` — Các phần tử con hoặc slot của thành phần.
- `index: string` — Khóa (key) cho VNode.

**Trả về:** `VNode[]` — Một mảng chứa VNode đã được tạo.

### `renderOne`

Render một thành phần duy nhất và trả về đối tượng `VNode` trực tiếp. Nếu không tìm thấy thành phần, nó sẽ trả về `undefined`.

**Tham số:**
- `name: string` — Tên của thành phần đã đăng ký.
- `props: object` — Các thuộc tính cho thành phần.
- `children: any` — Các phần tử con của thành phần.
- `index: string` — Khóa (key) cho VNode.

**Trả về:** `VNode | undefined` — Đối tượng VNode hoặc `undefined`.

### `renderAdd`

Render một thành phần và đẩy `VNode` kết quả vào một mảng được cung cấp. Điều này cho phép thu thập nhiều nút trong một lần thực thi.

**Tham số:**
- `item: any[]` — Mảng mà kết quả render sẽ được thêm vào.
- `name: string` — Tên của thành phần.
- `props: object` — Các thuộc tính cho thành phần.
- `children: any` — Các phần tử con của thành phần.
- `index: string` — Khóa (key) cho VNode.

**Trả về:** `this` — Một tham chiếu đến instance hiện tại để thực hiện chuỗi lệnh (chaining).

## Các phương thức bổ sung

- `is(name: string): boolean` — Kiểm tra xem một thành phần có được đăng ký hay không.
- `get(name: string): COMP[K]` — Trả về đối tượng thành phần đã đăng ký theo tên.
- `getModification(index?: string, props?: object): object | undefined` — Trả về dữ liệu đầu vào đã sửa đổi cho các thành phần kết nối.
