commit d8ae21ced4c1269dfda995145f3fe566e494a400 Author: ouhaolan Date: Mon Mar 2 08:31:49 2026 +0800 初始化 diff --git a/.image/admin-uniapp/01.png b/.image/admin-uniapp/01.png new file mode 100644 index 0000000..9583882 Binary files /dev/null and b/.image/admin-uniapp/01.png differ diff --git a/.image/admin-uniapp/02.png b/.image/admin-uniapp/02.png new file mode 100644 index 0000000..0413f5b Binary files /dev/null and b/.image/admin-uniapp/02.png differ diff --git a/.image/admin-uniapp/03.png b/.image/admin-uniapp/03.png new file mode 100644 index 0000000..6c48171 Binary files /dev/null and b/.image/admin-uniapp/03.png differ diff --git a/.image/common/project-vs.png b/.image/common/project-vs.png new file mode 100644 index 0000000..561e092 Binary files /dev/null and b/.image/common/project-vs.png differ diff --git a/.image/common/ruoyi-vue-pro-architecture.png b/.image/common/ruoyi-vue-pro-architecture.png new file mode 100644 index 0000000..7bd7d59 Binary files /dev/null and b/.image/common/ruoyi-vue-pro-architecture.png differ diff --git a/.image/common/yudao-cloud-architecture.png b/.image/common/yudao-cloud-architecture.png new file mode 100644 index 0000000..59416d8 Binary files /dev/null and b/.image/common/yudao-cloud-architecture.png differ diff --git a/H5部署文档.md b/H5部署文档.md new file mode 100644 index 0000000..144979a --- /dev/null +++ b/H5部署文档.md @@ -0,0 +1,297 @@ +# H5 版本部署文档 + +本文档介绍如何将项目编译成 H5 版本并部署到服务器,通过 Nginx 运行和代理访问。 + +--- + +## 📋 前置要求 + +### 环境要求 + +- **Node.js**: >= 20 +- **pnpm**: >= 9(必须使用 pnpm) +- **Nginx**: 已安装并运行(用于部署) + +### 服务器要求 + +- Linux/Unix 服务器 +- 已安装 Nginx +- 有权限访问服务器文件系统 + +--- + +## 🚀 部署步骤 + +### 1. 构建 H5 版本 + +在项目根目录执行以下命令进行构建: + +```bash +# 生产环境构建(推荐) +pnpm build:h5:prod + +# 或者使用默认构建命令 +pnpm build:h5 +``` + +构建完成后,文件会输出到 `dist/build/h5` 目录。 + +### 2. 配置环境变量(可选) + +如果您的应用需要部署在子目录下,或者需要修改其他配置,请编辑 `env/.env.production` 文件: + +```env +# 应用标题 +VITE_APP_TITLE=芋道管理后台 + +# 后端 API 地址 +VITE_SERVER_BASEURL=https://your-backend-api.com + +# H5 路由基础路径 +# 如果部署在根目录,设置为 / +# 如果部署在子目录(如 /app/),设置为 /app/ +VITE_APP_PUBLIC_BASE=/ + +# 其他配置... +``` + +**重要提示:** +- 如果部署在根目录,`VITE_APP_PUBLIC_BASE` 设置为 `/` +- 如果部署在子目录(如 `/app/`),`VITE_APP_PUBLIC_BASE` 设置为 `/app/` +- 修改后需要重新构建:`pnpm build:h5:prod` + +### 3. 上传文件到服务器 + +将 `dist/build/h5` 目录下的所有文件上传到服务器。 + +**方式一:使用 scp 命令** + +```bash +# 上传整个目录到服务器 +scp -r dist/build/h5/* user@your-server:/path/to/nginx/html/ + +# 或者上传到子目录 +scp -r dist/build/h5/* user@your-server:/path/to/nginx/html/app/ +``` + +**方式二:使用 rsync 命令(推荐)** + +```bash +# 同步文件到服务器 +rsync -avz dist/build/h5/ user@your-server:/path/to/nginx/html/ + +# 或者同步到子目录 +rsync -avz dist/build/h5/ user@your-server:/path/to/nginx/html/app/ +``` + +**方式三:使用 FTP/SFTP 工具** + +使用 FileZilla、WinSCP 等工具上传文件。 + +### 4. 配置 Nginx + +#### 4.1 部署在根目录(推荐) + +1. 复制 `nginx.conf.example` 文件中的第一个 server 配置块 +2. 修改以下配置: + - `server_name`: 改为您的域名或 IP + - `root`: 改为实际的文件路径(指向 `dist/build/h5` 目录) +3. 将配置添加到 Nginx 配置文件(通常在 `/etc/nginx/sites-available/` 或 `/etc/nginx/conf.d/`) + +**示例配置:** + +```nginx +server { + listen 80; + server_name your-domain.com; + + root /var/www/html; + index index.html; + + # 启用 gzip 压缩 + gzip on; + gzip_vary on; + gzip_min_length 1024; + gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json application/javascript; + + # 静态资源缓存 + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + } + + # Vue Router History 模式支持 + location / { + try_files $uri $uri/ /index.html; + } +} +``` + +#### 4.2 部署在子目录 + +如果您的应用需要部署在子目录下(如 `/app/`): + +1. 确保 `env/.env.production` 中 `VITE_APP_PUBLIC_BASE=/app/` +2. 重新构建:`pnpm build:h5:prod` +3. 上传文件到服务器的 `/app/` 目录 +4. 使用 `nginx.conf.example` 中的第二个 server 配置块 + +#### 4.3 配置 API 代理(可选) + +如果后端 API 需要通过 Nginx 代理,取消注释并修改 API 代理配置: + +```nginx +location /api/ { + proxy_pass http://your-backend-server:port; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; +} +``` + +### 5. 测试 Nginx 配置 + +```bash +# 测试 Nginx 配置文件语法 +sudo nginx -t + +# 如果测试通过,重新加载 Nginx 配置 +sudo nginx -s reload + +# 或者重启 Nginx +sudo systemctl restart nginx +``` + +### 6. 访问应用 + +在浏览器中访问: +- 如果部署在根目录:`http://your-domain.com` +- 如果部署在子目录:`http://your-domain.com/app/` + +--- + +## 🔧 常见问题 + +### 1. 页面刷新后 404 错误 + +**问题:** 刷新页面或直接访问路由时出现 404 错误。 + +**解决方案:** 确保 Nginx 配置了 `try_files` 指令: + +```nginx +location / { + try_files $uri $uri/ /index.html; +} +``` + +### 2. 静态资源加载失败 + +**问题:** CSS、JS 等静态资源无法加载。 + +**解决方案:** +- 检查 `VITE_APP_PUBLIC_BASE` 配置是否正确 +- 检查文件路径是否正确上传 +- 检查 Nginx 的 `root` 配置是否正确 + +### 3. API 请求跨域问题 + +**问题:** 前端请求后端 API 时出现跨域错误。 + +**解决方案:** +- 在 Nginx 中配置 API 代理(推荐) +- 或者在后端配置 CORS 允许跨域 + +### 4. 部署在子目录后路由不工作 + +**问题:** 部署在子目录后,路由跳转不正确。 + +**解决方案:** +- 确保 `env/.env.production` 中 `VITE_APP_PUBLIC_BASE` 设置为正确的子目录路径(如 `/app/`) +- 重新构建项目 +- 确保 Nginx 配置正确 + +--- + +## 📝 完整部署示例 + +### 示例:部署到根目录 + +```bash +# 1. 构建项目 +pnpm build:h5:prod + +# 2. 上传到服务器 +rsync -avz dist/build/h5/ user@server:/var/www/html/ + +# 3. 在服务器上配置 Nginx(参考上面的配置) + +# 4. 测试并重载 Nginx +sudo nginx -t +sudo nginx -s reload +``` + +### 示例:部署到子目录 `/app/` + +```bash +# 1. 修改环境变量 +# 编辑 env/.env.production,设置 VITE_APP_PUBLIC_BASE=/app/ + +# 2. 重新构建 +pnpm build:h5:prod + +# 3. 上传到服务器子目录 +rsync -avz dist/build/h5/ user@server:/var/www/html/app/ + +# 4. 在服务器上配置 Nginx(使用子目录配置) + +# 5. 测试并重载 Nginx +sudo nginx -t +sudo nginx -s reload +``` + +--- + +## 🔒 HTTPS 配置(推荐生产环境) + +生产环境建议使用 HTTPS,可以参考 `nginx.conf.example` 中的 HTTPS 配置示例。 + +使用 Let's Encrypt 免费证书: + +```bash +# 安装 certbot +sudo apt-get install certbot python3-certbot-nginx + +# 获取证书 +sudo certbot --nginx -d your-domain.com + +# 证书会自动配置,并设置自动续期 +``` + +--- + +## 📚 相关文档 + +- [项目启动文档](./启动文档.md) +- [构建文档](./docs/base/11-build.md) +- [环境变量配置](./docs/base/12-env.md) + +--- + +## ✅ 检查清单 + +部署前请确认: + +- [ ] 已构建 H5 版本(`pnpm build:h5:prod`) +- [ ] 已配置正确的环境变量(特别是 `VITE_APP_PUBLIC_BASE`) +- [ ] 已上传文件到服务器 +- [ ] 已配置 Nginx(包括 `try_files` 指令) +- [ ] 已测试 Nginx 配置(`nginx -t`) +- [ ] 已重载 Nginx 配置 +- [ ] 已测试访问应用 +- [ ] 已测试页面刷新功能 +- [ ] 已测试 API 请求(如果配置了代理) + +--- + +**部署完成后,您就可以通过浏览器访问您的应用了!** 🎉 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9e91d10 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 菲鸽 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..ae5662f --- /dev/null +++ b/README.md @@ -0,0 +1,112 @@ +

