**角色**: 你是一位资深前端架构师，精通 Vue 3、TypeScript 和 Vuetify 3，严格遵循 Material Design 3 设计哲学和企业级代码规范。

**任务**: 根据以下详细设计方案，创建一个名为 `CurrencySelector` 的通用、高性能、主题自适应的加密货币/交易对选择器组件。

-----

#### **1. 组件核心概述 (Component Overview)**

`CurrencySelector` 是一个基于 Vuetify 3 的高级表单控件。它旨在提供一个功能强大且用户友好的界面，用于从一个可配置的数据源中单选或多选加密货币或交易对。组件内部将封装数据加载、搜索过滤、状态管理以及复杂的UI渲染逻辑，同时对外暴露简洁、类型安全的API。

-----

#### **2. 核心技术栈与规范 (Core Tech Stack & Specifications)**

  * **框架 (Framework):** Vue 3.x
  * **脚本 (Script):** `<script setup lang="ts">` (组合式API)
  * **语言 (Language):** TypeScript (严格模式，**严禁 `any`** )
  * **UI库 (UI Library):** Vuetify 3.x
  * **状态管理 (State Management):** Pinia
  * **设计规范 (Design System):** Google Material Design 3 (MD3)
  * **强制遵循**: `vue3-typescript-stye.md` 中的所有规范。

-----

#### **3. 组件API设计 (Props & Emits)**

为了实现组件的高度可复用性和灵活性，其API必须经过精心设计，并提供完整的TypeScript类型定义。

##### **3.1 类型定义 (Type Definitions)**

首先，在 `@/types/currency.d.ts` 中定义核心数据结构：

```typescript
// @/types/currency.d.ts

/**
 * @interface CurrencyItem
 * @description 代表一个可选择的币种或交易对的基础数据结构
 */
export interface CurrencyItem {
  id: string | number;      // 唯一标识符
  name: string;             // 完整名称, e.g., "Bitcoin"
  symbol: string;           // 简称/符号, e.g., "BTC"
  pair?: string;            // 交易对名称, e.g., "BTCUSDT"
  iconUrl?: string;         // 图标的URL地址
}
```

##### **3.2 Props**

```typescript
// CurrencySelector.vue

import type { CurrencyItem } from '@/types/currency';

interface Props {
  // v-model 绑定值，支持单选或多选
  modelValue: string | number | (string | number)[] | null;

  // 选项列表数据源
  items: CurrencyItem[];

  // 是否支持多选
  multiple?: boolean;

  // 占位符文本
  placeholder?: string;

  // 是否处于加载状态
  loading?: boolean;

  // 是否禁用
  disabled?: boolean;

  // 返回对象的属性，决定了 modelValue 的值
  itemValue?: keyof CurrencyItem; // 默认为 'id'

  // 自定义清除按钮图标
  clearable?: boolean;
  clearIcon?: string;

  // 错误信息和状态
  error?: boolean;
  errorMessages?: string | string[];

  // Vuetify v-field 的 density 和 variant 属性
  density?: 'default' | 'comfortable' | 'compact';
  variant?: 'outlined' | 'filled' | 'underlined' | 'solo' | 'plain';
}

const props = withDefaults(defineProps<Props>(), {
  multiple: false,
  placeholder: '点击选择币种',
  loading: false,
  disabled: false,
  itemValue: 'id',
  clearable: true,
  density: 'compact',
  variant: 'outlined'
});
```

##### **3.3 Emits**

```typescript
// CurrencySelector.vue

const emit = defineEmits<{
  (e: 'update:modelValue', value: string | number | (string | number)[] | null): void;
}>();
```

-----

#### **4. 内部实现与架构决策 (Internal Implementation & Architecture)**

##### **4.1 基础组件选用**

  * **核心**: 使用 Vuetify 的 `VAutocomplete` 组件作为基础。它原生支持搜索、单选/多选、异步加载以及丰富的插槽，能完美满足需求。**不要手动实现下拉菜单的显示/隐藏逻辑和层级管理**，`VAutocomplete` 内置的 `v-menu` 会自动处理。

