--- url: 'https://starter.wot-ui.cn/guide/open-wot.md' --- # CLI 我们在 [Open Wot](https://github.com/wot-ui/open-wot) 中维护了Wot UI 的 AI 工具链仓库,其中对外发布的核心包为 [@wot-ui/cli](https://www.npmjs.com/package/@wot-ui/cli)。它提供命令行工具、MCP Server、离线组件知识库与数据提取脚本,用于把 wot-ui v2 的组件知识接入编辑器、AI Agent 和本地工程分析流程。 ## 亮点 * 完全离线:组件 Props、事件、CSS 变量、Demo、Changelog 等元数据随包安装,无需网络请求 * Agent 友好:多数命令支持 `--format json`,适合被工具/脚本消费 * 项目分析:提供 `doctor / usage / lint` 诊断与统计能力 * MCP 集成:通过 `wot mcp` 以 stdio 方式提供 tools,便于集成到支持 MCP 的客户端 ## 安装 ```bash npm install -g @wot-ui/cli ``` 安装完成后可直接使用 `wot` 命令。 ## 快速开始 ```bash wot list wot info Button wot demo Button basic wot doc Button wot token Button wot changelog ``` ## 命令速查 ### 组件知识 * `wot list`:列出可用的 wot-ui 组件 * `wot info `:查看组件 props、events、slots、CSS 变量 * `wot doc `:输出组件 Markdown 文档 * `wot demo [name]`:查看 demo 列表或输出指定 demo 源码 * `wot token [Component]`:查看组件 CSS 变量与默认值 * `wot changelog [version] [component]`:查看版本更新记录 ### 项目分析 * `wot doctor [dir]`:检查项目依赖、运行环境与基础集成情况 * `wot usage [dir]`:统计 `.vue` 文件中的 `` 使用情况 * `wot lint [dir]`:检查未知组件、空按钮等规则 ### MCP Server 启动 MCP Server: ```bash wot mcp ``` 在支持 MCP 的客户端中添加配置(示例): ```json { "mcpServers": { "wot-ui": { "command": "wot", "args": ["mcp"] } } } ``` 当前 MCP Server 提供的 tools 包括: * `wot_list` * `wot_info` * `wot_doc` * `wot_demo` * `wot_token` * `wot_changelog` * `wot_lint` ## 通用参数 多数查询命令支持以下参数: * `--format text|json` * `--version v2` --- --- url: 'https://starter.wot-ui.cn/guide/llms-txt.md' --- # LLMs.txt [llms.txt](https://llmstxt.org/) 是一个专为大型语言模型设计的文本文件,类似 robots.txt,但目标不同。robots.txt 告诉搜索引擎爬虫哪些页面可以爬取,而 llms.txt 为 AI 工具提供网站内容的结构化信息,帮助它们更好地理解和索引组件库文档、示例和最佳实践。 ## 可用资源 我们也提供 2 个 `llms.txt` 路由来帮助 AI 工具访问文档: * [llms.txt](https://wot-ui.cn/llms.txt) - 包含所有组件及其文档链接的结构化概览 * [llms-full.txt](https://wot-ui.cn/llms-full.txt) - 提供包含实现细节和示例的完整文档 ## 在 AI 工具中使用 ### Cursor 在 Cursor 中找到 `Indexing & Docs` 设置,并将 `llms.txt` 添加到 `Docs` 中,使用 `@Docs` 功能将 llms.txt 文件包含到项目中。 [详细了解 Cursor 中的 @Docs 功能](https://cursor.com/docs/agent/tools/search) ### TRAE 在 TRAE 中找到 `上下文/文档集` 设置,并将 `llms.txt` 添加到 `文档集` 中,使用 `#Docs` 功能将 llms.txt 文件包含到项目中。 [详细了解 TRAE 中的 #Docs 功能](https://docs.trae.ai/ide/number-sign) ### 其他工具 任何支持 `llms.txt` 标准,或支持通过 URL 摄取文档的工具,都可以使用我们提供的 llms.txt 文件。你可以将它加入工具的 `文档集`、`rules` 或知识库配置中,帮助 AI 更好地理解 Wot UI 组件库。 ### context7 如果不使用 llms.txt,也可以通过 [context7](https://github.com/upstash/context7) 直接读取组件库文档。 [详细了解 context7](https://github.com/upstash/context7) ## 延伸阅读 * [Skills](/guide/skills) * [llms.txt:让 AI 更好地理解你的文档](https://juejin.cn/post/7500981295105015847) --- --- url: 'https://starter.wot-ui.cn/guide/skills.md' --- # Skills [Skills](https://agentskills.io/what-are-skills) 是 AI 的“超能力模板”,是一套完整的、可复用的、能解决特定问题的方案,我们专为 AI Agent(如 Trae, Cursor, Cline 等)设计了 Wot UI 相关的 Skills,以帮助 AI 更加准确、高效地处理 `wot-ui` 相关的开发任务。 ## 🎯 内置技能 我们提供以下 AI 技能,可供 AI 智能体根据任务需求加载: | Skill | 描述 | 适用场景 | 入口 | | --- | --- | --- | --- | | `wot-ui-v2` | 处理 wot-ui v2 组件库日常开发的核心技能。 | 组件选型、API 查询、生成 Vue3 + uni-app 页面代码、排查常见组件坑位(如 Toast, Dialog 挂载等)。 | [skills/wot-ui-v2/SKILL.md](https://github.com/wot-ui/open-wot/tree/main/skills/wot-ui-v2/SKILL.md) | | `wot-ui-cli` | 专门用于回答、使用和调试 `@wot-ui/cli` 工具本身的技能。 | 查询 CLI 命令用法(list, info, doc 等)、配置 MCP Server、本地调试 CLI 源码、执行离线数据提取。 | [skills/wot-ui-cli/SKILL.md](https://github.com/wot-ui/open-wot/tree/main/skills/wot-ui-cli/SKILL.md) | | `wot-ui-unocss-preset-guide` | 指导安装、配置并使用 `@wot-ui/unocss-preset`。 | 预设接入、`unocss.config.ts` 配置(如 `presetWot`)、`prefix/preflight/baseTokens` 使用示例、类名不生效/自动补全不出现等问题排查。 | [skills/wot-ui-unocss-preset-guide/SKILL.md](https://github.com/wot-ui/open-wot/tree/main/skills/wot-ui-unocss-preset-guide/SKILL.md) | | `create-wot-ui-theme` | 生成 wot-ui 单文件主题 SCSS 的专项技能。 | 需要为 wot-ui 定制品牌主题,且要求遵循“单文件包含 mixin 和挂载选择器、App.vue 仅作 `@use` 引入”的约束时使用。 | [skills/create-wot-ui-theme/SKILL.md](https://github.com/wot-ui/open-wot/tree/main/skills/create-wot-ui-theme/SKILL.md) | | `starter-cleaner` | 将 wot-starter v2 模板精简为最小可开发状态的清理技能。 | 初始化业务项目前移除文档、演示分包、生成文件和 monorepo 配置;同步收敛 `vite.config.ts`、`package.json`,并重新生成最小 `src/pages.json` / `src/uni-pages.d.ts`。 | [.agents/skills/starter-cleaner/SKILL.md](https://github.com/wot-ui/wot-starter/tree/v2/.agents/skills/starter-cleaner/SKILL.md) | ## 安装 推荐使用脚本安装 Skills,可以根据实际需求选择安装项: ```sh pnpx skills add wot-ui/open-wot # or npx skills add wot-ui/open-wot ``` ## 延伸阅读 * [llms.txt](/guide/llms-txt) * [Agent Skills、Rules、Prompt、MCP,一文把它们理清楚了](https://juejin.cn/post/7599268297201958950) --- --- url: 'https://starter.wot-ui.cn/guide/uni-helper.md' --- # Uni Helper 插件 Uni Helper 是一个旨在增强 uni-app 系列产品的开发体验为爱发电的非官方组织。作为靠爱发电的非官方项目,Uni Helper 提供了打包工具插件支持、编辑器扩展支持、NPM 包等并尽力维护它们,而他们提供的众多插件组成了本项目的核心插件库。 ## Components 组件 大多数组件都是用户界面的可重用部分,如按钮和菜单。 得益于 [@uni-helper/vite-plugin-uni-components](https://github.com/uni-helper/vite-plugin-uni-components),组件将自动注册到全局,你不需要显式导入它们。只需要在 `src/components` 目录下创建组件,然后直接使用即可。 :::code-group ```vue [src/pages/index.vue] ``` ```vue [src/components/AppAlert.vue] ``` ::: ## Pages 页面 通过组合使用组件,我们可以得到展示给用户的页面。 得益于 [@uni-helper/vite-plugin-uni-pages](https://github.com/uni-helper/vite-plugin-uni-pages),约定式路由(文件路由)的实现轻而易举。`src/pages` 目录下的每个文件都代表着一个路由。要创建新页面,只需要在这个目录里新增 `.vue` 文件。 :::code-group ```vue [src/pages/index.vue] ``` ```vue [src/pages/about.vue] ``` [@uni-helper/vite-plugin-uni-pages](https://github.com/uni-helper/vite-plugin-uni-pages) 也支持配置排除指定目录的页面(例如组件目录),相对于 dir 和 subPackages,我们在`vite.config.ts`中已经做了相应的配置排除了`components`目录: ```ts // vite.config.ts ... UniHelperPages({ dts: 'src/uni-pages.d.ts', subPackages: [ 'src/subPages', ], /** * 排除的页面,相对于 dir 和 subPackages * @default [] */ exclude: ['**/components/**/*.*'], }) ... ``` ::: ## Layouts 布局 布局可以用来创建通用界面(如页眉和页脚显示)的包装器,不同的页面可能需要不同的布局。布局是使用 `Vue` 的插槽功能实现的。 得益于 [@uni-helper/vite-plugin-uni-layouts](https://github.com/uni-helper/vite-plugin-uni-layouts),你可以轻松地切换不同的布局。 `src/layouts/default.vue` 文件将作为默认布局。 :::code-group ```vue [src/layouts/default.vue] ``` ```vue [src/pages/index.vue] ``` ```vue [src/pages/about.vue] ``` ::: 在页面文件内设置 `route` 代码块可以指定自定义布局。 ```vue [src/pages/index.vue] { "layout": "custom" } ``` ## manifest 应用配置 `manifest.json` 文件是应用的配置文件,用于指定应用的名称、图标、权限等。 得益于 [@uni-helper/vite-plugin-uni-manifest](https://github.com/uni-helper/vite-plugin-uni-manifest),你可以使用 `TypeScript` 编写 `uni-app` 的 `manifest.json`。 ```ts // vite.config.ts import Uni from '@dcloudio/vite-plugin-uni' import UniManifest from '@uni-helper/vite-plugin-uni-manifest' import { defineConfig } from 'vite' export default defineConfig({ plugins: [UniManifest(), Uni()], }) ``` 创建 `manifest.config.(ts|mts|cts|js|cjs|mjs|json)`, 然后用 `TypeScript` 编写你的 `manifest.json`。 ```ts // manifest.config.ts import { defineManifestConfig } from '@uni-helper/vite-plugin-uni-manifest' export default defineManifestConfig({ // code here... }) ``` 在 [这里](https://github.com/uni-helper/vite-plugin-uni-manifest/blob/main/playground/manifest.config.ts),你可以找到 `uni-app` 默认的 Vite-TS 模版的 `manifest.json` 是如何用 TypeScript 编写的。 --- --- url: 'https://starter.wot-ui.cn/guide/uni-echarts.md' --- # Echarts 在移动端跨平台开发中,数据可视化是一个常见需求。而 ECharts 作为百度开源的强大图表库,在 Web 端有着广泛的应用,我们在技术栈选择的时候往往倾向于选择这种应用广泛,解决方案完善的库。 但在 uni-app 中直接使用 ECharts 会遇到各种兼容性问题,特别是在小程序端。幸运的是,有很多库可以帮助我们在 `uni-app` 中使用 `Echarts`,例如 `uni-echarts`、`lime-echart` 等插件,为我们提供了相应的解决方案。 本章节中,我们将会在 wot-starter 中,探索 uni-app 接入 `Echarts` 的方案,并针对小程序,对其超级庞大的体积进行优化。 ## 为什么选择 uni-echarts? [uni-echarts](https://github.com/xiaohe0601/uni-echarts) 是一个适用于 uni-app 的 Apache ECharts 组件(仅支持Vue 3),具有以下优势: * 🚀 **快速上手**:与 [Vue ECharts](https://github.com/ecomfe/vue-echarts) 近乎一致的使用体验 * 📱 **多端兼容**:支持 H5、小程序、APP 等多个平台 * 📦 **支持 easycom**:无需手动导入,开箱即用 * ☕ **TypeScript 支持**:完整的类型定义 * 🍳 **免费商用**:基于 MIT 许可协议 基于以上,选择使用 `uni-echarts` 作为我们的图表库,当然也可以选择 [lime-echart](https://ext.dcloud.net.cn/plugin?id=4899) 。 ## 安装和配置 ### 1. 安装依赖 首先安装必要的依赖包: ```bash pnpm add echarts uni-echarts # 或者 npm install echarts uni-echarts ``` 在我们的项目中,`package.json` 已经包含了这些依赖: ```json { "dependencies": { "echarts": "^6.0.0", "uni-echarts": "^1.1.2" } } ``` ### 2. Vite 配置 在 `vite.config.ts` 中添加必要的配置: ```typescript import { defineConfig } from 'vite' import Uni from '@dcloudio/vite-plugin-uni' import UniHelperComponents from '@uni-helper/vite-plugin-uni-components' import { UniEchartsResolver } from 'uni-echarts/resolver' export default defineConfig({ optimizeDeps: { exclude:['@wot-ui/ui', 'uni-echarts'] : [], }, plugins: [ // 组件自动导入 UniHelperComponents({ resolvers: [UniEchartsResolver()], dts: 'src/components.d.ts', }), Uni(), ], }) ``` 这样配置后,`uni-echarts` 组件就可以在项目中自动导入使用了,更多信息参见 [Uni ECharts 快速开始](https://uni-echarts.xiaohe.ink/guide/getting-started)。 ## 基础使用示例 ### 创建一个柱状图组件 让我们以项目中的 `BarChart.vue` 为例,看看如何创建一个基础的柱状图: ```vue ``` ### 关键要点说明 1. **provideEcharts(echarts)**:这是使用 uni-echarts 的关键步骤,必须在每个组件中调用 2. **按需导入**:只导入需要的图表类型和组件,减小打包体积 3. **echarts.use()**:注册导入的组件 4. **uni-echarts 组件**:使用 `` 标签渲染图表 ## 更多图表类型 更多图表类型见 [Echarts](https://echarts.apache.org/examples/zh/index.html) 和 [Uni ECharts](https://uni-echarts.xiaohe.ink/examples/basic),当然你也可以使用 AI 工具帮助你编写想要的图表配置,它非常善于处理这个事情。 ## 高级功能:分包优化与异步加载 引入 `Echarts` 后,体积暴增 800KB ,怎么办? 有办法,我们曾在 [Vue3 uni-app 主包 2 MB 危机?1 个插件 10 分钟瘦身](https://mp.weixin.qq.com/s/nnmu91kclQHnE-1TAn11Tg) 一文中介绍过 `@uni-ku/bundle-optimizer`,它是解决微信小程序超包的利器,我们现在使用它的分包优化和分包异步化能力,来优化引入 `Echarts` 后暴增的小程序体积。 这是我们的项目结构,在 `subEcharts` 分包中实现 `Echarts` 相关组件,在 `subAsyncEcharts` 分包中演示分包异步化效果: ```text src/ ├── pages/ # 主包页面 ├── subEcharts/ # ECharts 组件分包 │ └── echarts/ │ └── components/ ├── subAsyncEcharts/ # 异步 ECharts 演示分包 │ └── asyncEcharts/ └── subPages/ # 其他功能分包 ``` ### 安装和配置 #### 1. 安装依赖 ```bash pnpm add -D @uni-ku/bundle-optimizer # 或者 npm install -D @uni-ku/bundle-optimizer ``` 在我们的项目中,`package.json` 已经包含了这个依赖: ```json { "devDependencies": { "@uni-ku/bundle-optimizer": "1.3.15-beta.2" } } ``` #### 2. Vite 配置 在 `vite.config.ts` 中配置插件: ```typescript import { defineConfig } from 'vite' import Uni from '@dcloudio/vite-plugin-uni' import Optimization from '@uni-ku/bundle-optimizer' export default defineConfig({ plugins: [ Uni(), // 分包优化插件 Optimization({ logger: true, // 开启日志输出 }), ], }) ``` #### 3. 小程序分包配置 在 `manifest.json` 中开启分包优化: ```json { "mp-weixin": { "optimization": { "subPackages": true } } } ``` 如果你使用了 `@uni-helper/vite-plugin-uni-manifest` 插件,那么需要在 `manifest.config.ts` 中开启分包优化: ```ts export default defineManifestConfig({ 'mp-weixin': { optimization: { subPackages: true, }, }, }) ``` 配置完成后,重新构建,我们会发现主包少了 200+KB ,还剩 500KB 在主包中,可以期待 `@uni-ku/bundle-optimizer` 未来可以传送组件到分包中,到时会把大部分构建产物都打包进入分包中。 > 这里配合 lime-echart 的话,应该可以将 echarts.min.js 完全放入分包,各位可以自行探索。 ### 跨分包异步组件引用 在我们的项目中,`subAsyncEcharts` 分包可以异步引用 `subEcharts` 分包中的组件: ```vue ``` 更多信息参见 [@uni-ku/bundle-optimizer](https://github.com/uni-ku/bundle-optimizer)。 ## 注意事项和最佳实践 ### 1. 使用 npm 方式安装必须调用 provideEcharts 在每个使用 ECharts 的组件中,都必须调用 `provideEcharts(echarts)`: ```javascript import * as echarts from 'echarts/core' import { provideEcharts } from 'uni-echarts/shared' // 🚨 这一行是必须的 provideEcharts(echarts) ``` ### 2. 按需导入组件 为了减小打包体积,建议按需导入需要的图表类型和组件: ```javascript // 只导入需要的图表类型 import { BarChart, LineChart, PieChart } from 'echarts/charts' // 只导入需要的组件 import { GridComponent, TooltipComponent, LegendComponent } from 'echarts/components' // 导入渲染器 import { CanvasRenderer } from 'echarts/renderers' ``` ### 3. 设置图表尺寸 使用 `custom-class` 属性设置图表容器的尺寸: ```vue ``` ### 4. 响应式数据更新 当需要动态更新图表数据时,直接修改 `option` 对象即可: ```javascript const option = ref({ // 初始配置 }) // 更新数据 function updateData() { option.value.series[0].data = [/* 新数据 */] } ``` ### 5. 主题定制 可以通过 `provideEchartsTheme` 来设置自定义主题: ```javascript import { provideEcharts, provideEchartsTheme } from 'uni-echarts/shared' import * as echarts from 'echarts/core' provideEcharts(echarts) // 设置自定义主题 provideEchartsTheme({ color: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de'], backgroundColor: 'transparent', // 更多主题配置... }) ``` ## 卸载步骤 如果你不再需要在项目中使用 ECharts,可以按照以下步骤完全卸载相关依赖和配置: ### 1. 卸载依赖包 首先卸载 ECharts 相关的依赖包: ```bash pnpm remove echarts uni-echarts ``` ### 2. 清理 Vite 配置 在 `vite.config.ts` 中移除 ECharts 相关的配置: ```typescript import { defineConfig } from 'vite' import Uni from '@dcloudio/vite-plugin-uni' import UniHelperManifest from '@uni-helper/vite-plugin-uni-manifest' import UniHelperPages from '@uni-helper/vite-plugin-uni-pages' import UniHelperLayouts from '@uni-helper/vite-plugin-uni-layouts' import UniHelperComponents from '@uni-helper/vite-plugin-uni-components' import AutoImport from 'unplugin-auto-import/vite' import { WotResolver } from '@uni-helper/vite-plugin-uni-components/resolvers' import { UniEchartsResolver } from 'uni-echarts/resolver' // [!code --] import UniKuRoot from '@uni-ku/root' export default async () => { const UnoCSS = (await import('unocss/vite')).default return defineConfig({ optimizeDeps: { exclude: ['@wot-ui/ui', 'uni-echarts'] : [], // [!code --] exclude: ['@wot-ui/ui',] : [], // [!code ++] }, plugins: [ UniHelperManifest(), UniHelperPages({ dts: 'src/uni-pages.d.ts', subPackages: [ 'src/subPages', ], exclude: ['**/components/**/*.*'], }), UniHelperLayouts(), UniHelperComponents({ resolvers: [WotResolver(), UniEchartsResolver()], // [!code --] resolvers: [WotResolver()], // [!code ++] dts: 'src/components.d.ts', dirs: ['src/components', 'src/business'], directoryAsNamespace: true, }), UniKuRoot(), Uni(), // https://github.com/uni-ku/bundle-optimizer Optimization({ logger: true, }), AutoImport({ imports: ['vue', '@vueuse/core', 'pinia', 'uni-app', { from: '@wot-ui/router', imports: ['createRouter', 'useRouter', 'useRoute'], }, { from: '@wot-ui/ui', imports: ['useToast', 'useMessage', 'useNotify', 'CommonUtil'], }, { from: 'alova/client', imports: ['usePagination', 'useRequest'], }], dts: 'src/auto-imports.d.ts', dirs: ['src/composables', 'src/store', 'src/utils', 'src/api'], vueTemplate: true, }), UnoCSS(), ], }) } ``` ### 3. 删除相关文件和目录 删除项目中与 ECharts 相关的文件和目录: ```bash # 删除 ECharts 组件分包目录 rm -rf src/subEcharts/ # 删除异步 ECharts 演示分包目录 rm -rf src/subAsyncEcharts/ ``` 完成以上步骤后,你的项目就完全移除了 ECharts 相关的依赖和配置,项目体积也会相应减小。 ## 总结 我们在 `wot-starter` 中 使用 `uni-echarts` 结合 `@uni-ku/bundle-optimizer` 为 `uni-app` 开发者提供了一个完整的高性能 ECharts 解决方案。通过合理的配置和规范的使用方式,我们可以在各个平台上实现丰富的数据可视化效果,同时保证应用的性能和用户体验。 ## 参考资源 * [uni-echarts 官方文档](https://uni-echarts.xiaohe.ink) * [@uni-ku/bundle-optimizer](https://github.com/uni-ku/bundle-optimizer) * [ECharts 官方文档](https://echarts.apache.org/zh/index.html) * [lime-echart](https://ext.dcloud.net.cn/plugin?id=4899) --- --- url: 'https://starter.wot-ui.cn/guide/uni-ku-root.md' --- # @uni-ku/root 在传统的 UniApp 开发中,由于框架限制,无法像标准 Vue 应用那样使用全局根组件来管理公共状态和组件,这给开发带来了诸多不便。 为了解决这个问题,我们引入了 [@uni-ku/root](https://github.com/uni-ku/root) 插件,它通过 Vite 模拟出虚拟根组件,让 UniApp 项目也能享受到类似 Vue 标准应用的开发体验,也可以解决 `@uni-helper/vite-plugin-uni-layouts` 插件无法使用微信小程序 `page-meta` 的问题。 ## 🎯 @uni-ku/root 是什么? @uni-ku/root 借助 Vite 模拟出虚拟根组件(支持SFC的App.vue),解决 uniapp 无法使用公共组件问题。 ### 🎏 支持 * 自定义虚拟根组件文件命名(App.ku.vue文件命名支持更换) * 更高灵活度的获取虚拟根组件实例(获取KuRootView的Ref) * 自动提取PageMeta到页面顶层(自动提升小程序PageMeta\[用于阻止滚动穿透]组件) ## 🚀 接入步骤和配置 ### 📦 安装 ```bash pnpm add -D @uni-ku/root yarn add -D @uni-ku/root npm install -D @uni-ku/root ``` ### 🚀 Vite 配置 在 `vite.config.ts` 中引入并配置 UniKuRoot 插件: ```typescript import { defineConfig } from 'vite' import Uni from '@dcloudio/vite-plugin-uni' import UniHelperManifest from '@uni-helper/vite-plugin-uni-manifest' import UniHelperPages from '@uni-helper/vite-plugin-uni-pages' import UniHelperLayouts from '@uni-helper/vite-plugin-uni-layouts' import UniHelperComponents from '@uni-helper/vite-plugin-uni-components' import AutoImport from 'unplugin-auto-import/vite' import { WotResolver } from '@uni-helper/vite-plugin-uni-components/resolvers' import UniKuRoot from '@uni-ku/root' // https://vitejs.dev/config/ export default async () => { const UnoCSS = (await import('unocss/vite')).default return defineConfig({ plugins: [ // https://github.com/uni-helper/vite-plugin-uni-manifest UniHelperManifest(), // https://github.com/uni-helper/vite-plugin-uni-pages UniHelperPages({ dts: 'src/uni-pages.d.ts', subPackages: [ 'src/subPages', ], /** * 排除的页面,相对于 dir 和 subPackages * @default [] */ exclude: ['**/components/**/*.*'], }), // https://github.com/uni-helper/vite-plugin-uni-layouts UniHelperLayouts(), // https://github.com/uni-helper/vite-plugin-uni-components UniHelperComponents({ resolvers: [WotResolver()], dts: 'src/components.d.ts', dirs: ['src/components', 'src/business'], directoryAsNamespace: true, }), // https://github.com/uni-ku/root UniKuRoot(), Uni(), // https://github.com/antfu/unocss // see unocss.config.ts for config UnoCSS(), ], }) } ``` **重要提示**:UniKuRoot 插件必须放在 `Uni()` 插件之前,如果存在修改 pages.json 的插件和 `Layout` 插件,需要将 UniKuRoot 放在它们之后。 ### 🎉 创建虚拟根组件 在 `src/App.ku.vue` 中创建虚拟根组件: > 注意 `App.ku.vue` 中暂时无法编写样式全局生效,所以我们可以将样式写到 `App.vue` 中 ```html ``` ## 💡 代码示例和使用方法 ### 1. 在页面中使用全局 Toast ```html ``` ### 2. PageMeta 自动提升示例 在页面中使用 PageMeta 组件,会自动提升到页面顶层: ```html ``` ## 🎉 总结 通过接入 `@uni-ku/root`,wot-starter 项目成功实现了: * ✅ 全局组件的统一管理 * ✅ 主题配置的全局应用 * ✅ 更好的代码组织结构 * ✅ 接近标准 Vue 应用的开发体验 * ✅ 完美支持 Wot UI 组件库 这个方案不仅解决了 UniApp 开发中的痛点,还可以解决 `@uni-helper/vite-plugin-uni-layouts` 插件无法使用微信小程序 `page-meta` 的问题,一举多得,美哉! ## 🔗 相关链接 * [@uni-ku/root GitHub](https://github.com/uni-ku/root) * [Wot UI](https://wot-ui.cn) * [Wot Starter](https://starter.wot-ui.cn) --- --- url: 'https://starter.wot-ui.cn/guide/styling.md' --- # 样式 模板基于 `UnoCSS` 提供主要样式支持。当然,你可以结合 CSS 预处理器、组件库等使用。 ## UnoCSS [UnoCSS](https://unocss.dev/) 是按需使用的原子 CSS 引擎,提供了良好的样式支持。 模板内置了 [@uni-helper/unocss-preset-uni](https://github.com/uni-helper/unocss-preset-uni),它在底层使用 [unocss-applet](https://github.com/unocss-applet/unocss-applet) 来兼容不同平台,并提供了按平台编写样式的能力。 ```html ``` ## CSS 预处理器 你可以参考 [Vite 文档 CSS 预处理器](https://cn.vitejs.dev/guide/features.html#css-pre-processors),了解相关使用方法。 ## 单文件组件样式 你可以参考 [Vue 文档单文件组件 CSS 功能](https://cn.vuejs.org/api/sfc-css-features.html),了解相关使用方法。 ## 组件库 除了 Wot UI 组件库,你还可以查看 \[uni-helper/awesome-uni-app] 整理的 [组件库](https://github.com/uni-helper/awesome-uni-app#ui-%E7%BB%84%E4%BB%B6%E5%BA%93),当然最好不要看,如果你非要看,那么选一个你心动的即可~ --- --- url: 'https://starter.wot-ui.cn/guide/unocss-preset.md' --- # UnoCSS 预设 [@wot-ui/unocss-preset](https://github.com/wot-ui/unocss-preset) 是我们提供的 `UnoCSS` 预设,用来把 `wot-ui` 的设计 token 和主题变量映射成可直接使用的原子类。 接入后,你可以直接在模板中使用 `wot-` 前缀类名完成颜色、间距、圆角、字重、排版、透明度和描边等样式编排,而不需要手动维护一套额外的 CSS 变量映射。 ```html Wot UI UnoCSS Preset ``` ## 适用场景 如果你满足以下任一场景,推荐使用 `@wot-ui/unocss-preset`: * 项目已经接入 `UnoCSS` * 希望直接复用 `wot-ui` 的设计 token 与主题变量 * 希望通过原子类快速搭建 `uni-app` / `Vue` 页面样式 ## 它提供了什么 这个预设主要提供三部分能力: | 能力 | 说明 | | --- | --- | | `theme` | 把 `wot-ui` 的语义色和基础色映射到 `UnoCSS theme`,供颜色类规则使用 | | `rules` | 生成 `wot-text-*`、`wot-bg-*`、`wot-m-*`、`wot-p-*`、`wot-rounded-*` 等原子类规则 | | `preflights` | 自动注入 `wot-ui` 的 CSS 变量,确保这些原子类能拿到正确的变量值 | 默认情况下,类名前缀为 `wot-`,例如: * `wot-text-primary` * `wot-bg-danger-surface` * `wot-m-main` * `wot-rounded-md` * `wot-text-body-main` ## 安装 ::: code-group ```bash [npm] npm i -D unocss npm i @wot-ui/unocss-preset ``` ```bash [yarn] yarn add -D unocss yarn add @wot-ui/unocss-preset ``` ```bash [pnpm] pnpm add -D unocss pnpm add @wot-ui/unocss-preset ``` ::: ## 使用 在项目根目录创建或更新 `unocss.config.ts`: ```ts import { presetWot } from '@wot-ui/unocss-preset' import { defineConfig } from 'unocss' export default defineConfig({ presets: [ presetWot(), ], }) ``` 完成配置后,就可以直接在模板中使用 `wot-` 前缀原子类: ```vue ``` ## 配置项 你可以通过 `presetWot()` 传入配置项来自定义行为: ```ts presetWot({ prefix: 'wot', preflight: true, baseTokens: false, }) ``` | 配置项 | 默认值 | 说明 | 示例 | | --- | --- | --- | --- | | `prefix` | `wot` | 工具类前缀 | `wot-text-primary`、`wot-m-main` | | `preflight` | `true` | 是否自动注入 `wot-ui` CSS 变量 | `presetWot({ preflight: true })` | | `baseTokens` | `false` | 是否开放基础色板和原始 token 类名 | `presetWot({ baseTokens: true })` | ### prefix 用于控制原子类前缀。默认是 `wot`,对应生成的类名格式为 `wot-*`。 ```ts presetWot({ prefix: 'wot', }) ``` ### preflight 开启后会自动注入 `wot-ui` 相关 CSS 变量,通常推荐保持默认值 `true`。如果关闭它,需要你自行确保这些变量已在项目中可用,否则类名可能存在但样式不生效。 ### baseTokens 默认情况下,预设主要暴露语义化 token。开启 `baseTokens` 后,还会额外开放基础色板和原始 token 类名,适合需要更细粒度控制的场景。 ## 支持的规则 | 规则类型 | 前缀模式 | 示例 | | --- | --- | --- | | 颜色 | `wot-text-*` / `wot-bg-*` / `wot-border-*` | `wot-text-primary`、`wot-bg-danger-surface`、`wot-border-border-main` | | 间距 | `wot-m-*` / `wot-gap-*` | `wot-m-main`、`wot-gap-tight`、`wot-gap-x-loose` | | 内边距 | `wot-p-*` | `wot-p-main`、`wot-px-tight`、`wot-pb-loose` | | 圆角 | `wot-rounded-*` | `wot-rounded-md`、`wot-rounded-full` | | 字重 | `wot-font-*` | `wot-font-medium`、`wot-font-semibold` | | 排版 | `wot-text-*` | `wot-text-body-main`、`wot-text-title-large` | | 透明度 | `wot-opacity-*` | `wot-opacity-disabled` | | 描边 | `wot-border-stroke-*` | `wot-border-stroke-main` | ## 可用变量值 以下为各类原子类支持的主要变量值,使用时将它们拼接到对应规则后即可。 ### 颜色类 | 项目 | 内容 | | --- | --- | | 适用前缀 | `wot-text-*`、`wot-bg-*`、`wot-border-*` | | 主色 | `primary`、`primary-1` ~ `primary-10` | | 危险色 | `danger`、`danger-main`、`danger-hover`、`danger-clicked`、`danger-disabled`、`danger-particular`、`danger-surface` | | 成功色 | `success`、`success-main`、`success-hover`、`success-clicked`、`success-disabled`、`success-particular`、`success-surface` | | 警告色 | `warning`、`warning-main`、`warning-hover`、`warning-clicked`、`warning-disabled`、`warning-particular`、`warning-surface` | | 文字色 | `text-main`、`text-secondary`、`text-auxiliary`、`text-disabled`、`text-placeholder`、`text-white` | | 图标色 | `icon-main`、`icon-secondary`、`icon-auxiliary`、`icon-disabled`、`icon-placeholder`、`icon-white` | | 边框色 | `border-extra-strong`、`border-strong`、`border-main`、`border-light`、`border-white`、`border-zero` | | 填充色 | `filled-extra-strong`、`filled-strong`、`filled-content`、`filled-bottom`、`filled-oppo`、`filled-zero` | | 分割线 | `divider-main`、`divider-light`、`divider-strong`、`divider-white` | | 反馈色 | `feedback-hover`、`feedback-active`、`feedback-accent` | | 半透明填充 | `opacfilled-tooltip-toast-cover`、`opacfilled-main-cover`、`opacfilled-light-cover` | | `Picker View Mask` | `picker-view-mask-start`、`picker-view-mask-end` | | 分类色 | `classify-yellow-bg`、`classify-yellow-border`、`classify-yellow-content`、`classify-cyan-bg`、`classify-cyan-border`、`classify-cyan-content`、`classify-purple-bg`、`classify-purple-border`、`classify-purple-content`、`classify-grape-bg`、`classify-grape-border`、`classify-grape-content`、`classify-pink-bg`、`classify-pink-border`、`classify-pink-content` | | 示例 | `wot-text-primary`、`wot-bg-filled-oppo`、`wot-border-border-main`、`wot-bg-classify-purple-content` | ### 间距类 | 项目 | 内容 | | --- | --- | | 适用前缀 | `wot-m-*`、`wot-mx-*`、`wot-my-*`、`wot-mt-*`、`wot-mr-*`、`wot-mb-*`、`wot-ml-*`、`wot-gap-*`、`wot-gap-x-*`、`wot-gap-y-*` | | 可用值 | `zero`、`ultra-tight`、`super-tight`、`extra-tight`、`tight`、`main`、`loose`、`extra-loose`、`super-loose`、`ultra-loose`、`spacious`、`extra-spacious`、`super-spacious`、`ultra-spacious` | | 示例 | `wot-m-main`、`wot-mt-tight`、`wot-gap-x-loose` | ### 内边距类 | 项目 | 内容 | | --- | --- | | 适用前缀 | `wot-p-*`、`wot-px-*`、`wot-py-*`、`wot-pt-*`、`wot-pr-*`、`wot-pb-*`、`wot-pl-*` | | 可用值 | `zero`、`ultra-tight`、`super-tight`、`extra-tight`、`tight`、`main`、`loose`、`extra-loose`、`super-loose`、`ultra-loose`、`spacious`、`extra-spacious`、`super-spacious`、`ultra-spacious` | | 示例 | `wot-p-main`、`wot-px-tight`、`wot-pb-loose` | ### 圆角类 | 项目 | 内容 | | --- | --- | | 适用前缀 | `wot-rounded-*` | | 可用值 | `zero`、`sm`、`md`、`lg`、`xl`、`2xl`、`3xl`、`full` | | 示例 | `wot-rounded-md`、`wot-rounded-full` | ### 字重类 | 项目 | 内容 | | --- | --- | | 适用前缀 | `wot-font-*` | | 可用值 | `ultra-light`、`thin`、`light`、`regular`、`medium`、`semibold`、`bold` | | 示例 | `wot-font-medium`、`wot-font-semibold` | ### 排版类 | 项目 | 内容 | | --- | --- | | 适用前缀 | `wot-text-*` | | Title | `title-main`、`title-large`、`title-extra-large` | | Body | `body-main`、`body-large`、`body-extra-large`、`body-super-large`、`body-ultra-large` | | Label | `label-super-small`、`label-extra-small`、`label-small`、`label-main`、`label-large` | | 示例 | `wot-text-body-main`、`wot-text-title-large`、`wot-text-label-large` | ### 透明度类 | 项目 | 内容 | | --- | --- | | 适用前缀 | `wot-opacity-*` | | 可用值 | `disabled`、`dimmer`、`overlay`、`main`、`backdrop` | | 示例 | `wot-opacity-disabled`、`wot-opacity-main` | ### 描边类 | 项目 | 内容 | | --- | --- | | 适用前缀 | `wot-border-stroke-*` | | 可用值 | `zero`、`light`、`main`、`bold` | | 示例 | `wot-border-stroke-main`、`wot-border-stroke-bold` | ### 开启 `baseTokens` 后可用 当 `baseTokens: true` 时,会额外开放基础色板与原始 token。 | 项目 | 内容 | | --- | --- | | 基础色 | `base-black`、`base-white`、`base-transparent` | | 色阶家族 | `blue-*`、`lightblue-*`、`pink-*`、`red-*`、`volcano-*`、`orange-*`、`yellow-*`、`green-*`、`cyan-*`、`purple-*`、`grape-*`、`coolgrey-*`、`neutralgrey-*`、`warmgrey-*` | | 色阶范围 | 每个家族支持 `1` ~ `10` | | 额外透明色 | 非 `grey` 家族额外支持 `*-opac` | | 透明阶 | `opac-1_02`、`opac-2_04`、`opac-3_08`、`opac-4_15`、`opac-5_20`、`opac-6_30`、`opac-7_45`、`opac-7_55`、`opac-8_65`、`opac-9_75`、`opac-10_85` | | 白色透明阶 | `opacwhite-1_02`、`opacwhite-2_04`、`opacwhite-3_08`、`opacwhite-4_15`、`opacwhite-5_20`、`opacwhite-6_30`、`opacwhite-7_45`、`opacwhite-7_55`、`opacwhite-8_65`、`opacwhite-9_75`、`opacwhite-10_85` | | 示例 | `wot-bg-base-black`、`wot-text-blue-6`、`wot-border-opac-3_08` | ## 导出内容 包默认导出 `presetWot`,并额外导出以下 token maps,便于业务侧复用: * `SEMANTIC_COLOR_MAP` * `BASE_COLOR_MAP` * `SPACING_MAP` * `PADDING_MAP` * `RADIUS_MAP` * `FONT_WEIGHT_MAP` * `TYPOGRAPHY_MAP` * `OPACITY_MAP` * `STROKE_MAP` --- --- url: 'https://starter.wot-ui.cn/guide/wot-ui.md' --- # Wot UI Wot UI 是一个轻量、美观、AI友好的 uni-app 组件库,提供80+高质量组件,支持暗黑模式、国际化和自定义主题。总之就是好用,爱用。它是本模板项目的组件库,当然本项目就是为它而生的。Wot UI 与 Wot Starter 团队高度重合,共享开发资源,快来使用吧。 ## 快速上手 请查看[快速上手](https://wot-ui.cn/guide/quick-use.html)文档。 ## 扫码体验 ## ✨ 特性 * 🎯 多平台覆盖,支持 微信小程序、支付宝小程序、钉钉小程序、H5、APP 等. * 🚀 80+ 个高质量组件,覆盖移动端主流场景. * 💪 使用 Typescript 构建,提供良好的组件类型系统. * 🤖 提供 AI 友好的设计系统. * 🌍 支持国际化,内置 15 种语言包. * 📖 提供丰富的文档和组件示例. * 🎨 支持修改 CSS 变量实现主题定制. * 🍭 支持暗黑模式 ## 赞助我们 如果您认为 Wot UI 帮助到了您的开发工作,您可以选择[赞助](https://wot-ui.cn/reward/reward.html)我们,赞助无门槛,哪怕是一杯柠檬水也好。 捐赠后您的昵称、留言等将会展示在[捐赠榜单](https://wot-ui.cn/reward/donor.html)中。 ## 生态 | 分类 | 项目 | 描述 | | --- | --- | --- | | 官方生态 | [wot-starter](https://starter.wot-ui.cn/) | Wot UI 官方快速起手项目 | | 官方生态 | [@wot-ui/router](https://my-uni.wot-ui.cn/) | Wot UI 官方路由与工程能力扩展 | | 官方生态 | [@wot-ui/cli](https://github.com/wot-ui/open-wot) | Wot UI 官方 AI 工具链与 CLI | | 官方生态 | [@wot-ui/unocss-preset](https://github.com/wot-ui/unocss-preset) | Wot UI 官方 UnoCSS 预设 | | 官方生态 | [VS Code 插件](https://marketplace.visualstudio.com/items?itemName=wot-ui.wot-ui-intellisense) | Wot UI 官方 VS Code 代码提示插件 | | 官方生态 | [小程序 CI 工具](https://github.com/Moonofweisheng/uni-mini-ci) | Wot UI 官方推荐的小程序 CI 工具 | | 官方生态 | [wot-starter-retail](https://github.com/wot-ui/wot-starter-retail) | Wot UI 官方零售行业模板方案 | | 开发资源 | [awesome-uni-app](https://github.com/uni-helper/awesome-uni-app) | 多端统一开发框架 uni-app 优秀开发资源汇总 | | 开发资源 | [create-uni](https://github.com/uni-helper/create-uni) | 快速创建 uni-app 项目 | | 开发资源 | [uni-ku](https://github.com/uni-ku) | uni-app 生态扩展与工具集合 | | 开发资源 | [uni-echarts](https://uni-echarts.xiaohe.ink/) | uni-app 图表组件与接入方案 | | 模板方案 | [vitesse-uni-app](https://vitesse-docs.netlify.app/) | 现代化 uni-app 基础模板 | | 模板方案 | [unibest](https://unibest.tech/) | 功能完善的 uni-app 开发模板 | ## 鸣谢 * [wot-design](https://github.com/jd-ftf/wot-design-mini) - 感谢 wot-design 团队多年来的不断维护,让 wot-ui 能够站在巨人的肩膀上。 * [uni-helper](https://github.com/uni-helper) - 感谢 uni-helper 团队提供的 uni-app 工具库,让 wot-ui 能够更方便地使用。 * [捐赠者](https://wot-ui.cn/reward/donor.html) - 感谢所有捐赠者,是你们的捐赠让 wot-ui 能够更好地发展。 ## 开源协议 本项目基于 [MIT](https://zh.wikipedia.org/wiki/MIT%E8%A8%B1%E5%8F%AF%E8%AD%89) 协议,请自由地享受和参与开源。 --- --- url: 'https://starter.wot-ui.cn/guide/introduction.md' --- # 介绍 Wot Starter 是一个基于 [vitesse-uni-app](https://github.com/uni-helper/vitesse-uni-app) 深度整合 [Wot UI V2](https://github.com/wot-ui/wot-ui) 组件库的快速启动模板,采用直观且可扩展的方式创建类型安全、高性能和生产级的跨端应用。你可以直接开始编写 `.vue` 文件,而无需从头开始配置。 ## 为什么 `uni-app` 背后的公司 DCloudio 选择创建自己的生态,比如 HBuilderX、uni\_modules 等。这部分工作对部分开发者来说意义非凡,他们可以轻松上手并享受社区提供的一切资源。 但是,`uni-app` 社区生态远不如 npm 生态繁荣,我们常常需要求助于 npm 生态来实现部分需求,而 `uni-app` 的黑盒性阻碍了这一点。 vitesse-uni-app 充分拥抱开放生态,比如 VS Code 和 npm,希望能带给你更好的体验。 同样的,基于以上前提,我们选择基于 vitesse-uni-app 深度整合 WotUI 为使用 WotUI 组件库的开发者提供一个拥有更好体验的快速启动模板。 当然,如果你希望使用一个相对纯净的启动模板, [vitesse-uni-app](https://github.com/uni-helper/vitesse-uni-app) 是一个绝佳选择。此外,仍可以使用 [create-uni](https://github.com/uni-helper/create-uni) 自行搭建启动模板。 ## 主要依赖 vitess-uni-app 主要由以下开源包组成: * 核心:[@uni-helper](https://uni-helper.cn/) * 引擎:[uni-app](https://github.com/dcloudio/uni-app) * 打包器:[Vite](http://vite.dev/) * CSS 样式:[UnoCSS](https://unocss.dev/) * 代码质量:[ESLint](https://github.com/uni-helper/eslint-config) 和 [TypeScript](https://www.typescriptlang.org/) wot-starter 在以上开源包的基础上引入了以下开源包: * 组件库:[Wot UI V2](https://github.com/wot-ui/wot-ui) * CI/CD:[uni-mini-ci](https://github.com/Moonofweisheng/uni-mini-ci) * 路由:[@wot-ui/router](https://github.com/wot-ui/my-uni) * 图表库:[uni-echarts](https://github.com/xiaohe0601/uni-echarts) * 网络请求:[Alova](https://github.com/alovajs/alova) * Pinia:[Pinia ](https://pinia.vuejs.org/zh/) ## 鸣谢 * [uni-helper](https://github.com/uni-helper) - 感谢 uni-helper 团队为 uni-app 开发体验优化做出的贡献。 * [vitesse-uni-app](https://github.com/uni-helper/vitesse-uni-app) - 感谢 vitesse-uni-app 提供的快速起手项目。 ## 开源协议 本项目基于 [MIT](https://zh.wikipedia.org/wiki/MIT%E8%A8%B1%E5%8F%AF%E8%AD%89) 协议,请自由地享受和参与开源。 --- --- url: 'https://starter.wot-ui.cn/guide/feedback.md' --- # 全局反馈组件 本项目基于 Pinia 和 Wot UI 封装了三类可全局调用的反馈能力:GlobalLoading、GlobalToast、GlobalDialog。它们适合在网络请求中间件、路由导航守卫以及其他不方便直接依赖页面内 hook 实例的场景中使用。 :::tip 提示 Wot UI 原生提供了 useToast、useDialog 等函数式能力,但调用侧通常仍要依赖对应组件实例。这里的全局反馈组件通过 Pinia 保存状态,并在组件内部监听状态后再调用 wd-toast 或 wd-dialog,因此可以把触发逻辑放到更靠近业务流程的位置,例如请求拦截器和路由守卫。 ::: ## 使用前提 使用这套全局反馈封装前,需要保证页面树中已经挂载以下组件实例: * GlobalLoading * GlobalToast * GlobalDialog 本项目通过组件自动导入支持直接使用这些组件;业务侧只需要调用对应的 composable: ```vue ``` 三个组件都会记录触发时所在页面路径,并且仅在相同页面内展示,避免切页后在错误页面继续显示旧反馈。 ## 全局加载 ### 概述 GlobalLoading 基于 Wot UI 的 wd-toast 封装,适合配合 axios、alova 等请求流程显示全局加载状态。 ### 组件特性 * 基于 wd-toast 实现 * 默认不自动关闭 * 默认显示遮罩,防止重复操作 * 自动记录当前页面路径,只在触发页面展示 ### 使用 ```ts import { useGlobalLoading } from '@/composables/useGlobalLoading' const loading = useGlobalLoading() ``` ### API #### loading(option) 显示加载状态。 ```ts loading.loading('加载中...') loading.loading({ msg: '数据加载中', cover: true, }) ``` 默认会合并以下配置: * iconName: loading * duration: 0 * cover: true * position: middle * show: true #### close() 关闭加载状态。 ```ts loading.close() ``` ### 参数说明 #### ToastOptions | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | msg | string | - | 加载文案 | | iconName | string | loading | 图标名称 | | duration | number | 0 | 持续时间,0 表示不自动关闭 | | cover | boolean | true | 是否显示遮罩 | | position | string | middle | 显示位置:top | middle | bottom | | show | boolean | true | 是否显示,内部状态字段 | #### 参数形式 支持两种调用方式: 1. 字符串:作为 msg 使用 2. 对象:传入完整 ToastOptions ### 示例 ```ts const { loading, close } = useGlobalLoading() async function fetchData() { try { loading('正在加载数据...') await api.getData() } finally { close() } } ``` ## 全局提示 ### 概述 GlobalToast 基于 Wot UI 的 wd-toast 封装,提供统一的全局轻提示能力。 ### 组件特性 * 基于 wd-toast 实现 * 支持 success、error、info、warning 四种快捷调用 * 支持自定义位置、时长、图标和遮罩 * 自动记录当前页面路径,只在触发页面展示 ### 使用 ```ts import { useGlobalToast } from '@/composables/useGlobalToast' const toast = useGlobalToast() ``` ### API #### show(option) 显示普通提示。 ```ts toast.show('这是一条提示信息') toast.show({ msg: '自定义提示', duration: 3000, position: 'top', }) ``` 默认配置: * duration: 2000 * show: false * 调用时自动补齐 show: true * 未传 position 时默认使用 middle #### success(option) 成功提示,默认附带 success 图标,duration 为 1500。 ```ts toast.success('操作成功') ``` #### error(option) 错误提示,默认附带 error 图标,direction 为 vertical。 ```ts toast.error('操作失败') ``` #### info(option) 信息提示,默认附带 info 图标。 ```ts toast.info('这是一条信息') ``` #### warning(option) 警告提示,默认附带 warning 图标。 ```ts toast.warning('警告信息') ``` #### close() 手动关闭当前提示。 ```ts toast.close() ``` ### 参数说明 #### ToastOptions | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | msg | string | - | 提示内容 | | duration | number | 2000 | 持续时间,0表示不自动关闭 | | position | string | middle | 显示位置:top | middle | bottom | | iconName | string | - | 图标名称 | | direction | string | - | 布局方向:horizontal | vertical | | cover | boolean | false | 是否显示遮罩 | | show | boolean | true | 是否显示,内部状态字段 | #### 参数形式 所有方法都支持两种调用方式: 1. 字符串:作为 msg 使用 2. 对象:传入完整 ToastOptions ## 全局弹窗 ### 概述 GlobalDialog 基于 Wot UI 的 wd-dialog 封装,用于统一处理提醒、确认和输入等交互流程。 ### 组件特性 * 基于 wd-dialog 实现 * 支持 alert、confirm、prompt 三种模式 * 支持 success、fail 回调 * 自动记录当前页面路径,只在触发页面展示 * 内部统一设置取消按钮和确认按钮为非圆角 ### 使用 ```ts import { useGlobalDialog } from '@/composables/useGlobalDialog' const dialog = useGlobalDialog() ``` ### API #### show(option) 显示通用弹窗。 ```ts dialog.show({ title: '提示', msg: '这是一条消息', success: (res) => console.log('成功', res), fail: (res) => console.log('失败', res), }) dialog.show('简单提示') ``` 注意:当参数为字符串时,实际会作为 title 使用。 #### alert(option) 显示提醒弹窗,只显示确认按钮。 ```ts dialog.alert('操作完成') dialog.alert({ title: '提醒', msg: '请注意查看结果', }) ``` #### confirm(option) 显示确认弹窗,自动开启取消按钮。 ```ts dialog.confirm('确定要删除吗?') dialog.confirm({ title: '确认删除', msg: '删除后不可恢复,确定要删除吗?', success: (res) => { if (res.action === 'confirm') { console.log('用户确认删除') } }, fail: (res) => { console.log('用户取消删除') }, }) ``` #### prompt(option) 显示输入弹窗,自动开启取消按钮。 ```ts dialog.prompt('请输入您的姓名') dialog.prompt({ title: '输入信息', msg: '请输入新的名称', inputValue: '默认值', inputPlaceholder: '请输入内容', success: (res) => { if (res.action === 'confirm') { console.log('用户输入:', res.value) } }, }) ``` #### close() 手动关闭弹窗。 ```ts dialog.close() ``` ### 参数说明 #### GlobalDialogOptions GlobalDialogOptions 基于 Wot UI 的 DialogOptions 扩展,并额外支持 success、fail 回调。 | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | title | string | - | 弹窗标题 | | msg | string | - | 弹窗内容 | | type | string | - | 弹窗类型:alert | confirm | prompt | | showCancelButton | boolean | 自动设置 | alert 为 false,confirm 和 prompt 为 true | | inputValue | string | - | prompt 模式下的输入框默认值 | | inputPlaceholder | string | - | prompt 模式下的输入框占位文案 | | success | Function | - | 点击确认后的回调 | | fail | Function | - | 取消或关闭后的回调 | | confirmButtonText | string | 取决于 wd-dialog 默认值 | 确认按钮文本 | | cancelButtonText | string | 取决于 wd-dialog 默认值 | 取消按钮文本 | #### DialogResult 回调参数会透传 wd-dialog 的结果对象,常用字段如下: | 参数 | 类型 | 说明 | |------|------|------| | action | string | 用户操作:confirm | cancel | | value | string | 输入框的值,仅 prompt 模式可用 | #### 参数形式 所有方法都支持两种调用方式: 1. 字符串:作为 title 使用 2. 对象:传入完整 GlobalDialogOptions ### 示例 ```ts const { confirm, alert, prompt } = useGlobalDialog() const { success, warning } = useGlobalToast() alert({ title: '重要提醒', msg: '这是一个重要提醒', }) confirm({ title: '确认操作', msg: '确定继续吗?', success: (res) => { if (res.action === 'confirm') { success('继续执行') } }, }) prompt({ title: '输入信息', msg: '请输入您的姓名', success: (res) => { if (res.action === 'confirm' && String(res.value || '').trim()) { success(`您好,${res.value}`) } else { warning('输入不能为空') } }, }) ``` ## 典型场景 ### 请求中间件中显示全局加载 ```ts const globalLoading = useGlobalLoading() globalLoading.loading('请求中...') try { await request() } finally { globalLoading.close() } ``` ### 路由守卫中显示确认弹窗 ```ts const { confirm } = useGlobalDialog() confirm({ title: '离开当前页面', msg: '表单尚未保存,确定离开吗?', success: (res) => { if (res.action === 'confirm') { // 继续跳转 } }, }) ``` ## 注意事项 1. GlobalLoading 和 GlobalToast 底层都调用 wd-toast,但使用了不同 selector,不会互相覆盖。 2. GlobalDialog 使用 wd-dialog,内容字段应使用 msg,而不是 message。 3. 三个 composable 都会记录 currentPage,仅在触发时所在页面展示反馈。 4. 使用 duration: 0 的提示或加载时,需要手动调用 close()。 5. 支付宝小程序场景下组件内部做了兼容处理,业务侧无需额外处理。 --- --- url: 'https://starter.wot-ui.cn/guide/bundle-optimizer.md' --- # 分包优化 本项目基于 [@uni-ku/bundle-optimizer](https://github.com/uni-ku/bundle-optimizer) 分包优化插件,实现 uni-app Vue3 项目分包优化插件,解决小程序主包体积超限问题。 :::tip 提示 本章节基于 @uni-ku/bundle-optimizer@2.x 版本编写,1.x 版本请参考 [@uni-ku/bundle-optimizer](https://github.com/uni-ku/bundle-optimizer) 文档处理。 ::: ## 插件简介 ### 为什么需要这个插件? uni-app Vue3(vite 构建)官方为了"简化配置",移除了 Vue2(webpack 构建)中内置的分包优化逻辑。这导致所有第三方库、公共组件、工具函数全部打进 `common/vendor.js`,主包体积瞬间超限,无法满足微信小程序 2 MB 限制。 **@uni-ku/bundle-optimizer** 把官方砍掉的「自动拆包」能力补了回来,并提供: * **分包优化**:自动将公共依赖抽离到主包,各分包仅保留自用代码 * **模块异步跨包调用**:使用 `import()` 语法异步引用模块 * **组件异步跨包引用**:通过 `componentPlaceholder` 配置实现 ### 功能特性 | 功能 | 说明 | |---|---| | 分包优化 | 自动将公共依赖抽离到主包,控制主包体积 | | 模块异步跨包调用 | 允许使用 `import()` 语法,异步引用 JS/TS 模块 | | 组件异步跨包引用 | 通过 `componentPlaceholder` 配置,实现组件异步跨包引用 | ### 适用范围 > ⚠️ **暂时不支持 App 平台** 适用于 uni-app CLI 或 HBuilderX 创建的 Vue3 项目 *** ## 快速上手 > 本项目已集成 @uni-ku/bundle-optimizer 插件,无需额外安装。 ### 1. 安装插件 ```bash pnpm add -D @uni-ku/bundle-optimizer ``` ### 2. 配置 vite.config.ts ```ts import { defineConfig } from 'vite' import uni from '@dcloudio/vite-plugin-uni' import Optimization from '@uni-ku/bundle-optimizer' export default defineConfig({ plugins: [ uni(), Optimization({ logger: false, // 是否输出日志 }), ], }) ``` ### 3. 开启微信小程序分包优化 在 `manifest.json` 或 `manifest.config.ts` 中配置: ```json { "mp-weixin": { "optimization": { "subPackages": true } } } ``` 或使用 `@uni-helper/vite-plugin-uni-manifest`: ```ts // manifest.config.ts import { defineManifestConfig } from '@uni-helper/vite-plugin-uni-manifest' export default defineManifestConfig({ 'mp-weixin': { optimization: { subPackages: true, }, }, }) ``` ### 4. (可选)添加 TypeScript 类型支持 在 `tsconfig.json` 中添加: ```json { "compilerOptions": { "types": ["@uni-ku/bundle-optimizer/client"] } } ``` 或在入口文件顶部添加: ```ts /// ``` *** ## 使用示例 ### 模块异步跨包调用 使用 ESM 原生异步导入语法 `import()` 来实现模块的异步引入: ```ts // 异步引入 JS/TS 模块 import('@/pages-sub-pkg/utils/encrypt.ts').then((mod) => { mod?.aesEncrypt('hello') }) // 或使用 async/await const mod = await import('@/pages-sub-pkg/utils/encrypt.ts') mod?.aesEncrypt('hello') ``` > ⚠️ **注意**:不要使用 `import('./Comp.vue').then(...)` 动态导入 Vue 文件,这会导致组件/页面空白,与分包优化逻辑冲突。 ### 组件异步跨包引用 通过 `componentPlaceholder` 配置实现组件异步跨包引用: #### 方式一:使用 ` ``` #### 方式二:使用选项式 API ```vue ``` > 💡 **提示**:`componentPlaceholder` 的值通常填写 `'view'` 即可。 *** ## 本项目中的使用 ### 配置说明 本项目已完整接入 `@uni-ku/bundle-optimizer` 插件,配置如下: #### vite.config.ts 配置 ```ts import Optimization from '@uni-ku/bundle-optimizer' export default defineConfig({ plugins: [ // ... 其他插件 Optimization({ logger: false, }), ], }) ``` #### manifest.config.ts 配置 ```ts export default defineManifestConfig({ 'mp-weixin': { optimization: { subPackages: true, }, }, }) ``` #### 分包配置 在 `vite.config.ts` 中配置了三个分包: ```ts UniHelperPages({ subPackages: [ 'src/subPages', 'src/subEcharts', 'src/subAsyncEcharts', ], }) ``` ### 实际使用示例 #### 异步组件跨包引用示例 在 `src/subAsyncEcharts/asyncEcharts/index.vue` 中,展示了如何异步引用来自 `src/subEcharts` 分包的图表组件: ```vue ``` 这个示例展示了: 1. 从 `subEcharts` 分包异步引用多个图表组件 2. 使用 `componentPlaceholder` 配置所有异步组件 3. 在模板中正常使用这些组件 ### 验证效果 构建项目并使用微信开发者工具查看主包大小: ```bash pnpm build:mp-weixin ``` 使用微信开发者工具的「构建分析」功能对比主包大小,可以看到分包优化带来的体积缩减效果。 *** ## 常见问题 ### Q: 主包体积没有变化? A: 检查 `manifest.json` 或 `manifest.config.ts` 中是否开启了 `mp-weixin.optimization.subPackages: true`。 ### Q: 组件或页面空白? A: 可能使用了 `import('./Comp.vue').then(...)` 动态导入 Vue 文件,请改用 `componentPlaceholder` 配置式方案。 ### Q: 如何配置异步组件? A: 使用 `componentPlaceholder` 配置,通常填 `'view'` 即可。 ### Q: 支持 App 平台吗? A: 暂不支持 App 平台,未来是否支持未知。 ### Q: 为什么要使用原生 `import()`? A: 降低学习成本,提供更好的 IDE 类型支持,并使代码更符合标准。 *** ## 参考资料 * [@uni-ku/bundle-optimizer 官方文档](https://github.com/uni-ku/bundle-optimizer) * [微信小程序分包异步加载](https://developers.weixin.qq.com/miniprogram/dev/framework/subpackages/async.html) --- --- url: 'https://starter.wot-ui.cn/guide/i18n.md' --- # 国际化 本章节将系统化地「拆解」uni-app 项目中的国际化实现流程,从环境搭建到实战应用,手把手教你使用 [vue-i18n](https://vue-i18n.intlify.dev/) 结合vscode插件 [i18n-ally](https://github.com/lokalise/i18n-ally) 与 [Wot UI V2](https://github.com/wot-ui/wot-ui) 构建灵活高效的多语言支持系统,包含了各类平台(H5、小程序、App)的适配要点与优化策略。准备好了吗?Let's go! 不对,应该是「出发吧」...哦等等,这不就是国际化的意义所在吗?😉 > 注意:本项目是基于 `Vue3` 和 `WotUI` 的 uni-app cli 框架开发的,如果你使用的是 Vue2,请参考 uni-app [文档](https://uniapp.dcloud.net.cn/tutorial/i18n.html#vue%E7%95%8C%E9%9D%A2%E5%92%8Cjs%E5%86%85%E5%AE%B9%E7%9A%84%E5%9B%BD%E9%99%85%E5%8C%96) 进行相应调整。 ## 1. 安装和配置vue-i18n ### 1.1 安装依赖 首先,我们需要安装vue-i18n: ```bash # 使用npm npm install vue-i18n@9.1.9 # 或者使用yarn yarn add vue-i18n@9.1.9 # 或者使用pnpm pnpm add vue-i18n@9.1.9 ``` > 注意:根据[uni-app官方文档](https://link.juejin.cn?target=https%3A%2F%2Funiapp.dcloud.net.cn%2Ftutorial%2Fi18n.html%23vue%25E7%2595%258C%25E9%259D%25A2%25E5%2592%258Cjs%25E5%2586%2585%25E5%25AE%25B9%25E7%259A%2584%25E5%259B%25BD%25E9%2599%2585%25E5%258C%2596 "https://uniapp.dcloud.net.cn/tutorial/i18n.html#vue%E7%95%8C%E9%9D%A2%E5%92%8Cjs%E5%86%85%E5%AE%B9%E7%9A%84%E5%9B%BD%E9%99%85%E5%8C%96")建议,Vue3项目需要安装vue-i18n的固定版本9.1.9,和uni-app内部使用的vue-i18n保持一致。 ### 1.2 创建i18n实例 在项目中创建一个专门的目录来存放国际化相关的文件,例如`src/locale`: ```typescript // src/locale/index.ts import { createI18n } from 'vue-i18n' import zhCN from './zh-CN.json' import enUS from './en-US.json' import Locale from '@wot-ui/locale/locale' import WotEnUS from '@wot-ui/locale/locale/lang/en-US' Locale.add({ 'en-US': WotEnUS }) const messages = { 'zh-CN': { ...zhCN }, 'en-US': { ...enUS } } // 创建i18n实例 const i18n = createI18n({ locale: uni.getStorageSync('currentLang') || 'zh-CN', // 默认语言 fallbackLocale: 'zh-CN', // 回退语言 messages, // 语言包 legacy: false // 启用Composition API模式 }) // 同步组件库语言 Locale.use(i18n.global.locale.value) uni.setLocale(i18n.global.locale.value) export default i18n ``` ### 1.3 在main.ts中注册i18n ```typescript // src/main.ts import { createApp } from 'vue' import App from './App.vue' import i18n from './locale' const app = createApp(App) app.use(i18n) app.mount('#app') ``` ## 2. 语言文件的组织结构 ### 2.1 基本结构 语言文件通常以JSON格式存储,每种语言一个文件: ```bash src/locale/ ├── index.ts # i18n配置和实例 ├── zh-CN.json # 中文语言包 └── en-US.json # 英文语言包 ``` ### 2.2 语言文件内容 语言文件是键值对的集合,键是唯一标识符,值是对应语言的文本: ```json // zh-CN.json { "hello": "你好", "welcome": "欢迎使用", "button": "按钮" } // en-US.json { "hello": "Hello", "welcome": "Welcome to use", "button": "Button" } ``` ### 2.3 嵌套结构 对于复杂应用,可以使用嵌套结构组织语言文件: ```json // zh-CN.json { "common": { "confirm": "确认", "cancel": "取消" }, "home": { "title": "首页", "welcome": "欢迎回来" } } ``` ## 3. 使用useI18nSync钩子实现多语言切换 在项目中,我们实现了一个`useI18nSync`钩子来同步应用和组件库的语言设置: ```typescript // src/hooks/useI18nSync.ts import { computed, onBeforeMount } from 'vue' import { Locale } from '@wot-ui/locale/locale' import i18n from '../locale' const SUPPORTED_LOCALES = [ 'zh-CN', 'en-US', ] function setLocale(locale: string, syncComponentLib: boolean = true) { if (!SUPPORTED_LOCALES.includes(locale)) { console.warn(`不支持的语言: ${locale},将使用默认语言 zh-CN`) locale = 'zh-CN' } uni.setLocale(locale) i18n.global.locale.value = locale uni.setStorageSync('currentLang', locale) if (syncComponentLib) { Locale.use(locale) } return locale } function initLocale(defaultLocale: string, syncComponentLib: boolean) { const storedLocale = uni.getStorageSync('currentLang') || defaultLocale setLocale(storedLocale, syncComponentLib) } interface I18nSyncOptions { /** 是否同步组件库语言设置 */ syncComponentLib?: boolean /** 默认语言 */ defaultLocale?: string } /** * 国际化同步hook * @param options 配置选项 * @returns 国际化相关方法和状态 */ export function useI18nSync(options?: I18nSyncOptions) { const { syncComponentLib = true, defaultLocale = 'zh-CN' } = options || {} const currentLang = computed(() => i18n.global.locale.value) onBeforeMount(() => { initLocale(defaultLocale, syncComponentLib) }) return { currentLang, setLocale: (locale: string) => setLocale(locale, syncComponentLib), supportedLocales: SUPPORTED_LOCALES } } ``` ### 3.1 在App.vue中初始化语言 ```vue ``` ### 3.2 实现语言切换功能 ```vue ``` ## 4. 在组件中使用国际化文本 ### 4.1 使用Composition API 在Vue3的Composition API中使用i18n: ```vue ``` ### 4.2 使用模板语法 直接在模板中使用$t函数: ```vue ``` ### 4.3 动态计算属性 使用computed使内容响应语言变化: ```vue ``` ## 5. 处理动态内容的国际化 ### 5.1 平台限制与解决方案 根据uni-app官方文档,由于运行平台限制,**目前在小程序和App端不支持插值方式定义国际化**。这意味着以下方式在小程序和App端无法正常工作: ```typescript // 这种方式在小程序和App端不支持 t('hello', { name: '小明' }) // 使用命名参数 t('hello', ['小明']) // 使用数组参数 ``` 为了解决这个问题,我们需要使用自定义的插值方法来处理带参数的翻译。 ### 5.2 带参数的翻译 在小程序和App端,我们需要使用特殊的占位符格式和自定义插值方法来处理包含变量的文本: ```typescript // 在语言文件中定义带占位符的文本 // zh-CN.json { "greeting": "你好,{0}!", "welcome": "欢迎{0}来到{1}" } // 使用时传入参数 t('greeting', ['小明']) // 输出:你好,小明! t('welcome', ['小明', 'wot-ui']) // 输出:欢迎小明来到 wot-ui ``` > 注意:我们使用`{0}`, `{1}`这样的数字索引占位符,而不是使用命名参数如`{name}`。这是因为小程序和App端不支持命名参数的插值方式。 ### 5.3 实现插值工具函数 ```typescript // src/locale/utils.ts /** * 替换字符串中的占位符 * @param template 模板字符串,如 "Hello {0}, welcome to {1}" * @param values 要替换的值数组 * @returns 替换后的字符串 */ export function interpolateTemplate(template: string, values: any[]): string { return template.replace(/{(\d+)}/g, (_, index) => values[index] ?? '') } ``` ### 5.4 扩展t函数支持数组参数 由于小程序和App端的限制,我们需要扩展vue-i18n的t函数,使其能够处理数组参数并应用我们的插值方法: ```typescript // src/locale/index.ts import { createI18n } from 'vue-i18n' import zhCN from './zh-CN.json' import enUS from './en-US.json' import { interpolateTemplate } from './utils' // 创建i18n实例 const i18n = createI18n({ locale: 'zh-CN', fallbackLocale: 'zh-CN', messages: { 'zh-CN': zhCN, 'en-US': enUS }, legacy: false }) // 扩展t函数,支持数组参数插值 // 这是解决小程序和App端不支持插值方式的关键步骤 const originalT = i18n.global.t i18n.global.t = ((key: string | number, param1?: any, param2?: any) => { const result = originalT(key, param1, param2) // 检测是否传入了数组参数,如果是则使用我们的插值方法处理 if (Array.isArray(param1)) { return interpolateTemplate(result, param1) } return result }) as typeof i18n.global.t export default i18n ``` 这种扩展方式的优点是: 1. 保持了与vue-i18n原有API的兼容性 2. 在小程序和App端也能使用类似的参数传递方式 3. 统一了不同平台的国际化使用体验 > 需要注意的是我们仅实现了数组参数的插值,如果需要支持更多参数类型,可以进一步扩展。 ### 5.5 使用示例 ```vue ``` > 注意:这种方法在H5、App和小程序等所有平台上都能正常工作,因为我们使用了自定义的插值方法来处理参数,绕过了小程序和App端的限制。 ## 6. 组件库的国际化 WotUI组件库本身支持国际化,我们只需要参考[国际化](https://wot-ui.cn/guide/locale.html)文档进行配置即可。 ### 6.1 同步应用和组件库的语言 使用`useI18nSync`钩子可以同步应用和组件库的语言设置: ```typescript // 同步组件库语言设置 if (syncComponentLib) { Locale.use(locale) } ``` ## 7. pages.json的国际化 > 注意:建议仔细阅读uni-app[国际化文档](https://link.juejin.cn?target=https%3A%2F%2Funiapp.dcloud.net.cn%2Ftutorial%2Fi18n.html%23vue%25E7%2595%258C%25E9%259D%25A2%25E5%2592%258Cjs%25E5%2586%2585%25E5%25AE%25B9%25E7%259A%2584%25E5%259B%25BD%25E9%2599%2585%25E5%258C%2596 "https://uniapp.dcloud.net.cn/tutorial/i18n.html#vue%E7%95%8C%E9%9D%A2%E5%92%8Cjs%E5%86%85%E5%AE%B9%E7%9A%84%E5%9B%BD%E9%99%85%E5%8C%96")。 ### 7.1 页面标题国际化 在uni-app中,pages.json中的页面标题可以通过占位符实现国际化: ```json // pages.json { "pages": [ { "path": "pages/index/index", "style": { "navigationBarTitleText": "%index-title%" } } ] } ``` ### 7.2 语言文件配置 在语言文件中添加对应的翻译: ```json // zh-CN.json { "index-title": "首页" } // en-US.json { "index-title": "Home" } ``` ### 7.3 平台差异处理 * **H5平台**:直接支持占位符方式 * **其他平台**:可以使用自定义Tabbar和Navbar实现 > 注意:小程序下不支持这种国际化方案,也可以使用设置tabbar和navigationbar的API来设置文字。或者废弃原生tabbar和navigationbar,使用自定义方式,详情参考[uni-app官方文档](https://link.juejin.cn?target=https%3A%2F%2Funiapp.dcloud.net.cn%2Ftutorial%2Fi18n.html%23pages "https://uniapp.dcloud.net.cn/tutorial/i18n.html#pages") ## 8. i18n-ally插件 ### 8.1 插件概述 i18n-ally是VSCode的一款国际化插件,提供以下核心功能: * 自动检测项目中的硬编码文本 * 一键提取待翻译内容 * 多语言文件管理 * 翻译辅助工具集成 ### 8.2 安装与配置 1. **安装插件**: * 在VSCode扩展市场搜索并安装`i18n-ally` * 安装完成后重启VSCode 2. **基本配置**: * 在项目根目录创建`.vscode/settings.json`文件 * 添加以下基础配置: ```json // .vscode/settings.json { "i18n-ally.sourceLanguage": "zh-CN", // 项目的​​原始语言(基准语言)​​,通常是开发时使用的默认语言(如 en 或 zh-CN)。 "i18n-ally.displayLanguage": "zh-CN", // 插件​​界面中显示的语言​​(如悬浮提示、侧边栏预览等),方便开发者查看翻译结果。 "i18n-ally.localesPaths": ["src/locale"], "i18n-ally.keystyle": "flat", "i18n-ally.sortKeys": true } ``` ![i18n-ally 设置示例](https://blog.wot-ui.cn/images/image_1_c3b9d87b.png) ### 8.3 核心功能详解 #### 8.3.1 自动检测 * 扫描范围:HTML标签内容、Vue模板、JS/TS代码 * 支持配置检测规则: ```json "i18n-ally.extract.parsers.html": { "attributes": ["text", "title", "alt", "placeholder", "label", "aria-label"], "ignoredTags": ["script", "style"], "vBind": true, "inlineText": true } ``` ![i18n-ally 检测规则示例](https://blog.wot-ui.cn/images/image_2_0c8f8aa3.png) #### 8.3.2 一键提取 * 自动生成翻译键 * 保持语言文件结构一致 * 支持批量处理 ![i18n-ally 一键提取示例](https://blog.wot-ui.cn/images/image_3_00d5556e.png) > 注意:提取的翻译键会自动添加到语言文件中,无需手动添加,但是批量提取的翻译键值会丢失插值参数,例如:`哈哈哈${232}`应当生成为`t('hahaha', [232])`,但实际上生成的是`t('ha-ha-ha-232-0')`,可以选择手动添加插值参数,或者结合[8.4.1 重构模板](#841-重构模板)进行优化。 #### 8.3.3 翻译辅助 i18n-ally内置翻译API支持,这里我们使用百度翻译API作为示例: 1. **注册账号**:访问[百度翻译开放平台](https://link.juejin.cn?target=https%3A%2F%2Ffanyi-api.baidu.com%2F "https://fanyi-api.baidu.com/")注册账号 2. **创建应用**:获取APP ID和密钥 3. **配置插件**: ```json "i18n-ally.translate.engines": ["baidu"], "i18n-ally.translate.baidu.appid": "YOUR_APP_ID", "i18n-ally.translate.baidu.key": "YOUR_SECRET_KEY" ``` ![i18n-ally 翻译配置示例](https://blog.wot-ui.cn/images/image_4_b160ce47.png) ### 8.4 高级配置 #### 8.4.1 重构模板 ```json "i18n-ally.refactor.templates": [ { "source": "html-inline", "template": "{{ $t('{key}'{args}) }}" }, { "source": "html-attribute", "template": "$t('{key}'{args})" } ] ``` 重构模板后,提取的翻译键会自动添加插值参数,例如:`哈哈哈${232}${111}`会生成为携带插值参数的格式`t('hahaha', 232, 111)`,不过`vue-i18n`的`t`方法不支持这种格式,所以我们需要再展t函数,支持可变参数,并将其作为数组参数插值。 ```typescript // src/locale/index.ts import { createI18n } from 'vue-i18n' import zhCN from './zh-CN.json' import enUS from './en-US.json' import Locale from '@wot-ui/locale/locale' import WotEnUS from '@wot-ui/locale/locale/lang/en-US' Locale.add({ 'en-US': WotEnUS }) const messages = { 'zh-CN': { ...zhCN }, 'en-US': { ...enUS } } // 创建i18n实例 const i18n = createI18n({ locale: uni.getStorageSync('currentLang') || 'zh-CN', fallbackLocale: 'zh-CN', messages, legacy: false }) Locale.use(i18n.global.locale.value) uni.setLocale(i18n.global.locale.value) const originalT = i18n.global.t i18n.global.t = ((key: string | number, ...args: any[]) => { /** * 替换字符串中的占位符 * @param template 模板字符串,如 "Hello {0}, welcome to {1}" * @param values 要替换的值数组 * @returns 替换后的字符串 */ function interpolateTemplate(template: string, values: any[]): string { return template.replace(/{(\d+)}/g, (_, index) => values[index] ?? '') } // 处理对象参数场景: t(key, {key1: value1, key2: value2}) if (args.length === 1 && typeof args[0] === 'object' && !Array.isArray(args[0])) { const result = originalT(key, ...args) return result } // 处理数组参数场景: t(key, [arg1, arg2]) if (args.length === 1 && Array.isArray(args[0])) { const result = originalT(key, args[0]) return interpolateTemplate(result, args[0]) } // 处理可变参数场景: t(key, arg1, arg2, ...) if (args.length > 1 && args.every((arg) => typeof arg !== 'object')) { return interpolateTemplate(originalT(key, args), args) } // 处理默认场景: t(key) 或 t(key, defaultMessage) 或 t(key, plural) 等 const result = originalT(key, ...args) return result }) as typeof i18n.global.t export default i18n ``` #### 8.4.2 忽略规则 ```json "i18n-ally.extract.ignored": [ "特定文本", "正则表达式", ] ``` ## 总结 至此,我们完成了国际化配置,并使用 `i18n-ally` 插件实现了对 Vue 组件的自动提取和翻译。你可以按照本章节在 wot-starter 中集成并实现国际化功能。 ## 参考资料 * [Vue i18n官方文档](https://vue-i18n.intlify.dev/) * [uni-app官方文档](https://uniapp.dcloud.net.cn/tutorial/i18n.html#vue%E7%95%8C%E9%9D%A2%E5%92%8Cjs%E5%86%85%E5%AE%B9%E7%9A%84%E5%9B%BD%E9%99%85%E5%8C%96) * [wot-ui官方文档](https://wot-ui.cn/) * [i18n-ally官方文档](https://github.com/lokalise/i18n-ally) --- --- url: 'https://starter.wot-ui.cn/guide/icons.md' --- # 图标使用 你可以使用多种方案来在项目中使用图标。一般情况下,可以直接使用 UI 组件库内置的图标,也可以使用更加灵活的 Iconify 图标集,以下是我们推荐的一些实践方案。 ## WotUI 内置图标 最简单的图标使用方式是使用 [WotUI](https://wot-ui.cn/component/icon.html) 的内置图标。 ```html 添加 ``` ## Iconify 图标集 如果你需要更多图标选择,可以使用 [Iconify](https://iconify.design/) 图标集配合 [UnoCSS](https://unocss.dev/) 使用,我们已经默认集成了 [Carbon](https://icones.js.org/collection/carbon) 图标集,也可以在 [Icones](https://icones.js.org/) 中搜索你需要的图标。 ```html ``` ### 常用 Carbon 图标 ```html
``` > 📖 **了解更多**: [Carbon 图标集](https://icones.js.org/collection/carbon) | [Iconify 官网](https://iconify.design/) | [Icones](https://icones.js.org/) --- --- url: 'https://starter.wot-ui.cn/guide/dark-mode.md' --- # 暗黑模式 ## 什么是暗黑模式 暗黑模式(Dark Mode),也被称为夜间模式或深色模式,是一种使用深色背景和浅色文字的界面显示模式。 ### 主要特点 * **护眼体验**: 在光线较暗的环境下减少眼部疲劳 * **节省电量**: 在 OLED 屏幕设备上能够显著节省电池消耗 * **视觉美观**: 提供现代化的视觉体验和专业感 ## 使用指南 本章节将介绍在 uni-app 项目中实现h5和微信小程序的暗黑模式功能的方案。你可以结合本文内容并参考 uni-app 官方的 [DarkMode 适配指南](https://uniapp.dcloud.net.cn/tutorial/darkmode.html) 来完成适配。 :::tip 提示 App端的暗黑模式适配,请参考 [App 端暗黑模式适配](https://uniapp.dcloud.net.cn/tutorial/darkmode.html#app-plus)完成,本章节暂不涉及。 ::: ## 适配组成 暗黑模式的完整适配包含以下几个核心部分: * **uni-app 平台配置**: 开启 [DarkMode](https://uniapp.dcloud.net.cn/tutorial/darkmode.html) 官方支持 * **UI 组件适配**: [Wot UI](https://wot-ui.cn/component/config-provider.html#%E6%B7%B1%E8%89%B2%E6%A8%A1%E5%BC%8F) 组件库的暗黑模式支持 * **样式系统适配**: [UnoCSS](https://unocss.dev/presets/mini#dark-mode) 暗黑模式工具类 ## uni-app 平台配置 uni-app 提供了官方的暗黑模式配置方案,通过 `manifest.json` 和 `theme.json` 实现平台级的主题支持,其指南已经比较详细,本章节将简单介绍一下,具体可以参考官方文档。 > 📖 **详细文档**: [uni-app 暗黑模式适配指南](https://uniapp.dcloud.net.cn/tutorial/darkmode.html#get-theme) ### 配置步骤 1. **在 `manifest.config.ts` 中开启暗黑模式** ```json // H5 配置 "h5": { "darkmode": true, "themeLocation": "theme.json" } // 微信小程序配置 "mp-weixin": { "darkmode": true, "themeLocation": "theme.json" } ``` 2. **创建 `theme.json` 主题变量文件** ```json { "light": { "navBgColor": "#f8f8f8", "navTxtStyle": "black", "bgColor": "#ffffff", "tabBgColor": "#ffffff", "tabSelectedColor": "#0165FF" }, "dark": { "navBgColor": "#000000", "navTxtStyle": "white", "bgColor": "#000000", "tabBgColor": "#1a1a1a", "tabSelectedColor": "#0165FF" } } ``` 3. **在 `pages.config.ts` 中引用主题变量** ```json { "globalStyle": { "navigationBarBackgroundColor": "@navBgColor", "navigationBarTextStyle": "@navTxtStyle", "backgroundColor": "@bgColor" }, "tabBar": { "backgroundColor": "@tabBgColor", "selectedColor": "@tabSelectedColor" } } ``` ### 获取当前主题 ```javascript // 获取系统主题信息 const systemInfo = uni.getSystemInfoSync() console.log('当前主题:', systemInfo.theme) // 'light' 或 'dark' // 监听主题变化 uni.onThemeChange((res) => { console.log('主题已切换到:', res.theme) }) ``` ### CSS 媒体查询适配 ```css /* 默认样式 */ .some-background { background: white; } /* 暗黑模式样式 */ @media (prefers-color-scheme: dark) { .some-background { background: #1b1b1b; } } ``` ## 主题管理 API 本项目提供了两种主题管理方案,**推荐优先使用自动暗黑模式方案**: > 📝 **项目说明**: 本演示项目为了展示完整的主题管理功能,默认使用了 `useManualTheme()`。在实际项目中,建议根据需求选择合适的方案,大多数情况下使用 `useTheme()` 即可满足需求。 ### 🌙 自动暗黑模式 - `useTheme()` ⭐ 推荐 **适用场景:** * 大多数应用的首选方案 * 只需要系统主题适应的应用 * 追求简洁和用户体验的应用 **功能特性:** * ✅ 自动跟随系统主题 * ✅ 导航栏颜色通过 theme.json 自动处理 * ✅ 轻量级,性能优秀 * ✅ 用户体验一致 ```vue ``` ### 🎨 手动主题管理 - `useManualTheme()` **适用场景:** * 需要用户手动控制主题的特殊应用 * 需要主题色自定义功能的应用 * 需要完整主题管理功能的复杂应用 **功能特性:** * ✅ 手动切换暗黑模式 * ✅ 主题色选择(6种预设颜色) * ✅ 跟随系统主题 * ✅ 自动同步导航栏颜色 * ✅ 持久化用户设置 > 💡 **建议**:除非有特殊需求,否则推荐使用 `useTheme()` 自动暗黑模式方案,它能提供更好的用户体验和性能表现。 ```vue ``` ## UI 组件适配 (Wot UI) [Wot Design Uni](https://wot-ui.cn/) 组件库原生支持暗黑模式,通过 `wd-config-provider` 组件可以轻松开启全局暗黑模式支持。 ### 全局配置 ```vue ``` ### 组件级配置 ```vue ``` > 📖 **详细文档**: [Wot UI 暗黑模式配置](https://wot-ui.cn/component/config-provider.html#%E6%B7%B1%E8%89%B2%E6%A8%A1%E5%BC%8F) ## 样式系统适配 (UnoCSS) ### UnoCSS dark 前缀 如果你使用 [UnoCSS](https://unocss.dev/presets/mini#dark-mode),可以使用 `dark:` 前缀来实现暗黑模式样式。 ```html 内容区域 ``` ### 样式适配方案 ```html 自动适配暗黑模式的内容 使用主题变量的内容 ``` ### 最佳实践 ```html ``` ## 移除暗黑模式功能 如果你的项目不需要暗黑模式功能,可以按照以下步骤完全移除相关代码: ### 1. 移除官方配置 ```json // src/manifest.config.ts { "h5": { // "darkmode": true, // 删除这行 // "themeLocation": "theme.json" // 删除这行 }, "mp-weixin": { // "darkmode": true, // 删除这行 // "themeLocation": "theme.json" // 删除这行 } } ``` ### 2. 删除主题配置文件 ```bash # 删除主题配置文件 rm src/theme.json ``` ### 3. 简化主题管理逻辑 ```typescript // src/composables/useTheme.ts - 简化版本(仅保留系统主题跟随) export function useTheme() { const currentThemeColor = ref(themeColorOptions[0]) // 只保留主题色功能,移除明暗模式切换逻辑 function selectThemeColor(option: ThemeColorOption) { currentThemeColor.value = option } return { currentThemeColor: computed(() => currentThemeColor.value), themeColorOptions, selectThemeColor, } } // 如果需要完全移除主题功能,删除以下文件: // - src/composables/useTheme.ts // - src/composables/useManualTheme.ts // - src/store/themeStore.ts // - src/store/manualThemeStore.ts ``` ### 4. 清理样式代码 ```css /* 移除暗黑模式相关样式 */ .container { background: white; color: black; /* 移除:dark:bg-gray-900 dark:text-white */ } /* 移除媒体查询 */ /* @media (prefers-color-scheme: dark) { .container { background: #1a1a1a; color: white; } } */ ``` ### 5. 更新组件使用 ```vue ``` ### 6. 完全移除(可选) 如果要完全移除主题功能: ```bash # 删除主题相关文件 rm src/composables/useTheme.ts rm src/composables/useManualTheme.ts rm src/store/themeStore.ts rm src/store/manualThemeStore.ts # 从 pages.json 中移除主题变量引用 # 将 @navBgColor 等变量替换为具体颜色值 ``` ```json // pages.json - 替换主题变量 { "globalStyle": { "navigationBarBackgroundColor": "#ffffff", // 替换 @navBgColor "navigationBarTextStyle": "black", // 替换 @navTxtStyle "backgroundColor": "#f8f8f8" // 替换 @bgColor } } ``` 移除后,你的应用将只使用固定的明亮主题,减少代码复杂度和包体积。 > 📖 **了解更多**: [uni-app 暗黑模式适配指南](https://uniapp.dcloud.net.cn/tutorial/darkmode.html) --- --- url: 'https://starter.wot-ui.cn/guide/changelog.md' --- # 更新日志 ## [2.0.0](https://github.com/wot-ui/wot-starter/compare/v1.5.0...v2.0.0) (2026-04-21) ### ✨ Features | 新功能 * ✨ 集成 @wot-ui/vitepress-theme ([341f935](https://github.com/wot-ui/wot-starter/commit/341f935fef0da676c7f002506b51662baff09025)) * ✨ 支持 wot-ui v2 ([874455f](https://github.com/wot-ui/wot-starter/commit/874455f80abdd97d8ef11b4624d169ac3020a100)) ### ✏️ Documentation | 文档 * ✏️ 更新全局反馈组件文档,增加使用前提和示例 ([8866c45](https://github.com/wot-ui/wot-starter/commit/8866c459a0b33d933a1cbfecaacb4d3673a85351)) ### 🐛 Bug Fixes | Bug 修复 * 🐛 更新 banner URLs 为 wot-starter-v2-banner.json ([aa773d4](https://github.com/wot-ui/wot-starter/commit/aa773d409db38c041ba0e32b68602dc55f3fd2ec)) ## [1.5.0](https://github.com/wot-ui/wot-starter/compare/v1.4.0...v1.5.0) (2026-04-07) ### ✨ Features | 新功能 * ✨ add wot-ui skill ([2b9b664](https://github.com/wot-ui/wot-starter/commit/2b9b664a087ca25fba26bcde22d1337a8d00309d)) ### ✏️ Documentation | 文档 * ✏️ add wot-ui skill docs ([1c15e03](https://github.com/wot-ui/wot-starter/commit/1c15e03c47a1e6cdc3eb0e53cd65b41ef2dadf01)) ## [1.4.0](https://github.com/wot-ui/wot-starter/compare/v1.3.2...v1.4.0) (2026-01-25) ### ✏️ Documentation | 文档 * ✏️ remove gitee-vote-2025 ([ed32556](https://github.com/wot-ui/wot-starter/commit/ed32556db46d7922cde1a60d1efc32bfb1c87d63)) ### 🐛 Bug Fixes | Bug 修复 * 🐛 仅在微信小程序端开启 optimization 修复运行到支付宝小程序报错的问题 ([420aff4](https://github.com/wot-ui/wot-starter/commit/420aff484878ff88934b913d9aa84916a36c2de8)) ### ✨ Features | 新功能 * ✨ 添加基于本项目实际使用场景的 Agent Skills ([f2a58f7](https://github.com/wot-ui/wot-starter/commit/f2a58f748c8758b4a083fa7181862dc1ad97e303)) * ✨ 新增清理演示页面提供精简模板的 skill starter-cleaner ([8b4c4c4](https://github.com/wot-ui/wot-starter/commit/8b4c4c4d0c9abdee1616484a435444c9ae4ce000)) ### [1.3.2](https://github.com/wot-ui/wot-starter/compare/v1.3.1...v1.3.2) (2026-01-07) ### ✨ Features | 新功能 * ✨ 升级 @uni-ku/bundle-optimizer 至 2.0 并处理相关迁移配置 ([e0ab94c](https://github.com/wot-ui/wot-starter/commit/e0ab94cfd7e9971b52c929de5d89e7c5ab11eb3a)) ### [1.3.1](https://github.com/wot-ui/wot-starter/compare/v1.3.0...v1.3.1) (2026-01-05) ### ✨ Features | 新功能 * ✨ 更新 @wot-ui/router 以修复 route 类型问题和 afterEach多次触发的问题 ([fd4f585](https://github.com/wot-ui/wot-starter/commit/fd4f58524bc580a3f3cc249a9447d7c3d0c556d5)) ## [1.3.0](https://github.com/wot-ui/wot-starter/compare/v1.2.2...v1.3.0) (2026-01-04) ### ✨ Features | 新功能 * ✨ 更新 wot-ui 到 v1.14.0 版本 ([4fd2532](https://github.com/wot-ui/wot-starter/commit/4fd25328ba5c3d3e7ea202919071cd8fb98ffd74)) ### [1.2.2](https://github.com/wot-ui/wot-starter/compare/v1.2.1...v1.2.2) (2025-12-29) ### ✨ Features | 新功能 * ✨ 替换 uni-mini-router 为 @wot-ui/router ([171f054](https://github.com/wot-ui/wot-starter/commit/171f054ac7bb0976ee26edcbf4028c80cc4387a2)) ### ✏️ Documentation | 文档 * ✏️ 调整路由文档和演示demo ([73a9cf3](https://github.com/wot-ui/wot-starter/commit/73a9cf36b5b770a556e2ea74be9c5c21602ff661)) * ✏️ 更新 readme ([6bf2618](https://github.com/wot-ui/wot-starter/commit/6bf261833a6a8485c749c0123e3e8ba7b306156e)) * ✏️ 更新分包调整后demo的地址 ([5e358ec](https://github.com/wot-ui/wot-starter/commit/5e358ec27997c5437043ec3137cfbd4513154fd4)) * ✏️ 更新文档首页介绍内容 ([3a1a0a4](https://github.com/wot-ui/wot-starter/commit/3a1a0a409effcc730064d1acc1edc64fe58fd7d1)) * ✏️ 添加 PageSpy 远程的教程 ([f29a53c](https://github.com/wot-ui/wot-starter/commit/f29a53cd01cdc80c45e858e409f1564cf7716f73)) * ✏️ add about me ([046897a](https://github.com/wot-ui/wot-starter/commit/046897a862e402fd8ebbd993cac525de5e830f25)) * ✏️ add gitee vote 2025 ([14af7a0](https://github.com/wot-ui/wot-starter/commit/14af7a04cf1e26772782f0cad0d426e220dba40a)) ### [1.2.1](https://github.com/wot-ui/wot-starter/compare/v1.2.0...v1.2.1) (2025-12-04) ### 🐛 Bug Fixes | Bug 修复 * **manualTheme:** 修复跟随系统自动切换主题失效的问题 ([380c702](https://github.com/wot-ui/wot-starter/commit/380c7026eeb37a12e9a2866b18bd70880efdfecc)) ### ✨ Features | 新功能 * **index:** 首页设置中新增"跟随系统"按钮 ([d031788](https://github.com/wot-ui/wot-starter/commit/d031788d4c9b31a7d030f17856f69f2d177eb1b8)) * **logo:** 更新logo ([550caa2](https://github.com/wot-ui/wot-starter/commit/550caa243e423969745d62c3872dfae14976409a)) ### ✏️ Documentation | 文档 * ✏️ 更新 logo ([0e57c45](https://github.com/wot-ui/wot-starter/commit/0e57c45b94284320d5fdc3be6c082faf12ddcbad)) * ✏️ 首页添加 uni-ku 插件入口 ([a5b05c9](https://github.com/wot-ui/wot-starter/commit/a5b05c9091f5396c27c556ed23eed87b7f06fef0)) * ✏️ 文档增加显示版本号 ([10b7078](https://github.com/wot-ui/wot-starter/commit/10b707810529af53bd2a85fca6624807b5b2d9ec)) * ✏️ 移动非主包必需示例页面到分包中 ([#43](https://github.com/wot-ui/wot-starter/issues/43)) ([3d7a076](https://github.com/wot-ui/wot-starter/commit/3d7a07619cf4b84c26a91b5028b2635bcc6d44ff)), closes [#35](https://github.com/wot-ui/wot-starter/issues/35) * ✏️ update logo ([6b9e4f9](https://github.com/wot-ui/wot-starter/commit/6b9e4f9e66d7be10b1e678b46472c9e44a270fc3)) ## [1.2.0](https://github.com/wot-ui/wot-starter/compare/v1.1.0...v1.2.0) (2025-11-26) ### ✨ Features | 新功能 * ✨ 合并模板与文档项目开发便利性优化 ([#41](https://github.com/wot-ui/wot-starter/issues/41)) ([646d215](https://github.com/wot-ui/wot-starter/commit/646d2158c96dcf83518ed22bc27cc8e20f2ed0d2)), closes [#35](https://github.com/wot-ui/wot-starter/issues/35) * ✨ 支持 esm 并更新 unocss 和 [@uni-helper](https://github.com/uni-helper) 插件 ([#39](https://github.com/wot-ui/wot-starter/issues/39)) ([f433b49](https://github.com/wot-ui/wot-starter/commit/f433b49023c572488254b18584a4dbca0ba66336)) ### ✏️ Documentation | 文档 * ✏️ 添加 vite base ([b6f5cf8](https://github.com/wot-ui/wot-starter/commit/b6f5cf83084d0cc04bc94c9714722a7a4c9e6327)) * ✏️ 增加更新日志入口 ([7037d8f](https://github.com/wot-ui/wot-starter/commit/7037d8f10a9aa0274d5cc5d7afc8978342f96f1a)) ## [1.1.0](https://github.com/wot-ui/wot-starter/compare/v1.0.0...v1.1.0) (2025-11-12) ### ✨ Features | 新功能 * ✨ 添加 uni\_modules 插件引入示例 ([8493761](https://github.com/wot-ui/wot-starter/commit/8493761ad6ea4e6478d3b7764b43b813e5178e86)) * ✨ 支持 harmony next 自定义 tabbar ([f71e8ba](https://github.com/wot-ui/wot-starter/commit/f71e8ba62504a4c0b79d02e61979b52e1f538e59)) ## 1.0.0 (2025-10-28) ### 🐛 Bug Fixes | Bug 修复 * 🐛 修复分包路由未注册的问题 ([3da843b](https://github.com/wot-ui/wot-starter/commit/3da843ba33bf62d2a8032dabf3061b2ce87e46a9)) ### ✏️ Documentation | 文档 * ✏️ 更新 README ([a630274](https://github.com/wot-ui/wot-starter/commit/a63027496f9f75e8106437bf7e4285164a7f91b1)) * ✏️ 更新README ([abde3bc](https://github.com/wot-ui/wot-starter/commit/abde3bca57cbee293d0751dd6f273366425e2474)) * ✏️ 添加分包示例 ([809b65b](https://github.com/wot-ui/wot-starter/commit/809b65b8384029d9ed2c7807709023d65bf6bb4c)) * **README:** ✏️ 更新 vitesse-uni-app 项目链接 ([#11](https://github.com/wot-ui/wot-starter/issues/11)) ([6f1585a](https://github.com/wot-ui/wot-starter/commit/6f1585a6da97a9aeed4071125e6b618f30a50bb7)) ### ✨ Features | 新功能 * ✨ 全局反馈组件兼容支付宝小程序 ([7f04d43](https://github.com/wot-ui/wot-starter/commit/7f04d43d44b6eaedabcf32d6c5842b056a0ac8ba)) * ✨ 新增主题切换示例 ([#4](https://github.com/wot-ui/wot-starter/issues/4)) ([c39e756](https://github.com/wot-ui/wot-starter/commit/c39e756821b08ba9934c88f5576d6eabda8fd449)) * ✨ 引入 @uni-ku/root 解决使用 page-meta 和根组件的问题 ([989e9fd](https://github.com/wot-ui/wot-starter/commit/989e9fd05a9c5a3b103608c941e5e30040a19f32)) * ✨ 引入 uni-echarts 支持图表功能,增加分包异步化示例 ([f933a61](https://github.com/wot-ui/wot-starter/commit/f933a6143d5fe02783ade63c669001245970756e)) * ✨ 引入 vite-plugin-uni-pages 的 definePage 宏,优化开发体验 ([498df4f](https://github.com/wot-ui/wot-starter/commit/498df4f26b1a84e8e91827178167ff853ae1f1a9)) * 升级 uni-echarts 版本 ([#17](https://github.com/wot-ui/wot-starter/issues/17)) ([af94964](https://github.com/wot-ui/wot-starter/commit/af9496440e440afae589277c12999644ccfffe3e)) --- --- url: 'https://starter.wot-ui.cn/guide/state-management.md' --- # 状态管理 得益于组合式方法(Composition API),管理状态非常简单,本项目已经集成了 [Pinia](#pinia) ,并提供了简易集成方案,可以直接使用。 ## Pinia [Pinia](https://pinia.vuejs.org/zh/) 是 `Vue` 官方最新推荐的状态管理库,本项目已集成此方案,无需额外安装。 ```shell pnpm install pinia ``` 安装依赖后,需要做基本设置。 :::code-group ```ts [main.ts] import { createSSRApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' const pinia = createPinia() pinia.use(persistPlugin) export function createApp() { const app = createSSRApp(App).use(pinia); return { app, } } ``` ```ts import { defineStore } from 'pinia'; export const useCounterStore = defineStore('counter', () => { const count = ref(0) function increment() { count.value++ } return { count, increment } }) ``` ```vue ``` ::: ### 持久化配置 本项目添加了一个简易插件实现 Pinia 持久化,默认持久化所有 Store 数据,如需排除某些数据,可以在 [persist](https://github.com/wot-ui/wot-starter/blob/main/src/store/persist.ts) 中添加排除名单: ```typescript // src/store/persist.ts ... export function persistPlugin(context: PiniaPluginContext) { // 传入排除列表(store 名单) persist(context, ['temp']) } ... ``` > 也可以使用 [pinia-plugin-persistedstate](https://github.com/prazdevs/pinia-plugin-persistedstate) 等 `Pinia` 持久化插件,如果你使用过 `vuex-persistedstate` 想必对它会很熟悉,值得注意的是 `uni-app` 的 [storage](https://uniapp.dcloud.net.cn/api/storage/storage.html) 与传统web并非一致,所以需要手动配置该插件使用`uni-app` 的 `storage`。 ## 简单状态管理 你可以直接使用 `Vue` 提供的 `ref` 或 `reactive` 方法来做简单状态管理。 ### ref ::: code-group ```ts // 全局状态 const globalCount = ref(1) export function useCount() { // 本地状态 const localCount = ref(1) function increment() { globalCount.value++ localCount.value++ } return { globalCount, localCount, increment } } ``` ```vue ``` ::: ### reactive ::: code-group ```ts export const countStore = reactive({ count: 0, increment() { this.count++ } }) ``` ```vue ``` ::: ::: tip 以上例子修改自 Vue 文档的 [用响应式 API 做简单状态管理](https://cn.vuejs.org/guide/scaling-up/state-management.html#simple-state-management-with-reactivity-api)。 ::: ## VueUse 你也可以使用 VueUse 提供的 `createGlobalState` 进行状态管理,你还可以配合 `useStorage` 做数据持久。 :::code-group ```ts export const useAuth = createGlobalState(() => { const token = useStorage('token', '', uniStorage) const isLogin = computed(() => !!token.value) const login = (_token: string) => { token.value = _token } const logout = () => { token.value = '' } return { token, isLogin, login, logout, } }) ``` ```ts // storage adapter export const uniStorage = { getItem(key: string) { return uni.getStorageSync(key) || null }, setItem(key: string, value: any) { return uni.setStorageSync(key, value) }, removeItem(key: string) { return uni.removeStorageSync(key) }, } ``` ::: ::: warning 如果你正在使用 VueUse v10 并遇到了问题,请查看 [dcloudio/uni-app#4604](https://github.com/dcloudio/uni-app/issues/4604) 获取解决方案。 ::: --- --- url: 'https://starter.wot-ui.cn/guide/request.md' --- # 网络请求 你可以使用你喜欢的第三方请求库来获取数据。一般情况下,直接使用 `uni-app` 内置方法即可,以下是我们推荐的一些实践方案,本项目内置的请求库是 [alova](#alova) ,可以接着向下看。 ## `uni-app` 内置方法 `uni-app` 提供了 [uni.request](https://uniapp.dcloud.net.cn/api/request/request.html)、[uni.uploadFile](https://uniapp.dcloud.net.cn/api/request/network-file.html#uploadfile)、[uni.downloadFile](https://uniapp.dcloud.net.cn/api/request/network-file.html#downloadfile)、[WebSocket](https://uniapp.dcloud.net.cn/api/request/websocket.html) 等支持。一般情况下,你可以直接使用它们。 ## axios 如果你更喜欢 [axios](https://github.com/axios/axios) 及其相关生态,你可以使用 [@uni-helper/axios-adapter](https://github.com/uni-helper/axios-adapter)。它是专为 `uni-app` 打造的 `axios` 适配器,支持全平台! ```ts import axios from 'axios' import { createUniAppAxiosAdapter } from '@uni-helper/axios-adapter' axios.defaults.adapter = createUniAppAxiosAdapter() const { data, isFinished } = useAxios('/user?ID=12345') ``` ## @uni-helper/uni-network [@uni-helper/uni-network](https://github.com/uni-helper/uni-network) 是一个为 `uni-app` 打造的基于 `Promise` 的 HTTP 客户端,灵感和代码绝大部分源于 `axios@0.27.2`。`@uni-helper/uni-network` 在底层做了 `uni-app` 适配,体积更小,TypeScript 类型更贴近 `uni-app`。 ```ts import { un } from '@uni-helper/uni-network' try { const response = await un.get('/user?ID=12345') console.log(response) } catch (error) { console.error(error) } ``` ## alova [Alova](https://github.com/alovajs/alova) 是一个极致高效的请求工具集,本项目已集成此方案,无需额外安装。 :::danger ⚠️ 非常重要 我们通过[@alova/wormhole](https://alova.js.org/zh-CN/tutorial/getting-started/extension-integration) 完成了编辑器扩展集成,集成 alova 的编辑器扩展可以让它展现出它更强大的力量。 * 自动生成请求代码和响应数据类型,在 js 项目中也能体验对接口数据的智能提示。 * 将 api 文档嵌入代码中,带你体验边查边用 API 的效果。 * 定时更新 api 并主动通知前端开发,不再依赖服务端开发人员通知。 但是此方案在部分小程序平台存在`globalThis`报错问题,请参考[#657](https://github.com/alovajs/alova/issues/657),本项目通过 `AutoImport` 临时处理。 ::: ### 特性 * 简单易用,[观看视频](https://alova.js.org/video-tutorial)5分钟上手。 * 完美兼容你最喜欢的技术栈。 * 20+ 高性能的业务模块,帮助你快速开发性能更好的应用。 * 更先进的 openAPI 解决方案,在代码中和API信息高效交互。 * 请求共享和响应缓存,提升应用性能。 * 类型安全。 ### 有什么不同吗? 与 `@tanstack/react-query`、`swrjs`、`ahooks` 的 `useRequest` 等库不同,alova 旨在让API集成变得非常轻松高效,还能保持更高效的数据交互,为用户带来更流畅的体验。 > 您还可以查看 [与其他请求库的比较](https://alova.js.org/about/comparison) 以详细了解 alova 的不同之处。 ### 基础使用 ```typescript // 定义 API import { createAlova } from 'alova' import { uniappAdapter } from '@alova/adapter-uniapp' const alova = createAlova({ baseURL: 'https://api.example.com', ...uniappAdapter(), responded: response => response.data }) // 定义请求方法 const getUserInfo = (id: string) => alova.Get(`/user/${id}`) const updateUser = (data: UserInfo) => alova.Post('/user', data) ``` ### useRequest Hook ```typescript // 使用 useRequest 发送请求 const { data, // 响应数据 loading, // 加载状态 error, // 错误信息 send, // 手动发送请求 onSuccess, // 成功回调 onError, // 错误回调 } = useRequest(getUserInfo('123'), { immediate: true, // 立即发送请求 }) // 监听请求状态 onSuccess((data) => { console.log('请求成功:', data) }) onError((error) => { console.error('请求失败:', error) }) ``` ### 高级特性 ```typescript // 请求去重 const { data } = useRequest(getUserInfo('123'), { shareRequest: true // 相同请求自动去重 }) // 响应缓存 const { data } = useRequest(getUserInfo('123'), { cacheFor: 300000 // 缓存5分钟 }) // 分页请求 const { data: list, page, pageSize, total, isLastPage, loading, loadMore, loadPrev, refresh } = usePagination( (page, pageSize) => getApiList({ page, pageSize }), { initialPage: 1, initialPageSize: 10 } ) ``` ### 移除 alova 如果你不需要使用 alova 作为请求库,可以按照以下步骤将其从项目中移除: 1. **卸载依赖包** ```bash npm uninstall alova @alova/adapter-uniapp @alova/mock @alova/shared @alova/wormhole # 或者使用 pnpm pnpm remove alova @alova/adapter-uniapp @alova/mock @alova/shared @alova/wormhole ``` 2. **删除相关配置文件** * 删除 `src/api/` 目录下的 alova 相关配置文件 * 移除项目中引入 alova 的代码 * 移除`alova.config.ts`文件 3. **替换为其他请求方案** * 可以选择上述提到的 [axios](#axios)、[@uni-helper/uni-network](#uni-helperuni-network) 或直接使用 [uni-app 内置方法](#uni-app-内置方法) 4. **更新相关引用** * 查找并替换项目中所有使用 `useRequest`、`usePagination` 等 alova hooks 的地方 * 更新对应的导入语句 > 💡 **提示**: 移除前建议先备份项目,确保不会影响现有功能。 > 📖 **了解更多**: [Alova 官方文档](https://alova.js.org/zh-CN/) --- --- url: 'https://starter.wot-ui.cn/guide/tabbar.md' --- # 自定义 Tabbar 本项目基于 [Wot UI](https://wot-ui.cn/) 的 `wd-tabbar` 组件,提供自定义 Tabbar 的实现。 ## 实现原理 项目的自定义 Tabbar 主要由以下三个部分组成: 1. **配置文件** (`pages.config.ts`) - 启用自定义 Tabbar 并配置基础信息 2. **组件实现** (`src/layouts/tabbar.vue`) - 自定义 Tabbar 的视图层 3. **状态管理** (`src/composables/useTabbar.ts`) - Tabbar 的逻辑和状态管理 当前实现中,`tabbar.vue` 会在 APP 端调用 `uni.hideTabBar()` 隐藏原生 Tabbar,并通过 `router.pushTab` 切换页面。 ## 添加 Tabbar 项 ### 1. 修改配置文件 在 `pages.config.ts` 中的 `tabBar.list` 数组中添加新的页面路径: ```typescript tabBar: { custom: true, // ... 其他配置 list: [{ pagePath: 'pages/index/index', }, { pagePath: 'pages/about/index', }, { // 添加新的tabbar项 pagePath: 'pages/new-page/index', }], } ``` ### 2. 更新状态管理 在 `src/composables/useTabbar.ts` 中的 `tabbarItems` 数组中添加对应的配置: ```typescript const tabbarItems = ref([ { name: 'home', active: true, title: '首页', icon: 'home' }, { name: 'about', active: false, title: '关于', icon: 'user' }, // 添加新的tabbar项 { name: 'new-page', active: false, title: '新页面', icon: 'star' }, ]) ``` ### 3. TabbarItem 接口说明 ```typescript interface TabbarItem { name: string // 页面名称,对应路由name value?: number // 徽标数值,不传表示不显示徽标 active: boolean // 是否为当前激活项 title: string // 显示标题 icon: string // 图标名称 } ``` ## 配置图标 ### 图标来源 项目使用 [Wot UI](https://wot-ui.cn/) 的内置图标库。你可以通过以下方式查看可用图标: 1. 访问 [Wot UI 图标文档](https://wot-ui.cn/component/icon.html) 2. 查看所有可用的图标名称 ### 修改图标 在 `src/composables/useTabbar.ts` 中修改对应项的 `icon` 字段: ```typescript const tabbarItems = ref([ { name: 'home', active: true, title: '首页', icon: 'home' }, { name: 'about', active: false, title: '关于', icon: 'user' }, ]) ``` ### 常用图标示例 ```typescript // 常用的tabbar图标 'home' // 首页 'user' // 用户/关于 'shopping-bag' // 购物 'star' // 收藏 'setting' // 设置 'message' // 消息 'search' // 搜索 'calendar' // 日历 ``` ### 使用自定义图标 如果内置图标不能满足需求,你可以使用 `wd-tabbar-item` 的 `icon` 插槽来自定义图标。 #### 修改 tabbar.vue 组件 在 `src/layouts/tabbar.vue` 中使用插槽自定义图标: ```vue ``` #### 更新 TabbarItem 接口 ```typescript interface TabbarItem { name: string // 页面名称,对应路由name value?: number // 徽标数值,不传表示不显示徽标 active: boolean // 是否为当前激活项 title: string // 显示标题 icon: string // 图标名称(使用内置图标时) activeIcon?: string // 激活状态自定义图标路径 inactiveIcon?: string // 未激活状态自定义图标路径 } ``` #### 配置自定义图标 ```typescript const tabbarItems = ref([ { name: 'home', active: true, title: '首页', icon: 'home', activeIcon: '/static/icons/home-active.png', inactiveIcon: '/static/icons/home.png' }, { name: 'about', active: false, title: '关于', icon: 'user', activeIcon: '/static/icons/about-active.png', inactiveIcon: '/static/icons/about.png' }, ]) ``` > 📖 **了解更多**: 查看 [wd-tabbar 组件文档](https://wot-ui.cn/component/tabbar.html) 了解更多自定义选项和插槽用法。 ## 徽标配置 自定义 Tabbar 支持显示徽标,通过 `setTabbarItem` 方法为 Tabbar 项设置徽标数值。 ### 显示徽标 使用 `setTabbarItem` 方法为 Tabbar 项设置徽标数值: ```typescript const { setTabbarItem } = useTabbar() // 为 'about' 页面设置徽标数值为 5 setTabbarItem('about', 5) ``` ### 清除徽标 当前 `setTabbarItem` 的类型签名是 `setTabbarItem(name: string, value: number)`,文档示例只演示数字徽标。 如果你希望支持显式清除(例如传 `undefined` 或 `null`),建议先将 `useTabbar.ts` 中的签名改为 `value?: number` 或 `value: number | null`,再在业务中调用。 ### 在组件中使用 ```vue ``` ## 取消自定义 Tabbar 如果你想恢复使用 uni-app 原生 Tabbar,按以下步骤操作: ### 1. 修改配置文件 在 `pages.config.ts` 中修改 `tabBar` 配置: ```typescript tabBar: { custom: false, // 改为 false 或直接删除此行 color: '#7A7E83', selectedColor: '#3cc51f', backgroundColor: '#ffffff', borderStyle: 'black', list: [{ pagePath: 'pages/index/index', text: '首页', iconPath: '/static/icon/home.png', // 需要提供图标文件 selectedIconPath: '/static/icon/home-active.png' }, { pagePath: 'pages/about/index', text: '关于', iconPath: '/static/icon/about.png', selectedIconPath: '/static/icon/about-active.png' }], } ``` ### 2. 准备图标资源 原生 Tabbar 需要提供图标文件,在 `static/icon/` 目录下放置相应的图标: * 未选中状态图标:`home.png`、`about.png` * 选中状态图标:`home-active.png`、`about-active.png` ### 3. 移除自定义组件 可以选择删除或注释以下文件: * `src/layouts/tabbar.vue` * `src/composables/useTabbar.ts` ### 4. 更新布局 如果使用了自定义 Tabbar 布局,需要相应调整页面布局文件。 ## 注意事项 1. **平台兼容性**: 自定义 Tabbar 在所有平台都能正常工作,但在 APP 端会自动隐藏原生 Tabbar 2. **页面路由**: 确保 `pages.config.ts` 中的 `pagePath` 与实际页面文件路径一致 3. **路由名称**: `tabbarItems` 中的 `name` 需要与目标页面路由名一致,否则 `router.pushTab({ name })` 无法正确跳转 4. **徽标更新**: 徽标状态是响应式的,可以实时更新 5. **主题支持**: 自定义 Tabbar 完全支持明暗主题切换 ## API 参考 ### useTabbar() 返回的方法和属性: ```typescript const { tabbarList, // 计算属性:Tabbar项列表 activeTabbar, // 计算属性:当前激活的Tabbar项 getTabbarItemValue, // 方法:获取指定项的徽标值 setTabbarItem, // 方法:设置指定项的徽标值 setTabbarItemActive, // 方法:设置指定项为激活状态 } = useTabbar() ``` ### 方法详解 ```typescript // 获取徽标值 getTabbarItemValue(name: string): number | undefined // 设置徽标值 setTabbarItem(name: string, value: number): void // 设置激活状态 setTabbarItemActive(name: string): void ``` 通过以上配置,你可以灵活地管理项目中的自定义 Tabbar,满足各种业务需求。 --- --- url: 'https://starter.wot-ui.cn/guide/installation.md' --- # 起步 你可以直接使用在线编辑器快速试用,或者使用终端在本地开始使用。 ## 在线试用 您可以使用在线编辑器在浏览器中开始试用: * [StackBlitz](https://stackblitz.com/github/wot-ui/wot-starter) * [GitHub Template](https://github.com/wot-ui/wot-starter/generate) ## 本地使用 ### 前置依赖 * **Node.js** - `>= 20.19.0 || >= 22.12.0 || >= 24.0.0` * **文本编辑器** - 推荐使用 [VS Code](https://code.visualstudio.com/) 并使用 [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) 插件 * **终端** - 为了运行 `uni` 命令,Windows 推荐 Git Bash,Linux 和 macOS 推荐 zsh ::: details 最佳实践 * **Node.js**: 总是使用偶数版本 (即 [LTS 版本](https://nodejs.org/en/about/previous-releases),例如 20, 22) * **Volar**: 推荐启用 [接管模式 takeover mode](https://cn.vuejs.org/guide/typescript/overview#volar-takeover-mode) ::: 打开终端,然后使用以下命令: ::: code-group ```bash [create-uni] pnpm create uni -t wot-starter-v2 ``` ```bash [degit] pnpx degit wot-ui/wot-starter#v2 ``` ```bash [giget] pnpx giget gh:wot-ui/wot-starter#v2 ``` ::: 在 VS Code 中打开项目文件夹: ```bash code ``` 安装依赖: ::: code-group ```bash [pnpm] pnpm install ``` ```bash [yarn] npx rimraf pnpm-lock.yaml yarn install ``` ```bash [npm] npx rimraf pnpm-lock.yaml npm install ``` ```bash [bun] npx rimraf pnpm-lock.yaml bun install ``` ::: ## 开发 你可以使用 `dev` 命令直接启动 `h5` 模式的开发服务器 ::: code-group ```bash [pnpm] pnpm dev ``` ```bash [yarn] yarn dev ``` ```bash [npm] npm dev ``` ```bash [bun] bun dev ``` ::: ### 跨端开发 同样使用 `dev` 命令,不同的是你需要使用冒号并跟着你要开发的平台标识。 ::: code-group ```bash [pnpm] pnpm dev: ``` ```bash [yarn] yarn dev: ``` ```bash [npm] npm dev: ``` ```bash [bun] bun dev: ``` ::: --- --- url: 'https://starter.wot-ui.cn/guide/router.md' --- # 路由管理 [uni-app](https://uniapp.dcloud.net.cn/tutorial/page.html#%E8%B7%AF%E7%94%B1) 页面路由为框架统一管理,开发者需要在 `pages.json` 里配置每个路由页面的路径及页面样式。类似小程序在 `app.json` 中配置页面路由一样。所以 `uni-app` 的路由用法与 `Vue Router` 不同,不过我们可以引入类似插件实现类似 `Vue Router` 的开发体验,例如 `@wot-ui/router`。 [@wot-ui/router](https://my-uni.wot-ui.cn/) 是专为 uni-app 设计的轻量级路由库,它提供了类似`Vue Router`的API和功能,可以帮助开发者实现在uni-app中进行路由跳转、传参、拦截等常用操作。 :::tip 提示 `@wot-ui/router`的目标是基于小程序平台,将uni-app路由相关的API对齐Vue Router,而并非提供完全的Vue Router,`uni-app` [路由](https://uniapp.dcloud.net.cn/api/router.html)中存在的限制,使用`@wot-ui/router`仍将存在。 ::: ## 核心特性 * **📝 编程式导航**: 支持多种导航方式 * **🔄 参数传递**: 支持 params 和 query 参数 * **🛡️ 导航守卫**: 完整的导航守卫机制 * **📊 路由信息**: 获取当前路由状态 * **🎯 类型安全**: 完整的 TypeScript 支持 #### 基础用法 ```typescript // 获取路由实例 const router = useRouter() const route = useRoute() // 字符串路径跳转 router.push('/pages/detail/index') // 对象路径跳转 router.push({ path: '/pages/detail/index' }) // 命名路由跳转 router.push({ name: 'detail' }) // 带参数跳转 router.push({ name: 'detail', params: { id: '123' } }) // 带查询参数跳转 router.push({ path: '/pages/detail/index', query: { tab: 'info' } }) ``` #### 导航守卫 ```typescript // 全局前置守卫 router.beforeEach((to, from, next) => { // 检查用户权限 if (to.meta.requiresAuth && !isLoggedIn()) { next({ name: 'login' }) } else { next() } }) // 全局后置钩子 router.afterEach((to, from) => { // 页面跳转完成后的处理 console.log(`从 ${from.path} 跳转到 ${to.path}`) }) ``` > 📖 **了解更多**: [@wot-ui/router 文档](https://my-uni.wot-ui.cn/) --- --- url: 'https://starter.wot-ui.cn/guide/deployment.md' --- # 部署 对于 uni-app 来说,部署即打包和发行。 ## Web 使用下面的命令来打包: ```bash pnpm build:h5 ``` 产物位于 `dist/build/h5`, 就像传统 SPA 一样部署即可。 ## 小程序 以微信小程序为例,使用下面的命令来打包: ```bash pnpm build:mp-weixin ``` 产物位于 `dist/build/mp-weixin`, 使用微信开发者工具上传即可。 ::: tip 如果想自动上传到微信小程序,可直接使用 [uni-mini-ci](https://www.npmjs.com/package/uni-mini-ci),或参考 [这篇文章](https://juejin.cn/post/7272316909051346959) 自行配置。 ::: 要发行其他小程序,执行 `pnpm build:mp-`打包,并使用对应开发者工具上传即可,具体可查看 `package.json` 的 `scripts` 部分。 ## APP ### 离线打包 * [android](https://nativesupport.dcloud.net.cn/AppDocs/usesdk/android.html) * [ios](https://nativesupport.dcloud.net.cn/AppDocs/usesdk/ios.html) ::: warning 你仍然可以使用 HBuilderX 提供的“安心”打包功能,但是由于这种方式强依赖 HBuilderX,故不做推荐。 :::