# ZnIcon 字体图标组件封装计划

## Summary

基于项目现有字体映射表 [znicons.js](file:///d:/www/znkj/nianxx-h5/src/assets/fonts/znicons.js)，结合 Tailwind CSS 的 class 体系，补齐并统一封装字体图标组件 `ZnIcon`：

- 新增可复用组件：`src/components/ZnIcon/index.vue`
- 统一字体加载：在全局样式中声明 `@font-face`（字体源使用 `src/assets/fonts/znicons.ttf`）
- 增加兼容层：补齐 `@/assets/fonts/znicons` 的历史导入路径，避免逐文件改动才能编译
- 输出后续替换路径与校验方式

## Current State Analysis（以仓库为准）

- 字体映射表存在：`src/assets/fonts/znicons.js`
- 字体文件存在：`src/assets/fonts/znicons.ttf`
- 组件骨架存在但为空：`src/components/ZnIcon/index.vue`（0 行）
- 业务中大量使用 `<uni-icons fontFamily="znicons">` + `iconsMap[...]` 的方式展示字体图标，并且存在历史路径导入：
  - `import { iconsMap } from "@/static/fonts/znicons(.js)"`（仓库内当前没有 `src/static/`）
- 多处样式中通过 `@font-face` 引用 `@/static/fonts/znicons.ttf`，但仓库内无该字体路径，导致字体加载不稳定：
  - `src/components/ImageSwiper/styles/index.scss`
  - `src/components/GoodDetail/index.vue`
  - `src/pages/goods/components/GoodFacility/index.vue`
  - `src/pages/login/index.vue`

## Assumptions & Decisions（已确认）

- 改动范围：兼容层优先（先把组件 + 兼容路径落地；业务替换后续逐步做）
- 组件 API：props 为主（同时允许 class 传入 Tailwind 样式覆盖）
- 字体资源路径：统一以 `src/assets/fonts/znicons.ttf` 为唯一来源

## Proposed Changes

### 1) 实现 `ZnIcon` 组件

文件：`src/components/ZnIcon/index.vue`

#### 组件目标

- 以 `name`（映射 key）渲染对应字体图标字符
- 支持 size/color 作为 props（便于统一口径）
- 支持传入 `class` 使用 Tailwind 控制颜色、间距、对齐等；默认采用 `inline-flex` + `leading-none`

#### Props 设计（建议）

- `name: string`（必填；对应 `iconsMap` 的 key）
- `size?: number | string`（默认 16；number 按 px 处理，string 原样写入）
- `color?: string`（可选；不传则使用 `currentColor`，便于 Tailwind `text-*` 控制）
- `title?: string`（可选；用于无障碍/tooltip）

#### 渲染与样式策略

- 渲染元素：`<span>`（默认 `aria-hidden`，若传 title 则补充可访问属性）
- `style`：
  - `fontFamily: "znicons"`
  - `fontSize`：来自 `size`
  - `color`：仅当传入 `color` 时设置，否则依赖 `currentColor`
- `class`：默认 `inline-flex items-center justify-center leading-none select-none`，并合并用户传入 class

### 2) 全局声明 znicons 字体（统一入口）

文件：`src/styles/main.css`

新增 `@font-face`（放在文件较靠前位置，确保早加载）：

- `font-family: znicons;`
- `src: url("@/assets/fonts/znicons.ttf") format("truetype");`
- `font-display: swap;`

说明：

- 项目入口已在 `src/main.ts` 引入 `@/styles/main.css`，无需额外引入步骤

### 3) 增加历史导入路径兼容层（不改业务代码也能编译）

新增文件：`src/assets/fonts/znicons.js`

- 仅做 re-export：`export { iconsMap } from "@/assets/fonts/znicons"`

说明：

- 这一步用于兼容现有 `@/static/fonts/znicons(.js)` 的导入，减少“全仓替换 import 路径”的一次性风险

### 4) 修正历史字体路径引用（从 static 统一到 assets）

将以下文件中的字体引用路径：

- 从 `@/static/fonts/znicons.ttf`
- 改为 `@/assets/fonts/znicons.ttf`

涉及文件（基于当前扫描结果）：

- `src/components/ImageSwiper/styles/index.scss`
- `src/components/GoodDetail/index.vue`
- `src/pages/goods/components/GoodFacility/index.vue`
- `src/pages/login/index.vue`

注：

- 只做路径替换，不改动组件业务逻辑
- 保留重复的 `@font-face` 也不影响功能，但建议后续逐步移除重复声明，最终只保留全局 `main.css` 的一处定义

## Verification

实现完成后手动执行：

- `yarn typecheck`
- `yarn build`

验收标准：

- `ZnIcon` 组件可在任一页面按 props 正常渲染图标
- 字体在浏览器中可加载成功（Network 中能看到 `znicons.ttf`）
- 现有 `@/static/fonts/znicons` 导入不再报错（由兼容层兜底）