+ + + +

+ +

+ 芋道管理后台 · 移动端 +

+ +
+ +[![GitHub stars](https://img.shields.io/github/stars/yudaocode/yudao-ui-admin-uniapp?style=flat&logo=github)](https://github.com/yudaocode/yudao-ui-admin-uniapp) +[![Gitee star](https://gitee.com/yudaocode/yudao-ui-admin-uniapp/badge/star.svg?theme=dark)](https://gitee.com/yudaocode/yudao-ui-admin-uniapp/stargazers) +![node version](https://img.shields.io/badge/node-%3E%3D20-green) +![pnpm version](https://img.shields.io/badge/pnpm-%3E%3D9-green) +![GitHub License](https://img.shields.io/github/license/yudaocode/yudao-ui-admin-uniapp) + +
+ +--- + +**严肃声明:现在、未来都不会有商业版本,所有代码全部开源!!** + +**「我喜欢写代码,乐此不疲」** +**「我喜欢做开源,以此为乐」** + +我 🐶 在上海艰苦奋斗,早中晚在 top3 大厂认真搬砖,夜里为开源做贡献。 + +如果这个项目让你有所收获,记得 Star 关注哦,这对我是非常不错的鼓励与支持。 + +--- + +## 🐶 新手必读 + +平台兼容性: + +| H5 | iOS | Android | 微信小程序 | 支付宝小程序 | 字节小程序 | 百度小程序 | 钉钉小程序 | 快手小程序 | QQ 小程序 | +|:--:|:---:|:-------:|:-----:|:------:|:-----:|:-----:|:-----:|:-----:|:------:| +| ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | + +* nodejs >= 20 && pnpm >= 9 +* 启动文档: +* 视频教程: + +## 🐯 平台简介 + +**芋道**,以开发者为中心,打造中国第一流的快速开发平台,全部开源,个人与企业可 100% 免费使用。本项目是 **芋道管理后台的移动端**: + +| 工作台 | 工作流 | 个人中心 | +|:--------------------------------:|:--------------------------------:|:--------------------------------:| +| ![](/.image/admin-uniapp/01.png) | ![](/.image/admin-uniapp/02.png) | ![](/.image/admin-uniapp/03.png) | + +* 采用 `Vue3` + `TypeScript` + `Vite5` + `UnoCSS` + `wot-design-uni` + `z-paging` 构成,使用最新的前端技术栈,无需依赖 `HBuilderX`,通过命令行方式运行 `H5`、`小程序` 和 `App`。 +* 内置了 `约定式路由`、`layout布局`、`请求封装`、`请求拦截`、`登录拦截`、`UnoCSS`、`i18n多语言` 等基础功能,提供了 `代码提示`、`自动格式化`、`统一配置`、`代码片段` 等辅助功能,让你编写 `uniapp` 拥有 `best` 体验。 + +## ⚙️ 技术栈 + +| 框架 | 说明 | 版本 | +|-----------------------------------------------------|-------------------|--------| +| [Vue](https://vuejs.org/) | 渐进式 JavaScript 框架 | 3.4.x | +| [uni-app](https://uniapp.dcloud.io/) | 跨平台应用开发框架 | 3.0.x | +| [TypeScript](https://www.typescriptlang.org/) | JavaScript 的超集 | 5.8.x | +| [Vite](https://vitejs.dev/) | 下一代前端构建工具 | 5.2.x | +| [Pinia](https://pinia.vuejs.org/) | Vue 状态管理库 | 2.0.x | +| [UnoCSS](https://unocss.dev/) | 即时原子化 CSS 引擎 | 66.x | +| [unibest](https://github.com/feige996/unibest) | 最好的 uniapp 框架 | 4.1.0 | +| [wot-design-uni](https://wot-design-uni.pages.dev/) | 高颜值、轻量化 UI 组件库 | 1.13.x | +| [z-paging](https://z-paging.zxlee.cn/) | 高性能分页组件 | 2.8.x | +| [vue-i18n](https://vue-i18n.intlify.dev/) | 国际化解决方案 | 9.x | + +## ✨ 项目特性 + +| 特性 | 说明 | +|-------------------|-----------------------------------------| +| 🚀 **约定式路由** | 基于文件系统自动生成路由,无需手动配置 | +| 🎨 **Layout 布局** | 内置多种布局方案,支持 Tabbar 自定义 | +| 📦 **请求封装** | 基于 uni.request 封装,支持拦截器、TypeScript 类型推导 | +| 🔐 **登录拦截** | 内置完善的登录态管理与页面拦截机制 | +| 🎯 **UnoCSS** | 原子化 CSS,按需生成,极致性能 | +| 🌍 **i18n 多语言** | 内置国际化方案,轻松实现多语言切换 | +| 📝 **代码规范** | ESLint + Prettier + Husky,保证代码质量 | +| 🔧 **TypeScript** | 全面的 TypeScript 支持,类型安全 | +| 📱 **多端适配** | 一套代码,多端运行(H5、小程序、App) | + +## 🔥 后端架构 + +支持 Spring Boot、Spring Cloud 两种架构: + +### ① Spring Boot 单体架构 + +文档地址: + +![架构图](./.image/common/ruoyi-vue-pro-architecture.png) + +### ② Spring Cloud 微服务架构 + +文档地址: + +![架构图](./.image/common/yudao-cloud-architecture.png) + +## 😎 开源协议 + +**为什么推荐使用本项目?** + +① 本项目采用比 Apache 2.0 更宽松的 [MIT License](https://gitee.com/zhijiantianya/ruoyi-vue-pro/blob/master/LICENSE) 开源协议,个人与企业可 100% 免费使用,不用保留类作者、Copyright 信息。 + +② 代码全部开源,不会像其他项目一样,只开源部分代码,让你无法了解整个项目的架构设计。[国产开源项目对比](https://www.yuque.com/xiatian-bsgny/lm0ec1/wqf8mn) + +![开源项目对比](/.image/common/project-vs.png) + +③ 代码整洁、架构整洁,遵循《阿里巴巴 Java 开发手册》规范,代码注释详细,113770 行 Java 代码,42462 行代码注释。 diff --git a/docs/.vitepress/components/BuildInfo.vue b/docs/.vitepress/components/BuildInfo.vue new file mode 100644 index 0000000..380ef56 --- /dev/null +++ b/docs/.vitepress/components/BuildInfo.vue @@ -0,0 +1,23 @@ + + + + + + diff --git a/docs/.vitepress/composables/cases.ts b/docs/.vitepress/composables/cases.ts new file mode 100644 index 0000000..f96c451 --- /dev/null +++ b/docs/.vitepress/composables/cases.ts @@ -0,0 +1,25 @@ +import { ref, onMounted } from 'vue' +import axios from 'axios' + +export type CaseData = { + name: string + image: string + description?: string +} + +const data = ref([]) + +export function useCaseData() { + const data = [ + { + name: '调剂宝', + description: '一个专业的调剂助手,帮助你找到最适合自己的调剂方案。', + image: + 'https://private-user-images.githubusercontent.com/45726436/455309534-d6ae0ca0-9b42-4c01-8024-90f3d9690765.jpg?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NTAwNDA4MjQsIm5iZiI6MTc1MDA0MDUyNCwicGF0aCI6Ii80NTcyNjQzNi80NTUzMDk1MzQtZDZhZTBjYTAtOWI0Mi00YzAxLTgwMjQtOTBmM2Q5NjkwNzY1LmpwZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTA2MTYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwNjE2VDAyMjIwNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTJiMTBjOWIwYmY3OTVmMTBkZmY1ZjM3MjhhZmQ0OTc4NmRkMjllZDM2MzMwMmQyOGYyMTFiNmU3MzE3N2FhMmMmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.6NIPLDSN3n1LFQTSfynFOIa66DGh3QtIgSkx9zlEf54', + }, + ] + + return { + data, + } +} diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts new file mode 100644 index 0000000..c8dae94 --- /dev/null +++ b/docs/.vitepress/config.mts @@ -0,0 +1,271 @@ +import dayjs from 'dayjs' +import { defineConfig } from 'vitepress' +import llmsPlugin from 'vitepress-plugin-llms' +import packageJson from '../../package.json' + +const buildTime = dayjs().format('YYYY-MM-DD HH:mm:ss') + +const base = '/unibest/' // default is / + +// https://vitepress.dev/reference/site-config +export default defineConfig({ + lang: 'zh-CN', + base: base, + title: 'unibest 官方文档', + description: '最好用的 uniapp 开发模板', + lastUpdated: true, + cleanUrls: true, + head: [ + ['link', { rel: 'icon', href: `${base}favicon.ico` }], + // 增加构建信息 + ['meta', { name: 'build-time', content: buildTime }], + ['meta', { name: 'version', content: packageJson.version }], + [ + 'meta', + { + name: 'keywords', + content: 'unibest, uniapp, uni-app, vue, vue3, vite,template, typescript, ts', + }, + ], + [ + 'meta', + { + name: 'author', + content: '菲鸽, 菲哥, 鸽鸽, feige996, feige996, 1020103647@qq.com', + }, + ], + [ + 'meta', + { + name: 'twitter:title', + content: '最好用的 uniapp 开发模板', + }, + ], + // 添加 ICP 备案信息 + ['meta', { name: 'icp', content: '粤ICP备2024160998号' }], + ['link', { rel: 'license', href: 'https://beian.miit.gov.cn/' }], + // 百度联盟meta + ['meta', { property: 'baidu_union_verify', content: '8ab9e6068e7febf94e684886f81f406f' }], + // 其他杂七杂八的 meta 标签 + ['meta', { name: 'twitter:card', content: 'summary_large_image' }], + ['meta', { name: 'twitter:site', content: 'feige996' }], + [ + 'meta', + { + name: 'twitter:image:src', + content: + 'https://opengraph.githubassets.com/1cac1150838995e1f7d1643c00eee51a5d884f2054f995c9d3225b07b0eddb39/feige996/unibest', + }, + ], + [ + 'meta', + { + property: 'og:image', + content: + 'https://opengraph.githubassets.com/1cac1150838995e1f7d1643c00eee51a5d884f2054f995c9d3225b07b0eddb39/feige996/unibest', + }, + ], + [ + 'meta', + { + property: 'og:image:alt', + content: '最好用的 uniapp 开发模板', + }, + ], + ['meta', { property: 'og:image:width', content: '1200' }], + ['meta', { property: 'og:image:height', content: '600' }], + ['meta', { property: 'og:site_name', content: 'GitHub' }], + ['meta', { property: 'og:type', content: 'object' }], + [ + 'meta', + { + property: 'og:title', + content: '最好用的 uniapp 开发模板', + }, + ], + ['meta', { property: 'og:url', content: 'https://github.com/feige996/unibest' }], + [ + 'meta', + { + property: 'og:description', + content: '最好用的 uniapp 开发模板', + }, + ], + // 下面是百度统计代码 + ['script', { async: '', src: 'https://hm.baidu.com/hm.js?081c2ec121383d9e7d5a35c5833ab6ff' }], + // 下面是不蒜子统计代码 + ['script', { async: '', src: '//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js' }], + ], + markdown: { + theme: { + light: 'vitesse-light', + dark: 'vitesse-dark', + }, + }, + themeConfig: { + // https://vitepress.dev/reference/default-theme-config + logo: '/logo.png', + siteTitle: 'unibest', + nav: [ + { + text: '快速开始', + link: '/base/2-start', + activeMatch: '/base', + }, + { + text: '🥤 打赏', + link: '/advanced/rewards/rewards', + }, + { + text: '更新日志', + link: '/changelog/CHANGELOG', + }, + { + text: '相关链接', + link: '/other/links/links', + }, + { + text: 'unibest备用地址', + items: [ + { text: 'unibest.tech(本站)', link: 'https://unibest.tech' }, + { text: 'github page(备用)', link: 'https://feige996.github.io/unibest/' }, + ], + }, + ], + sidebar: [ + { + text: '基础·必看', + base: '/base/', + items: [ + { text: '介绍', link: '1-introduction' }, + { + text: '快速开始', + link: '2-start', + }, + { text: 'uni 插件', link: '3-plugin' }, + { text: '样式篇', link: '4-style' }, + // { text: '样式篇2', link: '4-style2' }, + { text: '图标篇', link: '5-icons' }, + { text: 'SVG篇', link: '6-svg' }, + { text: 'UI库选型篇', link: 'ui/ui' }, + { text: 'UI库替换篇', link: '7-ui' }, + { text: '请求篇', link: '8-request' }, + { text: '状态篇', link: '9-state' }, + { text: '多语言篇', link: '10-i18n' }, + { text: '运行发布', link: '11-build' }, + { text: 'App 专题', link: '18-app' }, + // { text: '环境变量', link: '12-env' }, + { text: 'hbx 模板', link: '13-hbx' }, + { text: '常见问题', link: '14-faq' }, + { text: '常见问题2', link: '15-faq' }, + // { text: '小程序标识', link: '16-terminology' }, + { text: '自动生成代码', link: '17-generate' }, + // { text: '最佳实践', link: '20-best' }, + ], + }, + { + text: '⭐ 优秀案例', + link: '/advanced/showcase/showcase', + }, + { + text: '更新日志', + link: '/changelog/CHANGELOG', + }, + { + text: '升级指南', + link: '/changelog/upgrade', + }, + { + text: '社交', + base: '/advanced/', + items: [ + { text: '🥤 打赏', link: 'rewards/rewards' }, + { text: '微信交流群', link: 'wechat/wechat' }, + { text: '赞助榜', link: 'sponsor/sponsor' }, + ], + }, + { + text: '延伸', + base: '/other/', + items: [ + { text: '相关链接', link: 'links/links' }, + { text: '图片占位图', link: 'image/image' }, + { text: 'iconfont详细版', link: 'iconfont/iconfont' }, + // { text: 'Git 提交优化', link: 'czg/czg' }, + // { text: '文件资源展示优化', link: 'files/files' }, + { text: 'unibest博客', link: 'blog' }, + ], + }, + ], + footer: { + message: 'Released under the MIT License.', + copyright: 'Copyright (c) 2024 菲鸽', + }, + socialLinks: [ + { icon: 'github', link: 'https://github.com/feige996/unibest' }, + { + icon: { + svg: ``, + }, + link: 'https://gitee.com/feige996/unibest', + ariaLabel: 'Gitee', + }, + { + icon: { + svg: ` + + +`, + }, + link: 'https://gitcode.com/feige996/unibest', + ariaLabel: 'GitCode', + }, + // #1f80ff 是掘金的 logo 的颜色 + { + icon: { + svg: ` + + + + `, + }, + link: 'https://juejin.cn/user/3263006241460792/posts', + ariaLabel: '菲鸽的掘金主页', + }, + ], + search: { + provider: 'local', + options: { + locales: { + root: { + translations: { + button: { + buttonText: '搜索文档', + buttonAriaLabel: '搜索文档', + }, + modal: { + displayDetails: '显示详情', + resetButtonTitle: '清除查询条件', + backButtonTitle: '返回', + noResultsText: '无法找到相关结果', + footer: { + selectText: '选择', + selectKeyAriaLabel: '选择', + navigateText: '切换', + navigateUpKeyAriaLabel: '切换', + navigateDownKeyAriaLabel: '切换', + closeText: '关闭', + closeKeyAriaLabel: '关闭', + }, + }, + }, + }, + }, + }, + }, + }, + vite: { + // 其他配置... + plugins: [llmsPlugin() as any], + }, +}) diff --git a/docs/.vitepress/layouts/Default.vue b/docs/.vitepress/layouts/Default.vue new file mode 100644 index 0000000..6235948 --- /dev/null +++ b/docs/.vitepress/layouts/Default.vue @@ -0,0 +1,26 @@ + + + + + + diff --git a/docs/.vitepress/theme/components/FreshImage.vue b/docs/.vitepress/theme/components/FreshImage.vue new file mode 100644 index 0000000..5a60ff1 --- /dev/null +++ b/docs/.vitepress/theme/components/FreshImage.vue @@ -0,0 +1,21 @@ + + + diff --git a/docs/.vitepress/theme/components/HomeStar.vue b/docs/.vitepress/theme/components/HomeStar.vue new file mode 100644 index 0000000..287ef53 --- /dev/null +++ b/docs/.vitepress/theme/components/HomeStar.vue @@ -0,0 +1,50 @@ + + + diff --git a/docs/.vitepress/theme/components/NavBarTitleAfter.vue b/docs/.vitepress/theme/components/NavBarTitleAfter.vue new file mode 100644 index 0000000..f115b68 --- /dev/null +++ b/docs/.vitepress/theme/components/NavBarTitleAfter.vue @@ -0,0 +1,20 @@ + + + diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css new file mode 100644 index 0000000..064f125 --- /dev/null +++ b/docs/.vitepress/theme/custom.css @@ -0,0 +1,84 @@ +/** + * Colors + * -------------------------------------------------------------------------- */ +:root { + --vp-c-brand-1: hsl(128, 56%, 38%); + --vp-c-brand-2: hsl(128, 56%, 55%); + --vp-c-brand-3: hsl(128, 56%, 45%); + --vp-c-brand-soft: rgba(98, 133, 208, 0.16); +} +/** + * Component: Home + * -------------------------------------------------------------------------- */ + +:root { + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: -webkit-linear-gradient( + 120deg, + hsl(128, 56%, 38%) 30%, + hsl(128, 56%, 60%) + ); + --vp-home-hero-image-background-image: linear-gradient( + 120deg, + hsl(100, 56%, 45%) 30%, + hsl(120, 56%, 38%) + ); + --vp-home-hero-image-filter: blur(40px); +} +@media (min-width: 640px) { + :root { + --vp-home-hero-image-filter: blur(56px); + } +} + +@media (min-width: 960px) { + :root { + --vp-home-hero-image-filter: blur(72px); + } +} + +.md-center > p { + display: flex; + /* justify-content: center; */ + flex-wrap: wrap; + margin-top: -4px; + margin-right: -4px; +} +.md-center img { + display: inline-block; + height: 1.4em; + margin-top: 4px; + margin-right: 4px; + line-height: 1.6; +} +.md-center2 img { + display: inline-block; + margin-top: 4px; + margin-right: 4px; +} + +.busuanzi_container { + display: flex; + justify-content: space-around; + opacity: 0.3; +} + +@media (max-width: 960px) { + .busuanzi_container { + flex-direction: column; + padding-top: 12px; + padding-left: 30px; + } +} +@media (min-width: 961px) { + .busuanzi_container { + height: 60px; + line-height: 60px; + } +} + +.icp_container { + display: flex; + align-items: center; + justify-content: center; +} diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts new file mode 100644 index 0000000..ac3e97a --- /dev/null +++ b/docs/.vitepress/theme/index.ts @@ -0,0 +1,28 @@ +// https://vitepress.dev/guide/custom-theme +import type { Theme } from 'vitepress' +import DefaultTheme from 'vitepress/theme' +import { h } from 'vue' +import './custom.css' + +import HomeStar from './components/HomeStar.vue' +import NavBarTitleAfter from './components/NavBarTitleAfter.vue' +import FreshImage from './components/FreshImage.vue' + +import ElementPlus from 'element-plus' +import 'element-plus/dist/index.css' + +export default { + extends: DefaultTheme, + Layout: () => { + return h(DefaultTheme.Layout, null, { + // https://vitepress.dev/guide/extending-default-theme#layout-slots + 'home-hero-info-after': () => h(HomeStar), + 'nav-bar-title-after': () => h(NavBarTitleAfter), + }) + }, + enhanceApp({ app, router, siteData }) { + // ... + app.component('FreshImage', FreshImage) + app.use(ElementPlus) + }, +} satisfies Theme diff --git a/docs/advanced/me/image-2.png b/docs/advanced/me/image-2.png new file mode 100644 index 0000000..b18b7ca Binary files /dev/null and b/docs/advanced/me/image-2.png differ diff --git a/docs/advanced/me/image-3.png b/docs/advanced/me/image-3.png new file mode 100644 index 0000000..02473d5 Binary files /dev/null and b/docs/advanced/me/image-3.png differ diff --git a/docs/advanced/me/me.md b/docs/advanced/me/me.md new file mode 100644 index 0000000..867d601 --- /dev/null +++ b/docs/advanced/me/me.md @@ -0,0 +1,30 @@ +# 关于我 + +我叫 `菲鸽`,江西宋城人。前端工程师,全栈实践者,精通 `vue`、`react`、`uniapp`、`typescript`、`小程序`、`Nodejs` 等。 + +热爱编程,喜欢分享,平时比较宅,喜欢撸代码,偶尔打篮球和玩王者荣耀。 + + + +## 找到我 + +- Github: [feige996](https://github.com/feige996) +- Gitee: [feige996](https://gitee.com/feige996) +- 掘金:[菲鸽](https://juejin.cn/user/3263006241460792/posts) +- 微信:`feige996` = `菲鸽`,大家都叫我 `鸽鸽` +- QQ:`1020103647` +- 邮箱:`1020103647@qq.com` + +## 微信公众号 + +微信公众号:`菲鸽爱编程` + +![微信公众号](./screenshots/wx-gzh.png) + + diff --git a/docs/advanced/me/screenshots/pay-wx.png b/docs/advanced/me/screenshots/pay-wx.png new file mode 100644 index 0000000..8c8c633 Binary files /dev/null and b/docs/advanced/me/screenshots/pay-wx.png differ diff --git a/docs/advanced/me/screenshots/wx-gzh.png b/docs/advanced/me/screenshots/wx-gzh.png new file mode 100644 index 0000000..25fcb5b Binary files /dev/null and b/docs/advanced/me/screenshots/wx-gzh.png differ diff --git a/docs/advanced/me/screenshots/wx-me.png b/docs/advanced/me/screenshots/wx-me.png new file mode 100644 index 0000000..efb91b9 Binary files /dev/null and b/docs/advanced/me/screenshots/wx-me.png differ diff --git a/docs/advanced/rewards/assets/group-qq.jpg b/docs/advanced/rewards/assets/group-qq.jpg new file mode 100644 index 0000000..6f6df26 Binary files /dev/null and b/docs/advanced/rewards/assets/group-qq.jpg differ diff --git a/docs/advanced/rewards/assets/group-wx.jpg b/docs/advanced/rewards/assets/group-wx.jpg new file mode 100644 index 0000000..78f2261 Binary files /dev/null and b/docs/advanced/rewards/assets/group-wx.jpg differ diff --git a/docs/advanced/rewards/assets/pay-1.png b/docs/advanced/rewards/assets/pay-1.png new file mode 100644 index 0000000..92e8019 Binary files /dev/null and b/docs/advanced/rewards/assets/pay-1.png differ diff --git a/docs/advanced/rewards/assets/pay-2.png b/docs/advanced/rewards/assets/pay-2.png new file mode 100644 index 0000000..9004bed Binary files /dev/null and b/docs/advanced/rewards/assets/pay-2.png differ diff --git a/docs/advanced/rewards/assets/pay-ali.png b/docs/advanced/rewards/assets/pay-ali.png new file mode 100644 index 0000000..dce450a Binary files /dev/null and b/docs/advanced/rewards/assets/pay-ali.png differ diff --git a/docs/advanced/rewards/assets/pay-w-5.png b/docs/advanced/rewards/assets/pay-w-5.png new file mode 100644 index 0000000..8de0cf8 Binary files /dev/null and b/docs/advanced/rewards/assets/pay-w-5.png differ diff --git a/docs/advanced/rewards/assets/pay-wx-10.png b/docs/advanced/rewards/assets/pay-wx-10.png new file mode 100644 index 0000000..c035320 Binary files /dev/null and b/docs/advanced/rewards/assets/pay-wx-10.png differ diff --git a/docs/advanced/rewards/assets/pay-wx-2.png b/docs/advanced/rewards/assets/pay-wx-2.png new file mode 100644 index 0000000..9a5f692 Binary files /dev/null and b/docs/advanced/rewards/assets/pay-wx-2.png differ diff --git a/docs/advanced/rewards/assets/pay-wx-5-doc.png b/docs/advanced/rewards/assets/pay-wx-5-doc.png new file mode 100644 index 0000000..e484ed0 Binary files /dev/null and b/docs/advanced/rewards/assets/pay-wx-5-doc.png differ diff --git a/docs/advanced/rewards/assets/pay-wx-5.png b/docs/advanced/rewards/assets/pay-wx-5.png new file mode 100644 index 0000000..909c225 Binary files /dev/null and b/docs/advanced/rewards/assets/pay-wx-5.png differ diff --git a/docs/advanced/rewards/assets/pay-wx.png b/docs/advanced/rewards/assets/pay-wx.png new file mode 100644 index 0000000..8c8c633 Binary files /dev/null and b/docs/advanced/rewards/assets/pay-wx.png differ diff --git a/docs/advanced/rewards/rewards.md b/docs/advanced/rewards/rewards.md new file mode 100644 index 0000000..03576e9 --- /dev/null +++ b/docs/advanced/rewards/rewards.md @@ -0,0 +1,8 @@ +# 🥤 打赏 + +如果本项目对你的工作起到了帮助,加快了您的项目进展,解决了您的问题,欢迎 `打赏` ! + +

+special sponsor appwrite +special sponsor appwrite +

diff --git a/docs/advanced/showcase/data.json b/docs/advanced/showcase/data.json new file mode 100644 index 0000000..e69de29 diff --git a/docs/advanced/showcase/showcase.md b/docs/advanced/showcase/showcase.md new file mode 100644 index 0000000..323d0ae --- /dev/null +++ b/docs/advanced/showcase/showcase.md @@ -0,0 +1,81 @@ +# ⭐ 优秀案例 + +我们非常欢迎大家一起贡献优秀的案例,欢迎在此 [issue](https://github.com/feige996/unibest/issues/139) 提交案例。 + +`unibest` 已被很多公司和团队在生产环境使用,下面是一些优秀的案例: + + + +
+ + + + +
+ + diff --git a/docs/advanced/showcase/云打牌.png b/docs/advanced/showcase/云打牌.png new file mode 100644 index 0000000..d5ecf85 Binary files /dev/null and b/docs/advanced/showcase/云打牌.png differ diff --git a/docs/advanced/showcase/佰润.png b/docs/advanced/showcase/佰润.png new file mode 100644 index 0000000..9bfb8cf Binary files /dev/null and b/docs/advanced/showcase/佰润.png differ diff --git a/docs/advanced/showcase/卡路里伙伴.png b/docs/advanced/showcase/卡路里伙伴.png new file mode 100644 index 0000000..4c3e607 Binary files /dev/null and b/docs/advanced/showcase/卡路里伙伴.png differ diff --git a/docs/advanced/showcase/橙掌柜.png b/docs/advanced/showcase/橙掌柜.png new file mode 100644 index 0000000..59fe07d Binary files /dev/null and b/docs/advanced/showcase/橙掌柜.png differ diff --git a/docs/advanced/showcase/监所通.png b/docs/advanced/showcase/监所通.png new file mode 100644 index 0000000..1f8837c Binary files /dev/null and b/docs/advanced/showcase/监所通.png differ diff --git a/docs/advanced/showcase/监所邮.png b/docs/advanced/showcase/监所邮.png new file mode 100644 index 0000000..c9a48c6 Binary files /dev/null and b/docs/advanced/showcase/监所邮.png differ diff --git a/docs/advanced/showcase/进货平台.png b/docs/advanced/showcase/进货平台.png new file mode 100644 index 0000000..94c82b2 Binary files /dev/null and b/docs/advanced/showcase/进货平台.png differ diff --git a/docs/advanced/sponsor/sponsor.md b/docs/advanced/sponsor/sponsor.md new file mode 100644 index 0000000..1397a8b --- /dev/null +++ b/docs/advanced/sponsor/sponsor.md @@ -0,0 +1,62 @@ +# 赞助榜 + +感谢所有赞助者! + +如需更改展示信息,或者需要展示更详细的信息,请联系我。 + +如果需要展示产品、博客、友链啥的,也可以联系我,很乐意为您展示。 + +> 金牌赞助者将额外获得首页产品展示位。 + +## 200 元 + +- 麦可 +- 程序员云创 [https://www.codecommitter.com/](https://www.codecommitter.com/) +- 海鲜™ 深圳金济福科技有限公司[https://www.jinjifu.com/](https://www.jinjifu.com/) + +## 50 元 + +- \*皮 +- 暗月隐落 [飞鸟快验 - 一个通用网络验证后台](https://www.fnkuaiyan.cn) + +## 20 元 + +- \*捷 +- \*度 +- \*恼 + +## 10-20 元 + +- 薛柳(15) +- 是魔王哒(12) + +## 10 元 + +- \*辛 +- \*y +- \*边 + +## 5-10 元 + +- Leo (9.90) +- \*熙 (6.66) +- 阿森纳 (6.66) +- I am 小萝北 ²º²4 (6.60) +- SUMMER (5) +- \*峰 (5) +- 阿云 (5) +- nuYoah (5) +- 许志成 (5) +- JY_en_ke_hao (5) + +## 2 元及以下 + +有 `15` 人,这里不一一列出。(如果希望展示,请联系我) + +## 红包打赏 + +还有一部分群友是发 `专属红包` 打赏的,这里没有统计,如果需要展示,请联系我。 + +--- + +> 再次感谢所有赞助者、打赏者! diff --git a/docs/advanced/wechat/wechat.md b/docs/advanced/wechat/wechat.md new file mode 100644 index 0000000..01b3dc1 --- /dev/null +++ b/docs/advanced/wechat/wechat.md @@ -0,0 +1,12 @@ +# 微信交流群 + +千万记得 `先看一遍文档`,可以解决大部分基础疑问。 + + + + + +> 如果上面的微信群满了,请使用下面的 QQ 群,QQ 群不会过期,长期有效。 + +①②③ 群已满,下面是 ④ 群。 +![alt text](https://oss.laf.run/ukw0y1-site/unibest-discussion-group/qq.jpg) diff --git a/docs/base/1-introduction.md b/docs/base/1-introduction.md new file mode 100644 index 0000000..3e7a246 --- /dev/null +++ b/docs/base/1-introduction.md @@ -0,0 +1,208 @@ +# 简介 + +
+ +[![GitHub Repo stars](https://img.shields.io/github/stars/codercup/unibest?style=flat&logo=github)](https://github.com/codercup/unibest) +[![GitHub Repo stars](https://img.shields.io/github/stars/feige996/unibest?style=flat&logo=github)](https://github.com/feige996/unibest) +[![star](https://gitee.com/codercup/unibest/badge/star.svg?theme=dark)](https://gitee.com/codercup/unibest) +![node version](https://img.shields.io/badge/node-%3E%3D18-green) +![pnpm version](https://img.shields.io/badge/pnpm-%3E%3D7.30-green) +![GitHub License](https://img.shields.io/github/license/codercup/unibest) + +
+ +> 上面前 2 个 `star` 分别是旧仓库 `codercup` 和新仓库 `feige996` 的 `star` 数。 + +`unibest` 是最好的 `uniapp` 开发框架,由 `uniapp` + `Vue3` + `Ts` + `Vite5` + `UnoCss` + `VSCode`(可选 `webstorm`) + `uni插件`+ `wot-ui`(可选其他 UI 库)构建,集成了多种工具和技术,使用了最新的前端技术栈,无需依靠 `HBuilderX`,通过命令行方式即可运行 `web`、`小程序` 和 `App`。(注:`App` 还是需要 `HBuilderX`) + +`unibest` 内置了 `约定式路由`、`layout布局`、`请求封装`、`请求拦截`、`登录拦截`、`UnoCSS`、`i18n多语言` 等基础功能,提供了 `代码提示`、`自动格式化`、`统一配置`、`代码片段` 等辅助功能,让你编写 `uniapp` 拥有 `best` 体验 ( `unibest 的由来`)。 + +> `unibest` 目前支持 `H5`、`小程序` 和 `App`。 + +::: tip ⭐⭐⭐⭐⭐ +如果 `unibest` 对您有帮助,希望你可以去 **Github** 或者 **Gitee(码云)** 帮我点个 ⭐ ,这将是对我极大的鼓励。 + + + +[![star](https://img.shields.io/github/stars/feige996/unibest?style=flat&logo=github)](https://github.com/feige996/unibest) + + + +[![star](https://gitee.com/feige996/unibest/badge/star.svg?theme=dark)](https://gitee.com/feige996/unibest) + +::: + +::: tip 🌟🌟🌟🌟🌟 +旧的文档地址 [codercup/unibest](https://codercup.github.io/unibest-docs/)不再维护,尽量使用新地址[unibest.tech](https://unibest.tech)。 +::: + +## ⭐ Star History + +同类模板对比实时地址:[https://www.star-history.com/#Ares-Chang/uni-vitesse&uni-helper/vitesse-uni-app&codercup/unibest&feige996/unibest&DaMaiCoding/uni-plus&Date](https://www.star-history.com/#Ares-Chang/uni-vitesse&uni-helper/vitesse-uni-app&codercup/unibest&feige996/unibest&DaMaiCoding/uni-plus&Date) + +如图所示,两个高高的都是 `unibest`,分别是新旧仓库。 + +黄色的是旧的 `codercup`,秘钥丢失,进不去了。粉色的新的仓库(`feige996`),目前正在积极维护。 + +[![Star History Chart](https://api.star-history.com/svg?repos=Ares-Chang/uni-vitesse,uni-helper/vitesse-uni-app,codercup/unibest,feige996/unibest,DaMaiCoding/uni-plus&type=Date)](https://www.star-history.com/#Ares-Chang/uni-vitesse&uni-helper/vitesse-uni-app&codercup/unibest&feige996/unibest&DaMaiCoding/uni-plus&Date) + +## 🗂 生成过程 + +`unibest` 由最初始的官方 cli 脚手架模板生成,执行的命令如下: + +```sh +npx degit dcloudio/uni-preset-vue#vite-ts my-vue3-project +``` + +`uniapp` 官方链接:[点击跳转 - quickstart-cli](https://uniapp.dcloud.net.cn/quickstart-cli.html) + +在官方生成的项目基础上,增加了如下内容: + +- 前端基础配置六件套 + - prettier + - eslint + - stylelint + - husky + - lint-staged + - commitlint +- UnoCSS +- UnoCSS Icons +- Uni 插件 + - vite-plugin-uni-pages + - vite-plugin-uni-layouts + - vite-plugin-uni-manifest + - vite-plugin-uni-platform +- UI 库(默认 `wot-ui`,支持替换其他 `UI库`) +- pinia + pinia-plugin-persistedstate +- 通用功能 + - 请求封装 + - 请求拦截 + - 路由拦截 + +## ✨ 特性 + +- ⚡️ [Vue 3](https://github.com/vuejs/core), [Vite](https://github.com/vitejs/vite), [pnpm](https://pnpm.io/), [esbuild](https://github.com/evanw/esbuild) - 就是快! + +- 🔥 最新语法 - ` +``` + +::: + +## 3. Vue-Official ( ` vue.volar` ) 使用哪个版本? + +`2025-05-22` 更新 :经测试,最新可用版本为 `v2.2.8` ,`v2.2.10` 会报错。(可以关闭 vue.volar 的自动更新) + +![alt text](./assets/15-4.png) + +## 4. 为啥不用 `vant-ui`? + +`vant-ui` 是 `WEB` 端 `UI 库`,不适用于 `uni-app`。 + +`uni-app` 没有 `window`, `document` 等 `WEB API`,所以凡是使用 `WEB API` 的 `框架`、`UI 库` 等都不适用于 `uni-app`。 + +## 4. 控制台报错 `[plugin:uni:mp-using-component] Unexpected token S in JSON at position 208`。 + +控制台报错如下: +![alt text](./assets/15-6.png) + +原因是 `uni-pages` 这个插件最新版本 `0.2.22` 有问题,需要回退到 `0.2.20`。 + +![alt text](./assets/15-5.png) + +执行如下命令即可: + +``` +pnpm add @uni-helper/vite-plugin-uni-pages@0.2.20 +``` + +> 因为 `unibest` 在 `2.3.0(含)` 之前没有把 `pnpm-lock.yaml` 加入到版本管理,导致小版还是有细微差别。 +> +> 在 `2.4.0` 开始已经加入,不会再出现这个问题。 + +## 5.不会 TypeScript 怎么办 + +不管个人还是团队、产品或者项目,从长远考虑我们都建议你学习 TypeScript,因为它是未来的趋势,而且大部分框架、库、插件都是用 TypeScript 开发的,足以证明它是构建一款成熟稳健产品的基石。 + +但考虑到实际情况,会各种客观原因存在,如果必须要用传统 JavaScript 进行开发,你可以在 `tsconfig.json` 里将 `allowJs` 设置为 `true` 即可,框架原有的 TypeScript 代码不会受到影响,并且你也可以在项目中使用 JavaScript 编写代码。 + +## 6.微信小程序 `INVALID_LOGIN` + +微信小程序开发进入登录页时,可能导致如下问题: + +```text +{errMsg: "navigateTo:fail Error: INVALID_LOGIN, +access_token expired [20250103 17:08:03][touristappid]"} +``` + +> 解答:游客模式会出现该错误,微信扫码登录一下就可以了。 diff --git a/docs/base/16-terminology.md b/docs/base/16-terminology.md new file mode 100644 index 0000000..dbb3d3b --- /dev/null +++ b/docs/base/16-terminology.md @@ -0,0 +1,17 @@ +# 小程序的标识 + +目前有以下 `9` 种小程序标识,对应小程序平台类型如下: + +| 类型 | 标识 | +| ------------ | ----------- | +| 微信小程序 | mp-weixin | +| 支付宝小程序 | mp-alipay | +| 抖音小程序 | mp-toutiao | +| 飞书小程序 | mp-lark | +| QQ小程序 | mp-qq | +| 京东小程序 | mp-jd | +| 小红书小程序 | mp-xhs | +| 百度小程序 | mp-baidu | +| 快手小程序 | mp-kuaishou | + +> 注意: `mp-toutiao` 就是抖音小程序,其他的都很好辨别。 diff --git a/docs/base/17-generate.md b/docs/base/17-generate.md new file mode 100644 index 0000000..cbab48e --- /dev/null +++ b/docs/base/17-generate.md @@ -0,0 +1,135 @@ +# 自动生成代码 + +![alt text](17-good.png) + +集成 [openapi-ts-request](https://github.com/openapi-ui/openapi-ts-request) 插件,可以根据接口文档自动生成 js,ts,uni.request,vue-query 代码。 + +> 好用的话记得点赞,`star` 支持下。 + +支持 apifox/swagger/opeanpi/yapi 等接口文档,更多配置详情请查看 [openapi-ts-request](https://github.com/openapi-ui/openapi-ts-request) 插件。 + +## 如何使用 + +你只需要将接口文档对应的接口配置url,复制到根目录的 `openapi-ts-request.config.ts` 插件的配置文件中的 `schemaPath` 字段中,然后运行 `npm run openapi-ts-request` 命令,就可以生成代码。 +支持同时配置多个接口文档url,生成的代码默认会放在 `src/service/app` 目录下,你可以自己调整生成代码的目录。 + +配置如下: + +```ts +import type { GenerateServiceProps } from 'openapi-ts-request' + +export default [ + { + schemaPath: 'http://petstore.swagger.io/v2/swagger.json', + serversPath: './src/service/app', + requestLibPath: `import request from '@/utils/request';\n import { CustomRequestOptions } from '@/interceptors/request';`, + requestOptionsType: 'CustomRequestOptions', + isGenReactQuery: true, + reactQueryMode: 'vue', + isGenJavaScript: false, + }, +] as GenerateServiceProps[] +``` + +## 生成 ts 代码 + +ts 的 type 类型会默认生成在 `src/service/app/types.ts` 文件,你可以通过引入它们进行使用。 + +```ts +import { type Category } from '@/service/app' + +const category: Category = { + id: 1, + name: '张三', +} +``` + +## 生成 uni.request 代码 + +ts 的 uni.request 客户端会默认生成在 `src/service/app` 目录下,以模块名进行分类,你可以通过引入它们进行使用。 + +```ts +import { getPetById } from '@/service/app' + +onShow(() => { + const res = await getPetById({ id: 1 }) + console.log('res: ', res) +}) +``` + +## 生成 vue-query 代码 + +vue-query 的代码会默认生成在 `src/service/app` 目录下,以模块名进行分类,后缀为 `moduleName.vuequery.ts`,你可以通过引入它们进行使用。 + +```ts +import { useQuery } from '@tanstack/vue-query' +import { findPetsByStatusQueryOptions, usePlaceOrderMutation } from '@/service/app' + +// get请求使用,findPetsByStatusQueryOptions 方法为自动生成 react-query 函数 +export function findPetsByStatusQueryOptions(options: { + // 叠加生成的Param类型 (非body参数openapi默认没有生成对象) + params: API.findPetsByStatusParams; + options?: CustomRequestOptions; +}) { + return queryOptions({ + queryFn: async ({ queryKey }) => { + return apis.findPetsByStatus(queryKey[1] as typeof options); + }, + queryKey: ['findPetsByStatus', options], + }); +} + +// vue-query useQuery 默认使用 +const { + data, + error + isLoading, + refetch, +} = useQuery(findPetsByStatusQueryOptions({ params: { status: ['available'] } })) + +// vue-query useQuery 额外配置 +const { + data, + error + isLoading, + refetch, +} = useQuery({ + ...findPetsByStatusQueryOptions({ params: { status: ['available'] } }), + enabled: !!token, +}) + +// post, delete, patch请求使用,usePlaceOrderMutation 为自动生成 vue-query hook函数 +export function usePlaceOrderMutation(options?: { + onSuccess?: (value?: API.Order) => void; + onError?: (error?: DefaultError) => void; +}) { + const { onSuccess, onError } = options || {}; + + const response = useMutation({ + mutationFn: apis.placeOrder, + onSuccess(data: API.Order) { + onSuccess?.(data); + }, + onError(error) { + onError?.(error); + }, + }); + + return response; +} + +// 定义请求 +const { mutate, isPending } = usePlaceOrderMutation({ + onSuccess: (data) => { + console.log('success data: ', data) + }, +}) + +// 提交请求 +mutate({ + body: { + status: 'placed', + complete: true, + } +}) +``` diff --git a/docs/base/17-good.png b/docs/base/17-good.png new file mode 100644 index 0000000..9255189 Binary files /dev/null and b/docs/base/17-good.png differ diff --git a/docs/base/18-app-1.png b/docs/base/18-app-1.png new file mode 100644 index 0000000..cf4649a Binary files /dev/null and b/docs/base/18-app-1.png differ diff --git a/docs/base/18-app-2.png b/docs/base/18-app-2.png new file mode 100644 index 0000000..190f5b2 Binary files /dev/null and b/docs/base/18-app-2.png differ diff --git a/docs/base/18-app-3.png b/docs/base/18-app-3.png new file mode 100644 index 0000000..cd0deae Binary files /dev/null and b/docs/base/18-app-3.png differ diff --git a/docs/base/18-app.md b/docs/base/18-app.md new file mode 100644 index 0000000..699b627 --- /dev/null +++ b/docs/base/18-app.md @@ -0,0 +1,72 @@ +# App 专题 + +## 1. 其他端正常,`App` 白屏 + +请检查 `useXxxStore` 的调用,需要在函数内部调用,而不是在函数外部调用。(估计是顶层调用的时候 `pinia` 没有初始化,导致的问题,`app` 端独有的问题。) + +```ts +// 错误写法 +const userStore = useUserStore() +function foo() { + userStore.xxx +} +// 正确写法 +function foo() { + const userStore = useUserStore() + userStore.xxx +} +``` + +## 2.unibest 的 `App` 模块配置 + +> 核心解决办法就是把 `manifest.json` 的内容搬运到 `manifest.config.ts` 中。 + +我们默认的的 `manifest.config.ts` 只包含了比较基础的 `uniapp` 配置,有的时候我们需要在打包 `app` 时在 `hbuilderx` 里面额外设置一些配置,那么就需要配置好后把 `manifest.json` 中的内容拷贝到 `manifest.config.ts` 中,后面运行就不会丢失了。 + +举例子,我在 `manifest.json` 里面配置了 2个模块配置,如下: +![alt text](image-18.png) + +点击左侧下面的 `源码视图` 就可以看到增加了如下内容: +![alt text](image-18-2.png) + +只需要把对应的内容拷贝到 `manifest.config.ts` 中的 `distribute.plugins` 里面即可。 + +## 3. `app` 热更新 + +### 3.1 `ios` 模拟器热更新 + +- `pnpm dev:app` +- 把 `dist/dev/app` 文件夹导入到 `hbx编辑器` 里面,然后运行。这样在编码的时候是可以热更新的。 + +> 但是上面的方法,在android 模拟器里面不生效。 + +### 3.2 `android` 热更新 + +- 在 `android` 里面,把`dist/dev/app` 文件夹导入到 `hbx编辑器` 里面运行,无法热更新!! +- 需要把整个 `unibest 项目中的 src 文件夹` 导入到 `hbx编辑器` 里面,然后运行,这样就可以热更新。 +- 不管是模拟器还是真机调试,都是这样。 + +### 3.3. `鸿蒙` 热更新 + +同 `android` 热更新。 + +## 4. 打包原生插件 + +> 思路:你把整个 `unibest项目的src` 放到 `hbx编辑器`,然后在 `src/mainifest.json` 里面配置好 `原生插件`。然后 `copy` 到`manifest.config.ts`,接着自定义打包基座。 +> 注意,全程不需要用到 `pnp build dev:app` 这个命令. + +步骤: + +- 1. 先配置好 `原生插件`,再 `copy` 到 `manifest.config.ts`。 + + ![alt text](18-app-1.png) + +- 2. 先打包自定义基座 + + ![alt text](18-app-2.png) + +- 3. 使用自定义基座 + + ![alt text](18-app-3.png) + +> 其他参看文章 [掘金教程 - Unibest 原生插件模块配置](https://juejin.cn/post/7496807547447427081) diff --git a/docs/base/2-start.md b/docs/base/2-start.md new file mode 100644 index 0000000..454ae39 --- /dev/null +++ b/docs/base/2-start.md @@ -0,0 +1,131 @@ +# 快速开始 + +- 前置依赖 + + - **Node.js** - `>=v18` + - **pnpm** - `>=7.30`(推荐使用 `8.12+`) + - **`VSCode`** - 可选 `WebStrom` + - **`HBuilderX`** - `APP` 的运行和发布还是离不开它 + +## 创建项目 + +通过下面的命令可以快速生成项目模板,`pnpm create unibest <项目名称>` ,如果不写 `<项目名称>` 会进入命令行交互模式。 + +```bash +# 如果没有 pnpm,请先安装: npm i -g pnpm +pnpm create unibest my-project +# 时不时加一下 @latest 标识,这样可以使用最新版本的 create-unibest (2025-06-04 发布了 v1.18.5) +pnpm create unibest@latest my-project +``` + +npm 创建如下(不推荐) +:::details +如果使用 `npm`,可能有缓存,需要加上 `@latest` 标识,如果创建失败,请使用 `pnpm` 安装。 + +```bash +npm create unibest my-project +# 如果提示报错,或者生成的项目版本太旧,请使用下面的命令,增加 @latest 标识 +npm create unibest@latest my-project +``` + +::: +实际操作截图如下: + +![create project](./assets/2-1.png) + +`create-unibest` 在 `v1.10.0` 开始会有版本号,如下: + +![alt text](./assets/2-2.png) + +![unibest templates](https://oss.laf.run/ukw0y1-site/xmind/unibest模板.png) + +`create unibest` 支持 `-t` 参数选择模板,目前已有两大类 `8` 个模板 + +- `普通` 模板( `4个` ):分别是 `base`、`tabbar`、`spa`、 `i18n`、`demo`。 +- `hbx` 模板(`2个` ):分别是 `hbx-base`、`hbx-demo`。 + +不带 `-t` 参数时会默认生成 `base` 模板。 + +`base` 模板是最基本的模板,更新最及时,推荐使用 `base` 模板创建新项目。其他几个模板也是基于 `base` 模板得到的。 `demo` 模板则作为参考用。 + +`base` 模板的改动会自动同步到其他几个分支,通过 `github actions` 实现。 + +::: details `tabbar 模板` 和 `spa 模板` 的区别 + +- `tabbar` 模板里面的tabbar 路由是属于 `tabbar` 级别的,需要使用 `switchTabbar` 切换,`tabbar` 页面会有缓存,渲染性能较好。 +- `spa` 模板类似于前端的 `SPA 应用`,`tabbar` 完全是一个组件实现的。页面之间切换是通过前端状态控制,简单灵活,不受 `tabbar` 的配置限制,但性能不如 `tabbar` 模板。 +- 两者各有优点,按需选用。 + +::: + +```sh +# VS Code 模板 +pnpm create unibest my-project # 默认用 base 模板 + +pnpm create unibest my-project -t base # 基础模板 +pnpm create unibest my-project -t tabbar # 自定义 tabbar 模板 +pnpm create unibest my-project -t spa # 单页应用 模板(使用一个组件模拟tabbar) +pnpm create unibest my-project -t i18n # 多语言模板 +pnpm create unibest my-project -t demo # 所有demo的模板(包括i18n) + +# HBuilderX 模板,方便使用 uniCloud 云开发 (未来可以对接 uni-app x) +pnpm create unibest my-project -t hbx-base # hbx的base模板 +pnpm create unibest my-project -t hbx-demo # hbx的demo模板,包含所有的demo +``` + +> 2024-12-29<周日> 发表了一篇文章:[【unibest】可以去掉hbx模版了,base模板一统天下](https://mp.weixin.qq.com/s/ybunFNkjKfV5yVLOMvqscg?token=1696234630&lang=zh_CN) +> +> 就是说 hbx 模板可以退出历史舞台了。 + +## 项目仓库地址 + +`github` 和 `gitee` 实时同步,代码一致。 + +### 普通模板: + +- https://github.com/feige996/unibest +- https://gitee.com/feige996/unibest + +> `demo` 模板是在 `hello-unibest` 项目中,仓库地址如下: + +- https://github.com/feige996/hello-unibest +- https://gitee.com/feige996/hello-unibest + +### hbx 模板 + +- https://github.com/uni-run/unibest-hbx + +> `hbx` 目前由 `青谷` 大佬维护,微信号:`qingguxixi`,[青谷 github 地址](https://github.com/Xiphin) 。 + +## 安装、运行 + +```bash [pnpm] +pnpm i +pnpm dev +# dev默认运行的是h5,其他平台执行dev:,如: +pnpm dev:mp-weixin +``` + +`pnpm dev` 之后在浏览器打开 `http://localhost:9000/`。 + +> 其他平台构建和发布,查看 [运行发布篇](./11-build)。 + +## 第一次 `commit` + +```bash +git add . +git commit -m "feat: init project" +``` + +## `v3` 代码块 + +在 `vue` 文件中,输入 `v3` 按 `tab` 即可快速生成页面模板,可以大大加快页面生成。 + +> 原理:基于 `VSCode` 代码块生成。 + +![alt text](./assets/2-4.gif) + +## 注意事项 + +- 若代码里面自动引入的 `API` 报错,只需要 `pnpm dev` 即可。 +- 若代码运行后,`H5端` 浏览器界面底部没有 `tabbar`, 刷新浏览器或者再次 `pnpm dev` 即可。 diff --git a/docs/base/20-best.md b/docs/base/20-best.md new file mode 100644 index 0000000..04b0ec2 --- /dev/null +++ b/docs/base/20-best.md @@ -0,0 +1,31 @@ +# 最佳实践 + +新项目使用 `base` 模板,可选 `tabbar` 模板。如果需要多语言,可以选 `i18n` 模板。 + +同时参考 `demo` 模板,可以直接 `clone` `demo` 项目,用来参考用。 + +![unibest templates](https://oss.laf.run/ukw0y1-site/xmind/unibest模板.png) + +## 创建项目 + +推荐使用 `pnpm` : + +```sh +# 新项目创建 +pnpm create unibest my-project -t base +``` + +## DEMO 模板 + +`demo` 模版-在线地址: + +推荐先全部体验一下 `demo` 的示例 + +## 必看章节 + +- [介绍](/base/1-introduction) +- [快速开始](/base/2-start) +- [uni 插件](/base/3-plugin) +- [常见问题](/base/14-faq) +- [常见问题 2](/base/15-faq) +- [运行发布](/base/11-build) diff --git a/docs/base/3-plugin.md b/docs/base/3-plugin.md new file mode 100644 index 0000000..7eb0c24 --- /dev/null +++ b/docs/base/3-plugin.md @@ -0,0 +1,158 @@ +# uni 插件 + +## 引言 + +有群友第一次看到 `unibest` 里面 `vue` 文件 `route-block` 这种写法,表示很奇怪,从来没见过! + +```vue + +{ + layout: 'demo', + style: { + navigationBarTitleText: '标题', + }, +} + + + +``` + +## uni 插件总览 + +哈哈,这个当然是 `uni插件` 的功劳了,具体点是 `@uni-helper/vite-plugin-uni-pages` 插件的功劳,该插件由 `uni-helper` 官方团队开发。 + +本文就来说说 `unibest` 都引入了哪些有用的 `uni插件`。下面这个表格描述了各个插件的主要作用。 + +| 插件名 | 作用 | +| :----------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| @dcloudio/vite-plugin-uni | **最核心的 `uni 插件`**,没有它就不能在 vite 项目跑 uniapp,其他所有的 `uni插件` 都需要经通过它的手来编译,所以写法上,都是先写 `UniXXX`,再写 `Uni`,见下文 | +| @uni-helper/vite-plugin-uni-pages | `uni 插件`,也是 `unibest 灵魂插件`,`route-block` 就是它的功劳,让你可以直接在本文件就能设置页面的路元信息,无需跑去 `pages.json` 配置,同时支持 `pages.config.ts` 编写 `pages.json` | +| @uni-helper/vite-plugin-uni-layouts | `uni 插件`,支持多种 `layouts` 布局,群友脑洞大开,充分利用这个特性实现平时不容易实现的布局 | +| @uni-helper/vite-plugin-uni-manifest | `uni 插件`,支持 `manifest.config.ts` 编写 `manifest.json` | + +`UniXXX()` 插件都需要在 `uni()` 之前引入,因为最终都需要 `Uni` 来处理所有的代码。如下图: +![vite uni plugin](./assets/3-1.png) + +接下来介绍一下 `uni 插件`,其他 `通用插件` 大家都比较熟悉,不再赘述。 + +`unibest` 引入了 `uni-helper` 团队的几个重要插件,少了它们 `unibest` 就缺少了灵魂,感谢 `uni-helper` 团队的贡献。`Uni 插件` 列表如下: + +- `vite-plugin-uni-pages` + + - 介绍:为 `Vite` 下的 `uni-app` 提供基于文件系统的路由 + - 额外:使用 `TypeScript` 来编写 `uni-app` 的 `pages.json` + - 访问地址:[@uni-helper/vite-plugin-uni-pages](https://github.com/uni-helper/vite-plugin-uni-pages) + +- `vite-plugin-uni-layouts` + + - 介绍:为 `Vite` 下的 `uni-app` 提供类 `nuxt` 的 `layouts` 系统 + - 访问地址:[@uni-helper/vite-plugin-uni-layouts](https://github.com/uni-helper/vite-plugin-uni-layouts) + +- `vite-plugin-uni-manifest` + + - 介绍:使用 `TypeScript` 来编写 `uni-app` 的 `manifest.json` + - 访问地址:[@uni-helper/vite-plugin-uni-manifest](https://github.com/uni-helper/vite-plugin-uni-manifest) + +## vite-plugin-uni-pages + +得益于 [@uni-helper/vite-plugin-uni-pages](https://github.com/uni-helper/vite-plugin-uni-pages),约定式路由(文件路由)的实现轻而易举。 + +`src/pages` 目录下的每个文件都代表着一个路由。要创建新页面,只需要在这个目录里新增 `.vue` 文件,插件会自动生成对应的 `pages.json` 文件。 + +`route` 代码块则可以配置页面相关信息,这些信息会自动同步到 `page.json`,无需切换到 `page.json` 进行配置。 + +> `pages.json` 文件是自动生成的,请不要手动修改,全局的东西请在 `pages.config.ts` 里面配置,页面上的东西请在 `vue` 文件的 `route` 代码块配置,如下图。 + +```vue [src/pages/index.vue] + + + +{ + style: { + navigationStyle: 'custom', + navigationBarTitleText: '首页', + }, +} + + +``` + +```vue [src/pages/about.vue] + +{ + style: { + navigationBarTitleText: '关于', + }, +} + + +``` + +### 设置首页 + +通过在 `route-block` 里面配置 `type="home"` 即可,尽量保证一个项目 `只有一个` 这个配置,如果有多个,会按照字母顺序来排列,最终可能不是您想要的效果。 + +### 设置 pages 过滤和分包 + +- 过滤:默认 `src/pages` 里面的 `vue` 文件都会生成一个页面,如果不需要生成页面可以对 `vite.config.ts` 中的 `UniPages` 进行 `exclude` 配置。 + +- 分包:如果需要设置 `分包` 则可以通过 `subPackages` 进行配置,该配置项是个数组,可以配置多个 `分包`,注意分包的目录不能为 `src/pages` 里面的子目录。 + +```ts [vite.config.ts] +UniPages({ + exclude: ['**/components/**/**.*'], + subPackages: ['src/pages-sub'], // 是个数组,可以配置多个,但不能为 `src/pages` 里面的子目录 +}) +``` + +## vite-plugin-uni-layouts + +得益于 [@uni-helper/vite-plugin-uni-layouts](https://github.com/uni-helper/vite-plugin-uni-layouts),你可以轻松地切换不同的布局。 + +`src/layouts` 文件夹下的 `vue` 文件都会自动生成一个布局,默认的布局文件名为 `default` ,路径 `src/layouts/default.vue` 。 + +如果需要修改使用的布局,可以通过 `vue` 文件内 `route` 代码块指定需要的布局,如下示例使用 `demo` 布局。 + +```vue [src/pages/demo.vue]{3} + +{ + layout: 'demo', + style: { + navigationBarTitleText: '关于', + }, +} + +``` + +```vue [src/layouts/demo.vue] + +``` + +## vite-plugin-uni-manifest + +得益于 [@uni-helper/vite-plugin-uni-manifest](https://github.com/uni-helper/vite-plugin-uni-manifest),你可以使用 `TypeScript` 来编写 `manifest.json`。 + +> `manifest.json` 文件是自动生成的,请不要手动修改,需要配置的内容请在 `manifest.config.ts` 里面配置。 + +## 总结 + +本文介绍了 `unibest` 引入的几个重要的 `uni插件`。 + +如果还想了解更多信息,可以去 `uni-helper` [github 仓库](https://github.com/uni-helper) 看看。 diff --git a/docs/base/4-style.md b/docs/base/4-style.md new file mode 100644 index 0000000..f5f7a64 --- /dev/null +++ b/docs/base/4-style.md @@ -0,0 +1,220 @@ +# 样式篇 + +本篇主要介绍 `UnoCSS` 的使用,以及如何与 `设计稿尺寸` 对应。 + +## UnoCSS + +[UnoCSS](https://unocss.dev/) 是按需使用的原子 CSS 引擎,提供了良好的样式支持。 + +![alt text](./assets/4-1.png) + +在 VSCode 中还可以预览, + +![alt text](./assets/4-2.png) + +![alt text](./assets/4-3.png) + +> 如果原子化 `UnoCSS` 没有预览效果,请安装 `VSCode` 插件 `antfu.unocss`。 + +如果不记得原子类,可以查 `UnoCSS 的原子类`,[UnoCSS Interactive](https://unocss.dev/interactive/),如下图 +![alt text](./assets/4-4.png) + +也可以查看 `tailwindcss` 的原子类,更加清晰明了,[链接 - tailwindcss](https://tailwindcss.com/),如下图: + +![alt text](./assets/4-5.png) + +## 常用的原子类 + +- 宽高内外边距: `w-2`, `h-4`, `px-6`, `mt-8`等 +- 前景色背景色:`text-green-400`, `bg-green-500` +- border: `border-2`, `border-solid`, `border-green-600`, `b-r-2` (注意 `border` = `border-1`,就是说边框 `1px` 时,一般简写为 `border` ) +- border-radius: `rounded-full`, `rounded-6`, `rounded-sm` (不是 `br-10`, 也不是 `b-r-10`) +- line-height: `leading-10` (不是 `l-10`, 也不是 `lh-10`) +- hover: `hover:text-green-200`, `hover:bg-green-300`, `hover:border-dashed` +- flex: `flex`, `items-center`, `justify-center`, `flex-1` + +## `UnoCSS` 配置 + +下面内容选读: + +:::details +`unocss.config.ts` 文件内容如下: + +```ts +// uno.config.ts +import { + type Preset, + defineConfig, + presetUno, + presetAttributify, + presetIcons, + transformerDirectives, + transformerVariantGroup, +} from 'unocss' + +import { presetApplet, presetRemRpx, transformerAttributify } from 'unocss-applet' + +// @see https://unocss.dev/presets/legacy-compat +import { presetLegacyCompat } from '@unocss/preset-legacy-compat' + +const isMp = process.env?.UNI_PLATFORM?.startsWith('mp') ?? false + +const presets: Preset[] = [] +if (isMp) { + // 使用小程序预设 + presets.push(presetApplet(), presetRemRpx()) +} else { + presets.push( + // 非小程序用官方预设 + presetUno(), + // 支持css class属性化 + presetAttributify(), + ) +} +export default defineConfig({ + presets: [ + ...presets, + // 支持图标,需要搭配图标库,eg: @iconify-json/carbon, 使用 `