##### **4.2 UI/UX 实现细节**

  * **已选项渲染 (胶囊按钮)**:

      * 利用 `VAutocomplete` 的 `#selection` 插槽。
      * 在插槽内，使用 `VChip` 组件来渲染已选项，以实现“胶囊按钮”效果。
      * `VChip` 应包含币种图标 (`VAvatar` 或 `VIcon`)、简称 (`item.raw.symbol` 或 `item.raw.pair`)，并自带删除按钮 (`closable=true`)。
      * `VChip` 的颜色应使用主题变量，例如 `color="primary"`, 使其与输入框背景色区分。

  * **下拉选项渲染**:

      * 利用 `VAutocomplete` 的 `#item` 插槽。
      * 在插槽内，使用 `VListItem` 组件。
      * `VListItem` 包含 `VListItemAvatar` (用于图标) 和 `VListItemTitle` (用于显示简称或交易对名称)。

  * **主题适配 (Theming)**:

      * **严禁**任何硬编码的颜色值。
      * 组件所有背景、文字、边框颜色**必须**使用 Vuetify 的主题系统。例如，`VChip` 的颜色应设置为 `primary` 或 `secondary` 等主题色，输入框的背景将自动适应主题。
      * 币种图标本身是图片，无需颜色变换，符合原始要求。

  * **滚动与显示数量**:

      * `VAutocomplete` 的下拉菜单默认就是可滚动的。
      * 要控制显示高度，可以通过 CSS `var(--v-overlay-max-height)` 变量或为 `menu-props` 设置样式 `{ maxHeight: '300px' }` 来实现，而非通过参数配置固定的`n`个选项。这更符合响应式设计。

##### **4.3 逻辑与功能**

  * **搜索功能**:

      * `VAutocomplete` 自带文本搜索功能。
      * 为了更精准地匹配 `name`, `symbol`, `pair`，可以提供一个自定义的 `custom-filter` 函数。
        ```typescript
        const currencyFilter = (itemTitle: string, queryText: string, item: { raw: CurrencyItem }): boolean => {
          const query = queryText.toLowerCase();
          const { name, symbol, pair } = item.raw;
          return (
            name.toLowerCase().includes(query) ||
            symbol.toLowerCase().includes(query) ||
            (pair && pair.toLowerCase().includes(query))
          );
        };
        ```

  * **数据管理**:

      * 如果币种列表是全局共享且不常变动的，**推荐**使用 Pinia Store (`@/store/currency.ts`) 进行管理。
      * Store 应包含 state (存储列表)、getters (用于快速查找) 和 actions (用于异步获取数据并缓存)。
      * 组件在 `onMounted` 时，检查 Store 中是否已有数据，若无则 dispatch action 获取。

  * **响应式设计**:

      * 组件的尺寸不应由内部 prop 控制。应遵循 Vuetify 的栅格系统，将其放置在 `VCol` 中，由父级布局决定其宽度。这保证了组件在不同屏幕尺寸下的适应性。

-----

#### **5. 非功能性需求 (Non-Functional Requirements)**

  * **性能 (Performance)**:

      * 对于超大数据量的选项列表 (e.g., \> 1000)，应考虑使用 `VVirtualScroll` 组件包裹在下拉菜单中，以提高渲染性能。
      * 搜索输入的 debounce 由 `VAutocomplete` 内置处理。

  * **可访问性 (Accessibility - A11Y)**:

      * 通过使用 `VAutocomplete` 和 `VChip` 等标准 Vuetify 组件，大部分 WAI-ARIA 属性会自动得到支持。
      * 确保所有可交互元素都有清晰的焦点状态，并支持键盘导航。

  * **错误处理 (Error Handling)**:

      * 当 `loading` 为 `true` 时，显示 `VProgressLinear` 或 `VProgressCircular`。
      * 当 `items` 数组为空时，应在下拉菜单中显示提示信息，如“无匹配数据”。
      * 当接收到 `error` prop 时，`VAutocomplete` 边框应变为错误颜色，并显示 `error-messages`。

-----

#### **6. 示例用法 (Example Usage)**

```vue
<template>
  <v-container>
    <v-row>
      <v-col cols="12" md="6">
        <CurrencySelector
          v-model="selectedSingle"
          :items="currencyStore.list"
          :loading="currencyStore.loading"
          label="选择单个币种"
        />
      </v-col>
      <v-col cols="12" md="6">
        <CurrencySelector
          v-model="selectedMultiple"
          :items="currencyStore.list"
          :loading="currencyStore.loading"
          label="选择多个交易对"
          multiple
          placeholder="搜索并选择交易对"
        />
      </v-col>
    </v-row>
  </v-container>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { useCurrencyStore } from '@/store/currency';
import CurrencySelector from '@/components/CurrencySelector.vue';

const currencyStore = useCurrencyStore();

const selectedSingle = ref<string | null>(null);
const selectedMultiple = ref<string[]>([]);

onMounted(() => {
  currencyStore.fetchCurrencies();
});
</script>
```

-----

**最终指令**: 请根据以上这份详尽、严谨的架构设计方案，生成 `CurrencySelector.vue` 组件的完整代码。代码必须是生产级别的，并体现出卓越的工程实践。