docs: 添加 API 文档和组件速查表
- 新增 docs/api-docs/README.md(API 文档缓存说明) - 新增 docs/api-docs/常用组件速查表.md(组件使用速查) - 更新 .claude/settings.local.json(权限配置) --- **详细信息**: - **影响文件**: .claude/settings.local.json, docs/api-docs/README.md, docs/api-docs/常用组件速查表.md - **技术栈**: 文档 - **测试状态**: N/A - **备注**: 提供 Taro 和 NutUI 文档缓存方案及常用组件使用示例 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Showing
3 changed files
with
733 additions
and
1 deletions
| ... | @@ -78,7 +78,12 @@ | ... | @@ -78,7 +78,12 @@ |
| 78 | "Bash(__NEW_LINE_b32968d45b3e16a9__ python3 /tmp/update-imports.py)", | 78 | "Bash(__NEW_LINE_b32968d45b3e16a9__ python3 /tmp/update-imports.py)", |
| 79 | "Bash(/Users/huyirui/program/itomix/git/manulife-weapp/docs/reports/2026-02-09/components-cleanup-report.md <<'EOF'\n\n---\n\n## ✅ 执行结果(2026-02-09)\n\n### 已完成的清理和重组\n\n#### 阶段 1: 清理未使用组件 ✅\n- ✅ 删除 `qrCode.vue` \\(11KB\\)\n- ✅ 删除 `FilterTabs.example.vue`\n- ✅ 删除 `PlanPopup/` 目录(旧版本)\n\n#### 阶段 2: 组件目录重组 ✅\n\n**创建的分类目录**:\n1. `navigation/` - 导航组件\n2. `list/` - 列表组件\n3. `forms/` - 表单组件\n4. `cards/` - 卡片组件\n5. `documents/` - 文档相关组件\n6. `plan/` - 计划书相关组件\n7. `icons/` - 图标组件\n\n**组件迁移清单**:\n```\nnavigation/\n├── TabBar.vue\n└── NavHeader.vue\n\nlist/\n├── ListItemActions/\n├── LoadMoreList/\n├── SectionCard.vue\n└── SectionItem.vue\n\nforms/\n├── FilterTabs.vue\n└── SearchBar.vue\n\ncards/\n├── MaterialCard.vue\n└── ProductCard.vue\n\ndocuments/\n├── DocumentPreview/\n├── OfficeViewer.vue\n└── PdfPreview.vue\n\nplan/\n├── PlanFields/\n├── PlanFormContainer.vue\n├── PlanPopupNew.vue\n└── PlanTemplates/\n\nicons/\n└── IconFont.vue\n```\n\n**路径更新统计**:\n- 更新文件数:38 个\n- 更新类型:import 语句\n- 更新范围:src/pages/, src/components/\n- 验证结果:✅ 通过(0 errors, 30 warnings)\n\n### 📊 最终收益\n\n**代码质量**:\n- ✅ 删除 3 个未使用组件(约 11KB)\n- ✅ 组件按功能分类,结构清晰\n- ✅ 所有引用路径已更新\n- ✅ 代码检查通过(0 errors)\n\n**可维护性**:\n- ✅ 组件查找更快速\n- ✅ 功能边界更明确\n- ✅ 为未来组件扩展预留空间\n- ✅ 符合项目架构原则\n\n**文档更新**:\n- ✅ CHANGELOG.md 已更新\n- ✅ 本报告已创建\n\n---\n\n**执行时间**: 2026-02-09\n**执行状态**: ✅ 完成\n**下一步**: 可以继续优化组件内部实现,或清理其他未使用代码\nEOF)", | 79 | "Bash(/Users/huyirui/program/itomix/git/manulife-weapp/docs/reports/2026-02-09/components-cleanup-report.md <<'EOF'\n\n---\n\n## ✅ 执行结果(2026-02-09)\n\n### 已完成的清理和重组\n\n#### 阶段 1: 清理未使用组件 ✅\n- ✅ 删除 `qrCode.vue` \\(11KB\\)\n- ✅ 删除 `FilterTabs.example.vue`\n- ✅ 删除 `PlanPopup/` 目录(旧版本)\n\n#### 阶段 2: 组件目录重组 ✅\n\n**创建的分类目录**:\n1. `navigation/` - 导航组件\n2. `list/` - 列表组件\n3. `forms/` - 表单组件\n4. `cards/` - 卡片组件\n5. `documents/` - 文档相关组件\n6. `plan/` - 计划书相关组件\n7. `icons/` - 图标组件\n\n**组件迁移清单**:\n```\nnavigation/\n├── TabBar.vue\n└── NavHeader.vue\n\nlist/\n├── ListItemActions/\n├── LoadMoreList/\n├── SectionCard.vue\n└── SectionItem.vue\n\nforms/\n├── FilterTabs.vue\n└── SearchBar.vue\n\ncards/\n├── MaterialCard.vue\n└── ProductCard.vue\n\ndocuments/\n├── DocumentPreview/\n├── OfficeViewer.vue\n└── PdfPreview.vue\n\nplan/\n├── PlanFields/\n├── PlanFormContainer.vue\n├── PlanPopupNew.vue\n└── PlanTemplates/\n\nicons/\n└── IconFont.vue\n```\n\n**路径更新统计**:\n- 更新文件数:38 个\n- 更新类型:import 语句\n- 更新范围:src/pages/, src/components/\n- 验证结果:✅ 通过(0 errors, 30 warnings)\n\n### 📊 最终收益\n\n**代码质量**:\n- ✅ 删除 3 个未使用组件(约 11KB)\n- ✅ 组件按功能分类,结构清晰\n- ✅ 所有引用路径已更新\n- ✅ 代码检查通过(0 errors)\n\n**可维护性**:\n- ✅ 组件查找更快速\n- ✅ 功能边界更明确\n- ✅ 为未来组件扩展预留空间\n- ✅ 符合项目架构原则\n\n**文档更新**:\n- ✅ CHANGELOG.md 已更新\n- ✅ 本报告已创建\n\n---\n\n**执行时间**: 2026-02-09\n**执行状态**: ✅ 完成\n**下一步**: 可以继续优化组件内部实现,或清理其他未使用代码\nEOF)", |
| 80 | "Bash(tail:*)", | 80 | "Bash(tail:*)", |
| 81 | - "Bash(pnpm build:weapp:*)" | 81 | + "Bash(pnpm build:weapp:*)", |
| 82 | + "Bash(pnpm view:*)", | ||
| 83 | + "Bash(pnpm update:*)", | ||
| 84 | + "Bash(open:*)", | ||
| 85 | + "Bash(awk:*)", | ||
| 86 | + "Bash(else)" | ||
| 82 | ] | 87 | ] |
| 83 | }, | 88 | }, |
| 84 | "enableAllProjectMcpServers": true, | 89 | "enableAllProjectMcpServers": true, | ... | ... |
docs/api-docs/README.md
0 → 100644
| 1 | +# API 文档缓存 | ||
| 2 | + | ||
| 3 | +本目录用于缓存 Taro 和 NutUI 的核心文档,方便离线查询。 | ||
| 4 | + | ||
| 5 | +## 📚 在线文档 | ||
| 6 | + | ||
| 7 | +### Taro 官方文档 | ||
| 8 | +- **Taro 官网**: https://docs.taro.zone/ | ||
| 9 | +- **Taro Vue 3**: https://docs.taro.zone/docs/vue3 | ||
| 10 | +- **Taro 组件**: https://docs.taro.zone/docs/components | ||
| 11 | +- **Taro API**: https://docs.taro.zone/docs/apis | ||
| 12 | +- **Taro 最佳实践**: https://docs.taro.zone/docs/best-practices | ||
| 13 | + | ||
| 14 | +### NutUI 官方文档 | ||
| 15 | +- **NutUI 官网**: https://nutui.jd.com/h5/#/ | ||
| 16 | +- **NutUI Taro 版本**: https://nutui.jd.com/taro/ | ||
| 17 | +- **NutUI 组件列表**: https://nutui.jd.com/taro/component.html | ||
| 18 | + | ||
| 19 | +## 🔧 本地缓存方案 | ||
| 20 | + | ||
| 21 | +### 方案 1: 使用文档工具(推荐) | ||
| 22 | + | ||
| 23 | +#### DevDocs | ||
| 24 | +```bash | ||
| 25 | +# 安装 DevDocs(macOS) | ||
| 26 | +brew install devdocs | ||
| 27 | + | ||
| 28 | +# 启动服务 | ||
| 29 | +devdocs | ||
| 30 | + | ||
| 31 | +# 在浏览器访问 | ||
| 32 | +open http://localhost:9292 | ||
| 33 | +``` | ||
| 34 | + | ||
| 35 | +#### Zeal(Windows/Linux) | ||
| 36 | +- 下载地址: https://zealuser.com/downloads/ | ||
| 37 | + | ||
| 38 | +### 方案 2: 离线文档网页 | ||
| 39 | + | ||
| 40 | +#### Taro PDF 文档 | ||
| 41 | +```bash | ||
| 42 | +# 创建 docs/pdf 目录 | ||
| 43 | +mkdir -p pdf | ||
| 44 | + | ||
| 45 | +# 下载 Taro Vue 3 PDF(如果官方提供) | ||
| 46 | +# 从 https://docs.taro.zone/ 下载 | ||
| 47 | +``` | ||
| 48 | + | ||
| 49 | +#### 使用 wget 镜像整个站点 | ||
| 50 | +```bash | ||
| 51 | +# 镜像 Taro 文档(仅用于学习) | ||
| 52 | +wget \ | ||
| 53 | + --recursive \ | ||
| 54 | + --no-clobber \ | ||
| 55 | + --page-requisites \ | ||
| 56 | + --html-extension \ | ||
| 57 | + --convert-links \ | ||
| 58 | + --restrict-file-names=windows \ | ||
| 59 | + --domains docs.taro.zone \ | ||
| 60 | + --no-parent \ | ||
| 61 | + docs.taro.zone/docs/vue3 | ||
| 62 | + | ||
| 63 | +# 镜像 NutUI 文档 | ||
| 64 | +wget \ | ||
| 65 | + --recursive \ | ||
| 66 | + --no-clobber \ | ||
| 67 | + --page-requisites \ | ||
| 68 | + --html-extension \ | ||
| 69 | + --convert-links \ | ||
| 70 | + --restrict-file-names=windows \ | ||
| 71 | + --domains nutui.jd.com \ | ||
| 72 | + --no-parent \ | ||
| 73 | + nutui.jd.com/taro/ | ||
| 74 | +``` | ||
| 75 | + | ||
| 76 | +### 方案 3: 创建常用组件速查表 | ||
| 77 | + | ||
| 78 | +在项目中维护常用的组件使用示例,例如: | ||
| 79 | + | ||
| 80 | +#### nut-button 常用用法 | ||
| 81 | + | ||
| 82 | +```vue | ||
| 83 | +<!-- 基础按钮 --> | ||
| 84 | +<nut-button type="primary">主要按钮</nut-button> | ||
| 85 | + | ||
| 86 | +<!-- 次要按钮(描边) --> | ||
| 87 | +<nut-button plain type="primary">次要按钮</nut-button> | ||
| 88 | + | ||
| 89 | +<!-- 独占一行 --> | ||
| 90 | +<nut-button type="primary" block>独占一行</nut-button> | ||
| 91 | + | ||
| 92 | +<!-- 自定义样式 --> | ||
| 93 | +<nut-button | ||
| 94 | + type="primary" | ||
| 95 | + color="#2563EB" | ||
| 96 | + class="!h-[88rpx] !rounded-[16rpx] !text-[30rpx]" | ||
| 97 | +> | ||
| 98 | + 自定义样式 | ||
| 99 | +</nut-button> | ||
| 100 | + | ||
| 101 | +### 方案 4: 使用 VSCode 插件 | ||
| 102 | + | ||
| 103 | +推荐安装以下插件: | ||
| 104 | + | ||
| 105 | +1. **Taro Snippets** | ||
| 106 | + - 提供 Taro 代码片段 | ||
| 107 | + - 自动补全组件和 API | ||
| 108 | + | ||
| 109 | +2. **Vue 3 Snippets** | ||
| 110 | + - Vue 3 代码片段 | ||
| 111 | + | ||
| 112 | +3. **Inline HTML** | ||
| 113 | + - 直接在编辑器中预览 HTML/CSS | ||
| 114 | + | ||
| 115 | +## 📝 常用属性速查 | ||
| 116 | + | ||
| 117 | +### nut-button 常用属性 | ||
| 118 | + | ||
| 119 | +| 属性 | 说明 | 类型 | 默认值 | | ||
| 120 | +|------|------|------|--------| | ||
| 121 | +| type | 类型 | `'default' \| 'primary' \| 'info' \| 'success' \| 'warning' \| 'danger' \| 'light'` | `'default'` | | ||
| 122 | +| size | 大小 | `'large' \| 'normal' \| 'small' \| 'mini'` | `'normal'` | | ||
| 123 | +| plain | 是否为描边按钮 | `boolean` | `false` | | ||
| 124 | +| block | 是否为块级按钮(独占一行) | `boolean` | `false` | | ||
| 125 | +| color | 自定义颜色 | `string` | - | | ||
| 126 | +| disabled | 是否禁用 | `boolean` | `false` | | ||
| 127 | +| loading | 是否加载中 | `boolean` | `false` | | ||
| 128 | + | ||
| 129 | +### nut-popup 常用属性 | ||
| 130 | + | ||
| 131 | +| 属性 | 说明 | 类型 | 默认值 | | ||
| 132 | +|------|------|------|--------| | ||
| 133 | +| visible | 是否显示 | `boolean` | `false` | | ||
| 134 | +| position | 弹出位置 | `'top' \| 'right' \| 'bottom' \| 'left' \| 'center'` | `'center'` | | ||
| 135 | +| round | 是否圆角 | `boolean` | `false` | | ||
| 136 | +| close-on-click-overlay | 点击遮罩是否关闭 | `boolean` | `true` | | ||
| 137 | +| safe-area-inset-bottom | 是否适配底部安全区 | `boolean` | `false` | | ||
| 138 | + | ||
| 139 | +## 🚀 快速查询 | ||
| 140 | + | ||
| 141 | +### grep 搜索现有用法 | ||
| 142 | + | ||
| 143 | +```bash | ||
| 144 | +# 搜索 nut-button 的用法 | ||
| 145 | +grep -r "nut-button" src/ --include="*.vue" -A 3 -B 1 | ||
| 146 | + | ||
| 147 | +# 搜索 nut-popup 的用法 | ||
| 148 | +grep -r "nut-popup" src/ --include="*.vue" -A 5 -B 1 | ||
| 149 | + | ||
| 150 | +# 搜索 TailwindCSS 类名 | ||
| 151 | +grep -r "!h-\[88rpx\]" src/ --include="*.vue" | ||
| 152 | + | ||
| 153 | +# 搜索特定的样式模式 | ||
| 154 | +grep -r "flex-1.*gap-3" src/ --include="*.vue" | ||
| 155 | +``` | ||
| 156 | + | ||
| 157 | +### 提取组件使用示例 | ||
| 158 | + | ||
| 159 | +从现有代码中提取常用模式: | ||
| 160 | + | ||
| 161 | +```bash | ||
| 162 | +# 查找所有按钮样式 | ||
| 163 | +grep -r "nut-button" src/components/plan/ -A 10 | ||
| 164 | + | ||
| 165 | +# 查找所有弹窗配置 | ||
| 166 | +grep -r "PlanPopupNew" src/ -A 5 -B 5 | ||
| 167 | +``` | ||
| 168 | + | ||
| 169 | +## 💡 最佳实践 | ||
| 170 | + | ||
| 171 | +1. **查文档优先**:遇到不熟悉的组件,先查官方文档 | ||
| 172 | +2. **搜索现有代码**:项目中可能有类似的用法 | ||
| 173 | +3. **记录常用模式**:将常用代码片段保存到文档 | ||
| 174 | +4. **使用类型提示**:TypeScript 可以提示可用的属性 | ||
| 175 | + | ||
| 176 | +## 📚 推荐学习资源 | ||
| 177 | + | ||
| 178 | +- [Taro 官方示例](https://docs.taro.zone/docs/tutorial) | ||
| 179 | +- [NutUI 组件示例](https://nutui.jd.com/taro/demos.html) | ||
| 180 | +- [Vue 3 官方文档](https://cn.vuejs.org/) | ||
| 181 | +- [TailwindCSS 文档](https://tailwindcss.com/docs) | ||
| 182 | + | ||
| 183 | +## 🔄 文档更新 | ||
| 184 | + | ||
| 185 | +记录文档更新时间,方便追踪: | ||
| 186 | + | ||
| 187 | +- **Taro 版本**: 4.1.11 | ||
| 188 | +- **NutUI 版本**: 4.3.14 | ||
| 189 | +- **最后更新**: 2026-02-10 |
docs/api-docs/常用组件速查表.md
0 → 100644
| 1 | +# 常用组件速查表 | ||
| 2 | + | ||
| 3 | +本文件记录项目中常用的组件使用模式,方便快速查找和复制。 | ||
| 4 | + | ||
| 5 | +## nut-button | ||
| 6 | + | ||
| 7 | +### 基础用法 | ||
| 8 | + | ||
| 9 | +```vue | ||
| 10 | +<!-- 主要按钮 --> | ||
| 11 | +<nut-button type="primary">确定</nut-button> | ||
| 12 | + | ||
| 13 | +<!-- 次要按钮(描边) --> | ||
| 14 | +<nut-button plain type="primary">取消</nut-button> | ||
| 15 | + | ||
| 16 | +<!-- 独占一行 --> | ||
| 17 | +<nut-button type="primary" block>确定</nut-button> | ||
| 18 | + | ||
| 19 | +<!-- 禁用状态 --> | ||
| 20 | +<nut-button disabled>禁用</nut-button> | ||
| 21 | + | ||
| 22 | +<!-- 加载中 --> | ||
| 23 | +<nut-button loading>提交中...</nut-button> | ||
| 24 | +``` | ||
| 25 | + | ||
| 26 | +### 自定义样式(项目常用) | ||
| 27 | + | ||
| 28 | +```vue | ||
| 29 | +<!-- 双按钮并排(取消 + 主要操作) --> | ||
| 30 | +<div class="flex gap-3 w-full"> | ||
| 31 | + <nut-button | ||
| 32 | + plain | ||
| 33 | + type="primary" | ||
| 34 | + class="flex-1 !h-[88rpx] !rounded-[16rpx] !text-[30rpx] !border-blue-600" | ||
| 35 | + > | ||
| 36 | + 取消 | ||
| 37 | + </nut-button> | ||
| 38 | + <nut-button | ||
| 39 | + type="primary" | ||
| 40 | + color="#2563EB" | ||
| 41 | + class="flex-1 !h-[88rpx] !rounded-[16rpx] !text-[30rpx]" | ||
| 42 | + > | ||
| 43 | + 确定 | ||
| 44 | + </nut-button> | ||
| 45 | +</div> | ||
| 46 | + | ||
| 47 | +<!-- 单按钮独占一行 --> | ||
| 48 | +<nut-button | ||
| 49 | + type="primary" | ||
| 50 | + color="#2563EB" | ||
| 51 | + block | ||
| 52 | + class="!h-[88rpx] !rounded-[16rpx] !text-[30rpx]" | ||
| 53 | +> | ||
| 54 | + 确定 | ||
| 55 | +</nut-button> | ||
| 56 | + | ||
| 57 | +<!-- 灰色关闭按钮 --> | ||
| 58 | +<nut-button | ||
| 59 | + type="primary" | ||
| 60 | + color="#9CA3AF" | ||
| 61 | + block | ||
| 62 | + class="!h-[88rpx] !rounded-[16rpx] !text-[30rpx]" | ||
| 63 | +> | ||
| 64 | + 关闭 | ||
| 65 | +</nut-button> | ||
| 66 | +``` | ||
| 67 | + | ||
| 68 | +## nut-popup | ||
| 69 | + | ||
| 70 | +### 基础用法 | ||
| 71 | + | ||
| 72 | +```vue | ||
| 73 | +<template> | ||
| 74 | + <nut-popup | ||
| 75 | + :visible="visible" | ||
| 76 | + position="bottom" | ||
| 77 | + round | ||
| 78 | + @update:visible="handleVisibleChange" | ||
| 79 | + > | ||
| 80 | + <div>弹窗内容</div> | ||
| 81 | + </nut-popup> | ||
| 82 | +</template> | ||
| 83 | + | ||
| 84 | +<script setup> | ||
| 85 | +import { ref } from 'vue' | ||
| 86 | + | ||
| 87 | +const visible = ref(false) | ||
| 88 | + | ||
| 89 | +const handleVisibleChange = (value) => { | ||
| 90 | + visible.value = value | ||
| 91 | +} | ||
| 92 | +</script> | ||
| 93 | +``` | ||
| 94 | + | ||
| 95 | +### 项目常用配置 | ||
| 96 | + | ||
| 97 | +```vue | ||
| 98 | +<nut-popup | ||
| 99 | + :visible="visible" | ||
| 100 | + position="bottom" | ||
| 101 | + round | ||
| 102 | + :style="{ height: '90%' }" | ||
| 103 | + :close-on-click-overlay="true" | ||
| 104 | + :safe-area-inset-bottom="true" | ||
| 105 | + @update:visible="handleVisibleChange" | ||
| 106 | +> | ||
| 107 | + <div class="h-full flex flex-col bg-gray-50 overflow-hidden rounded-t-2xl"> | ||
| 108 | + <!-- Header --> | ||
| 109 | + <div class="flex justify-between items-center px-5 py-4 bg-white border-b border-gray-100 flex-shrink-0"> | ||
| 110 | + <span class="text-lg font-bold text-gray-900">标题</span> | ||
| 111 | + <div class="p-2 -mr-2" @click="handleClose"> | ||
| 112 | + <IconFont name="close" size="16" color="#9CA3AF" /> | ||
| 113 | + </div> | ||
| 114 | + </div> | ||
| 115 | + | ||
| 116 | + <!-- Scrollable Content --> | ||
| 117 | + <div class="flex-1 overflow-y-auto p-4"> | ||
| 118 | + <div class="bg-white rounded-xl p-5 shadow-sm"> | ||
| 119 | + 内容 | ||
| 120 | + </div> | ||
| 121 | + </div> | ||
| 122 | + | ||
| 123 | + <!-- Footer Buttons --> | ||
| 124 | + <div class="p-4 bg-white border-t border-gray-100 flex gap-3 flex-shrink-0 pb-safe"> | ||
| 125 | + <nut-button | ||
| 126 | + plain | ||
| 127 | + type="primary" | ||
| 128 | + class="flex-1 !h-[88rpx] !rounded-[16rpx] !text-[30rpx]" | ||
| 129 | + @click="handleClose" | ||
| 130 | + > | ||
| 131 | + 取消 | ||
| 132 | + </nut-button> | ||
| 133 | + <nut-button | ||
| 134 | + type="primary" | ||
| 135 | + color="#2563EB" | ||
| 136 | + class="flex-1 !h-[88rpx] !rounded-[16rpx] !text-[30rpx]" | ||
| 137 | + @click="handleSubmit" | ||
| 138 | + > | ||
| 139 | + 确定 | ||
| 140 | + </nut-button> | ||
| 141 | + </div> | ||
| 142 | + </div> | ||
| 143 | +</nut-popup> | ||
| 144 | +``` | ||
| 145 | + | ||
| 146 | +## nut-tabs | ||
| 147 | + | ||
| 148 | +### 基础用法 | ||
| 149 | + | ||
| 150 | +```vue | ||
| 151 | +<nut-tabs v-model="activeTab"> | ||
| 152 | + <nut-tab-pane title="标签1">内容1</nut-tab-pane> | ||
| 153 | + <nut-tab-pane title="标签2">内容2</nut-tab-pane> | ||
| 154 | +</nut-tabs> | ||
| 155 | +``` | ||
| 156 | + | ||
| 157 | +### 自定义标题 | ||
| 158 | + | ||
| 159 | +```vue | ||
| 160 | +<nut-tabs v-model="activeTab"> | ||
| 161 | + <template #titles> | ||
| 162 | + <view class="filter-tabs-wrapper"> | ||
| 163 | + <view | ||
| 164 | + v-for="item in tabsData" | ||
| 165 | + :key="item.id" | ||
| 166 | + :class="[ | ||
| 167 | + 'filter-tab-item', | ||
| 168 | + activeTab === item.id ? 'filter-tab-active' : 'filter-tab-inactive' | ||
| 169 | + ]" | ||
| 170 | + @tap="onTabClick(item.id)" | ||
| 171 | + > | ||
| 172 | + <text class="filter-tab-text">{{ item.name }}</text> | ||
| 173 | + </view> | ||
| 174 | + </view> | ||
| 175 | + </template> | ||
| 176 | +</nut-tabs> | ||
| 177 | +``` | ||
| 178 | + | ||
| 179 | +## nut-input / nut-textarea | ||
| 180 | + | ||
| 181 | +### nut-input | ||
| 182 | + | ||
| 183 | +```vue | ||
| 184 | +<nut-input | ||
| 185 | + v-model="value" | ||
| 186 | + placeholder="请输入" | ||
| 187 | + :clearable="true" | ||
| 188 | + @input="handleInput" | ||
| 189 | +/> | ||
| 190 | +``` | ||
| 191 | + | ||
| 192 | +### nut-textarea | ||
| 193 | + | ||
| 194 | +```vue | ||
| 195 | +<!-- NutUI textarea (部分样式可能不支持深度选择器) --> | ||
| 196 | +<nut-textarea | ||
| 197 | + v-model="content" | ||
| 198 | + placeholder="请输入内容" | ||
| 199 | + :maxlength="200" | ||
| 200 | + @input="handleInput" | ||
| 201 | +/> | ||
| 202 | + | ||
| 203 | +<!-- 原生 textarea (完全控制样式) --> | ||
| 204 | +<textarea | ||
| 205 | + v-model="content" | ||
| 206 | + class="custom-textarea" | ||
| 207 | + :maxlength="200" | ||
| 208 | + @input="handleInput" | ||
| 209 | +/> | ||
| 210 | +``` | ||
| 211 | + | ||
| 212 | +```css | ||
| 213 | +.custom-textarea { | ||
| 214 | + width: 100%; | ||
| 215 | + min-height: 200rpx; | ||
| 216 | + padding: 24rpx; | ||
| 217 | + border: 2rpx solid #E5E7EB; | ||
| 218 | + border-radius: 16rpx; | ||
| 219 | + font-size: 28rpx; | ||
| 220 | +} | ||
| 221 | +``` | ||
| 222 | + | ||
| 223 | +## nut-picker | ||
| 224 | + | ||
| 225 | +### 基础用法 | ||
| 226 | + | ||
| 227 | +```vue | ||
| 228 | +<template> | ||
| 229 | + <nut-picker | ||
| 230 | + :visible="showPicker" | ||
| 231 | + :columns="columns" | ||
| 232 | + :default-value="value" | ||
| 233 | + @update:visible="showPicker = $event" | ||
| 234 | + @confirm="handleConfirm" | ||
| 235 | + @cancel="handleCancel" | ||
| 236 | + /> | ||
| 237 | +</template> | ||
| 238 | + | ||
| 239 | +<script setup> | ||
| 240 | +import { ref } from 'vue' | ||
| 241 | + | ||
| 242 | +const showPicker = ref(false) | ||
| 243 | +const value = ref(['选项1']) | ||
| 244 | +const columns = ref([ | ||
| 245 | + { text: '选项1', value: '1' }, | ||
| 246 | + { text: '选项2', value: '2' }, | ||
| 247 | +]) | ||
| 248 | + | ||
| 249 | +const handleConfirm = ({ selectedOptions }) => { | ||
| 250 | + console.log('选中:', selectedOptions) | ||
| 251 | +} | ||
| 252 | +</script> | ||
| 253 | +``` | ||
| 254 | + | ||
| 255 | +## nut-toast / NutUI.showToast | ||
| 256 | + | ||
| 257 | +### 轻提示 | ||
| 258 | + | ||
| 259 | +```javascript | ||
| 260 | +import Taro from '@tarojs/taro' | ||
| 261 | + | ||
| 262 | +// 成功提示 | ||
| 263 | +Taro.showToast({ | ||
| 264 | + title: '操作成功', | ||
| 265 | + icon: 'success', | ||
| 266 | + duration: 2000 | ||
| 267 | +}) | ||
| 268 | + | ||
| 269 | +// 失败提示 | ||
| 270 | +Taro.showToast({ | ||
| 271 | + title: '操作失败', | ||
| 272 | + icon: 'error', | ||
| 273 | + duration: 2000 | ||
| 274 | +}) | ||
| 275 | + | ||
| 276 | +// 加载提示 | ||
| 277 | +Taro.showLoading({ | ||
| 278 | + title: '加载中...', | ||
| 279 | + mask: true | ||
| 280 | +}) | ||
| 281 | + | ||
| 282 | +// 关闭加载 | ||
| 283 | +Taro.hideLoading() | ||
| 284 | + | ||
| 285 | +// 纯文本提示 | ||
| 286 | +Taro.showToast({ | ||
| 287 | + title: '提示信息', | ||
| 288 | + icon: 'none' | ||
| 289 | +}) | ||
| 290 | +``` | ||
| 291 | + | ||
| 292 | +## nut-dialog | ||
| 293 | + | ||
| 294 | +### 弹窗确认 | ||
| 295 | + | ||
| 296 | +```javascript | ||
| 297 | +import Taro from '@tarojs/taro' | ||
| 298 | + | ||
| 299 | +Taro.showModal({ | ||
| 300 | + title: '提示', | ||
| 301 | + content: '确定要删除吗?', | ||
| 302 | + success: (res) => { | ||
| 303 | + if (res.confirm) { | ||
| 304 | + console.log('用户点击确定') | ||
| 305 | + } else if (res.cancel) { | ||
| 306 | + console.log('用户点击取消') | ||
| 307 | + } | ||
| 308 | + } | ||
| 309 | +}) | ||
| 310 | +``` | ||
| 311 | + | ||
| 312 | +## 图标组件 | ||
| 313 | + | ||
| 314 | +### IconFont 组件 | ||
| 315 | + | ||
| 316 | +```vue | ||
| 317 | +<template> | ||
| 318 | + <!-- 使用 IconFont 组件 --> | ||
| 319 | + <IconFont name="close" size="16" color="#9CA3AF" /> | ||
| 320 | + <IconFont name="heart" size="20" color="#EF4444" /> | ||
| 321 | + <IconFont name="heart-fill" size="20" color="#EF4444" /> | ||
| 322 | +</template> | ||
| 323 | + | ||
| 324 | +<script setup> | ||
| 325 | +import IconFont from '@/components/icons/IconFont.vue' | ||
| 326 | +</script> | ||
| 327 | +``` | ||
| 328 | + | ||
| 329 | +### 动态切换图标 | ||
| 330 | + | ||
| 331 | +⚠️ **重要**: IconFont 动态切换时需要添加 `:key` 强制重新渲染 | ||
| 332 | + | ||
| 333 | +```vue | ||
| 334 | +<template> | ||
| 335 | + <IconFont :name="iconName" :key="iconName" size="20" /> | ||
| 336 | +</template> | ||
| 337 | + | ||
| 338 | +<script setup> | ||
| 339 | +import { ref } from 'vue' | ||
| 340 | +import IconFont from '@/components/icons/IconFont.vue' | ||
| 341 | + | ||
| 342 | +const iconName = ref('heart') | ||
| 343 | + | ||
| 344 | +const toggleIcon = () => { | ||
| 345 | + iconName.value = iconName.value === 'heart' ? 'heart-fill' : 'heart' | ||
| 346 | +} | ||
| 347 | +</script> | ||
| 348 | +``` | ||
| 349 | + | ||
| 350 | +## 列表组件 | ||
| 351 | + | ||
| 352 | +### nut-cell | ||
| 353 | + | ||
| 354 | +```vue | ||
| 355 | +<nut-cell | ||
| 356 | + title="单元格" | ||
| 357 | + sub-title="副标题" | ||
| 358 | + is-link | ||
| 359 | + @click="handleClick" | ||
| 360 | +/> | ||
| 361 | +``` | ||
| 362 | + | ||
| 363 | +### nut-checkbox / nut-checkbox-group | ||
| 364 | + | ||
| 365 | +```vue | ||
| 366 | +<template> | ||
| 367 | + <nut-checkbox-group v-model="checkedList"> | ||
| 368 | + <nut-checkbox label="选项1">选项1</nut-checkbox> | ||
| 369 | + <nut-checkbox label="选项2">选项2</nut-checkbox> | ||
| 370 | + </nut-checkbox-group> | ||
| 371 | +</template> | ||
| 372 | + | ||
| 373 | +<script setup> | ||
| 374 | +import { ref } from 'vue' | ||
| 375 | + | ||
| 376 | +const checkedList = ref(['选项1']) | ||
| 377 | +</script> | ||
| 378 | +``` | ||
| 379 | + | ||
| 380 | +## 表单组件 | ||
| 381 | + | ||
| 382 | +### 表单验证模式 | ||
| 383 | + | ||
| 384 | +```vue | ||
| 385 | +<template> | ||
| 386 | + <nut-form> | ||
| 387 | + <nut-form-item label="姓名" required> | ||
| 388 | + <nut-input | ||
| 389 | + v-model="form.name" | ||
| 390 | + placeholder="请输入姓名" | ||
| 391 | + :clearable="true" | ||
| 392 | + /> | ||
| 393 | + </nut-form-item> | ||
| 394 | + | ||
| 395 | + <nut-form-item label="手机号" required> | ||
| 396 | + <nut-input | ||
| 397 | + v-model="form.phone" | ||
| 398 | + placeholder="请输入手机号" | ||
| 399 | + type="tel" | ||
| 400 | + :clearable="true" | ||
| 401 | + /> | ||
| 402 | + </nut-form-item> | ||
| 403 | + | ||
| 404 | + <nut-button type="primary" @click="handleSubmit">提交</nut-button> | ||
| 405 | + </nut-form> | ||
| 406 | +</template> | ||
| 407 | + | ||
| 408 | +<script setup> | ||
| 409 | +import { reactive } from 'vue' | ||
| 410 | + | ||
| 411 | +const form = reactive({ | ||
| 412 | + name: '', | ||
| 413 | + phone: '' | ||
| 414 | +}) | ||
| 415 | + | ||
| 416 | +const handleSubmit = () => { | ||
| 417 | + // 验证 | ||
| 418 | + if (!form.name) { | ||
| 419 | + Taro.showToast({ title: '请输入姓名', icon: 'none' }) | ||
| 420 | + return | ||
| 421 | + } | ||
| 422 | + | ||
| 423 | + if (!form.phone) { | ||
| 424 | + Taro.showToast({ title: '请输入手机号', icon: 'none' }) | ||
| 425 | + return | ||
| 426 | + } | ||
| 427 | + | ||
| 428 | + // 提交逻辑 | ||
| 429 | + console.log('表单数据:', form) | ||
| 430 | +} | ||
| 431 | +</script> | ||
| 432 | +``` | ||
| 433 | + | ||
| 434 | +## 常用 TailwindCSS 类 | ||
| 435 | + | ||
| 436 | +### 布局 | ||
| 437 | + | ||
| 438 | +```vue | ||
| 439 | +<!-- Flexbox 布局 --> | ||
| 440 | +<div class="flex items-center justify-between">...</div> | ||
| 441 | +<div class="flex gap-3">...</div> | ||
| 442 | +<div class="flex flex-col">...</div> | ||
| 443 | + | ||
| 444 | +<!-- Grid 布局 --> | ||
| 445 | +<div class="grid grid-cols-2 gap-4">...</div> | ||
| 446 | +``` | ||
| 447 | + | ||
| 448 | +### 尺寸 | ||
| 449 | + | ||
| 450 | +```vue | ||
| 451 | +<!-- 宽度 --> | ||
| 452 | +<div class="w-full">全宽</div> | ||
| 453 | +<div class="w-1/2">一半宽</div> | ||
| 454 | +<div class="flex-1">自适应</div> | ||
| 455 | + | ||
| 456 | +<!-- 高度 --> | ||
| 457 | +<div class="h-[88rpx]">固定高度</div> | ||
| 458 | +<div class="min-h-[100rpx]">最小高度</div> | ||
| 459 | +``` | ||
| 460 | + | ||
| 461 | +### 间距 | ||
| 462 | + | ||
| 463 | +```vue | ||
| 464 | +<!-- Padding --> | ||
| 465 | +<div class="p-4">四周内边距</div> | ||
| 466 | +<div class="px-4 py-2">水平+垂直内边距</div> | ||
| 467 | + | ||
| 468 | +<!-- Margin --> | ||
| 469 | +<div class="mb-4">下边距</div> | ||
| 470 | +<div class="mx-auto">水平居中</div> | ||
| 471 | + | ||
| 472 | +<!-- Gap (flex/grid 子元素间距) --> | ||
| 473 | +<div class="gap-3">子元素间距</div> | ||
| 474 | +``` | ||
| 475 | + | ||
| 476 | +### 文字 | ||
| 477 | + | ||
| 478 | +```vue | ||
| 479 | +<!-- 大小 --> | ||
| 480 | +<div class="text-[30rpx]">30rpx</div> | ||
| 481 | +<div class="text-lg">大号</div> | ||
| 482 | +<div class="text-sm">小号</div> | ||
| 483 | + | ||
| 484 | +<!-- 颜色 --> | ||
| 485 | +<div class="text-gray-900">深灰</div> | ||
| 486 | +<div class="text-blue-600">蓝色</div> | ||
| 487 | +<div class="text-red-500">红色</div> | ||
| 488 | + | ||
| 489 | +<!-- 对齐 --> | ||
| 490 | +<div class="text-left">左对齐</div> | ||
| 491 | +<div class="text-center">居中</div> | ||
| 492 | +<div class="text-right">右对齐</div> | ||
| 493 | +``` | ||
| 494 | + | ||
| 495 | +### 圆角和边框 | ||
| 496 | + | ||
| 497 | +```vue | ||
| 498 | +<!-- 圆角 --> | ||
| 499 | +<div class="rounded-[16rpx]">16rpx 圆角</div> | ||
| 500 | + | ||
| 501 | +<!-- 边框 --> | ||
| 502 | +<div class="border border-gray-200">边框</div> | ||
| 503 | +``` | ||
| 504 | + | ||
| 505 | +## 样式覆盖技巧 | ||
| 506 | + | ||
| 507 | +### 深度选择器 | ||
| 508 | + | ||
| 509 | +```vue | ||
| 510 | +<style lang="less" scoped> | ||
| 511 | +// 修改 NutUI 组件内部样式 | ||
| 512 | +:deep(.nut-button) { | ||
| 513 | + border-radius: 16rpx !important; | ||
| 514 | +} | ||
| 515 | + | ||
| 516 | +:deep(.nut-tabs__titles) { | ||
| 517 | + display: none; | ||
| 518 | +} | ||
| 519 | +</style> | ||
| 520 | +``` | ||
| 521 | + | ||
| 522 | +### TailwindCSS + !important | ||
| 523 | + | ||
| 524 | +```vue | ||
| 525 | +<template> | ||
| 526 | + <!-- 使用 ! 覆盖 TailwindCSS 样式 --> | ||
| 527 | + <nut-button class="!h-[88rpx] !rounded-[16rpx] !text-[30rpx]"> | ||
| 528 | + 按钮 | ||
| 529 | + </nut-button> | ||
| 530 | +</template> | ||
| 531 | +``` | ||
| 532 | + | ||
| 533 | +## 最后更新 | ||
| 534 | + | ||
| 535 | +- **更新时间**: 2026-02-10 | ||
| 536 | +- **维护者**: Claude Code | ||
| 537 | +- **Taro 版本**: 4.1.11 | ||
| 538 | +- **NutUI 版本**: 4.3.14 |
-
Please register or login to post a comment