# base-uniapp **Repository Path**: riskboy/base-uniapp ## Basic Information - **Project Name**: base-uniapp - **Description**: base-uniapp - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-12-09 - **Last Updated**: 2025-12-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # base-uniapp 基于 Vue 3 + TypeScript + Vite 的 uni-app 多端开发基础模板。 ## 技术栈 - Vue 3.4 + TypeScript - Vite 5 - Pinia 状态管理 - UnoCSS 原子化 CSS - uview-plus UI 组件库 - vue-i18n 国际化 ## 支持平台 H5 / 微信小程序 / 支付宝小程序 / 抖音小程序 / QQ小程序 / APP ## 项目结构 ``` src/ ├── api/ # 接口定义 ├── components/ # 组件 │ ├── my/ # 自定义组件 │ ├── navbarContent/ │ └── tabbar/ ├── hooks/ # 组合式函数 ├── pages/ # 页面 ├── static/ # 静态资源 ├── stores/ # Pinia 状态 ├── types/ # 类型定义 └── utils/ # 工具函数 ``` ## 命令 ```bash pnpm dev:h5 # H5 开发 pnpm dev:mp-weixin # 微信小程序开发 pnpm dev:app # APP 开发 pnpm build:h5 # H5 构建 pnpm build:mp-weixin # 微信小程序构建 pnpm build:app # APP 构建 pnpm lint # 代码检查 pnpm lint:fix # 代码修复 ``` ## 环境变量 ``` VITE_API_URL # API 基础地址 VITE_API_PREFIX # API 前缀 ``` ## API 规范 ```ts // src/api/xxx.ts import request from "@/utils/request"; export const xxxApi = { getList: (params: object) => request({ url: "/xxx", method: "GET", params }), create: (data: object) => request({ url: "/xxx", method: "POST", data }) } ``` ### Request 配置项 | 参数 | 类型 | 说明 | |------|------|------| | url | string | 请求路径 | | method | GET/POST | 请求方法 | | params | object | GET 参数(自动过滤空值) | | data | object | POST 数据 | | header | object | 请求头 | | prefix | string | 接口前缀(覆盖 VITE_API_PREFIX) | | cancelPrevious | boolean | 是否取消之前的同 key 请求 | | requestKey | string | 请求标识(配合 cancelPrevious 使用) | Token 自动从 `uni.getStorageSync("token")` 获取并携带。 ## Utils 工具函数 | 函数 | 说明 | |------|------| | `redirect(options)` | 页面跳转,自动识别 tabbar 页面 | | `copy(value, callback)` | 复制到剪贴板 | | `getElementRect(selector, instance?)` | 获取元素布局信息 | | `currRoute()` | 获取当前路由路径 | | `currFullPath()` | 获取当前完整路径(含 /) | | `formatArguments(data)` | 过滤对象中的空值 | | `getPx(value, unit?)` | 转换 rpx/upx 为 px | | `addUnit(value, unit?)` | 添加单位 | | `delay(ms)` | 延迟 Promise | | `isUrl(str)` | 判断是否是 URL | | `isJsonString(str)` | 判断是否是 JSON 字符串 | | `isWeixinBrowser()` | 判断是否微信浏览器 | | `getTabbarPages()` | 获取 tabbar 页面列表 | | `queryParams(params, filterEmpty?)` | 对象转查询字符串 | | `parseQuery(query)` | 查询字符串转对象 | | `getImageInfo(src)` | 获取图片信息 Promise | | `getDownloadFileInfo(url)` | 下载文件 Promise | ### redirect 配置 ```ts redirect({ url: "/pages/xxx/index", mode: "navigateTo" | "switchTab" | "reLaunch" | "redirectTo", param: { id: 1 }, success: () => {}, fail: () => {} }) ``` ## Hooks ### useList - 列表分页 ```ts const { data, total, isLoading, isLoadMore, error, getList, resetState } = useList(api, { immediate: true, needReachBottom: true, params: { page: 1, size: 10 }, path: { dataKey: "list", totalKey: "count", pageKey: "page", sizeKey: "size" }, manageData: (data) => {} }) ``` ### useResetState - 状态重置 ```ts const [state, reset] = useResetReactive({ name: "", age: 0 }) const [refState, resetRef] = useResettableRef({ count: 0 }) ``` ### useSafeAreaInsets - 安全区域 ```ts const { saveTop, safeBottom } = useSafeAreaInsets() ``` ### useMenuButtonInfo - 胶囊按钮信息 ```ts const { menuLeft, menuRight, menuTop, menuHeight } = useMenuButtonInfo() ``` ### useSaveTopBoxHeight - 导航栏高度 ```ts const { height, contentHeight, contentWidth, statusBarHeight } = useSaveTopBoxHeight(contentHeight?) ``` ### useScrollTop - 页面滚动 ```ts const { scrollTop } = useScrollTop(handleScroll?) ``` ### useAnimation - 元素进入动画 ```ts const { show, AnimationFormat, transitionDuration } = useAnimation(selector, { delay: 0.1, duration: 0.3 }) ``` ### useImgInfo - 图片尺寸计算 ```ts const { height, imgratio, updateImgInfo } = useImgInfo(imgUrl, selector, immediate?) ``` ## Stores ### useConfigStore - 系统配置 | 属性/方法 | 说明 | |-----------|------| | navHeight | 导航栏高度(rpx) | | windowHeight | 窗口高度 | | screenHeight | 屏幕高度 | | safeAreaInsets | 安全区域 { top, right, bottom, left } | | menuButtonInfo | 胶囊按钮信息 | | XClientType | 客户端类型:h5/wechat/miniProgram/app | | getNavHeight() | 初始化导航栏高度 | | setXClientType() | 初始化客户端类型 | | getMenuButtonInfo() | 初始化胶囊信息 | ### useTabbarStore - 底部导航 | 属性 | 说明 | |------|------| | tabbarItemHeight | tabbar 项高度 | | tabbarHeight | tabbar 总高度(含安全区域) | | tabbarList | tabbar 配置列表 | ### useThemeStore - 主题 | 属性/方法 | 说明 | |-----------|------| | themeStyle | 主题 CSS 变量对象 | | hexToRgba(hex, alpha) | 颜色转换 | 默认主题变量:`--theme-color`, `--accent`, `--bg`, `--text`, `--text-muted` ## 自定义组件 ### my-layout - 页面布局 ```vue 内容 ``` | Prop | 类型 | 默认值 | 说明 | |------|------|--------|------| | title | string | "" | 导航栏标题(有值则显示 navbar) | | tabbarIndex | number | -1 | tabbar 索引(>=0 显示 tabbar) | | needSafeTop | boolean | false | 是否需要顶部安全区域 | | needSafeBottom | boolean | true | 是否需要底部安全区域 | | safeTopBgColor | string | #fff | 顶部安全区背景色 | | background | string | #fff | 导航栏背景色 | | color | string | #000 | 导航栏文字颜色 | | borderBottom | boolean | false | 导航栏底部边框 | | customBack | boolean | false | 自定义返回事件 | 事件:`@back` ### my-navbar - 导航栏 ```vue ``` | Prop | 类型 | 默认值 | 说明 | |------|------|--------|------| | title | string | "" | 标题 | | background | string | #fff | 背景色 | | color | string | #000 | 文字颜色 | | showLeft | boolean | true | 显示左侧返回 | | customBack | boolean | false | 自定义返回事件 | | borderBottom | boolean | false | 底部边框 | 插槽:`left`, `title`, `right` 事件:`@back` ### my-image - 图片 ```vue ``` | Prop | 类型 | 默认值 | 说明 | |------|------|--------|------| | src | string | 必填 | 图片地址 | | mode | string | "" | 裁剪模式 | | preview | boolean | false | 点击预览大图 | 事件:`@load`, `@error` ### my-lazy-image - 懒加载图片 ```vue ``` | Prop | 类型 | 默认值 | 说明 | |------|------|--------|------| | src | string | "" | 图片地址 | | mode | string | "" | 裁剪模式 | | threshold | number | 100 | 预加载阈值(px) | 事件:`@load`, `@error` ### my-swiper - 轮播图 ```vue ``` | Prop | 类型 | 默认值 | 说明 | |------|------|--------|------| | list | array | [] | 数据列表 | | height | number/string | 150 | 高度 | | bottom | number/string | 10 | 指示器距底部距离 | | autoplay | boolean | true | 自动播放 | | interval | number | 3000 | 切换间隔(ms) | | displayMultipleItems | number | 1 | 同时显示数量 | | previousMargin | string | "0" | 前边距 | 插槽:`default({ item, current })`, `indicator({ current })` 事件:`@change` ## CSS 变量 | 变量 | 说明 | |------|------| | --nav-height | 导航栏高度 | | --safe-top | 顶部安全区域高度 | | --safe-bottom | 底部安全区域高度 | | --tabbar-height | tabbar 高度 | | --theme-color | 主题色 | | --accent | 强调色 | | --bg | 背景色 | | --text | 文字颜色 | | --text-muted | 次要文字颜色 | ## UnoCSS 快捷方式 ``` flex-column, justify-center, align-center, flex1 line1, line2, line3, line4 # 文本截断 ``` ## 图标使用 基于 UnoCSS + Iconify 的纯 CSS 图标方案,三端兼容。 ### 安装图标集 ```bash pnpm add -D @iconify-json/carbon ``` ### 使用 ```vue ``` ### 格式 ``` i-{图标集}-{图标名} ``` ### 常用图标集 | 包名 | 前缀 | 说明 | |------|------|------| | @iconify-json/carbon | i-carbon- | IBM Carbon | | @iconify-json/mdi | i-mdi- | Material Design | | @iconify-json/ri | i-ri- | Remix Icon | | @iconify-json/tabler | i-tabler- | Tabler Icons | 图标浏览:https://icon-sets.iconify.design/ ## 条件编译 ```ts // #ifdef H5 // 仅 H5 执行 // #endif // #ifdef MP-WEIXIN // 仅微信小程序执行 // #endif // #ifdef APP-PLUS // 仅 APP 执行 // #endif // #ifndef H5 // 非 H5 执行 // #endif ``` ## 新增页面 1. 在 `src/pages/` 下创建页面文件夹和 `index.vue` 2. 在 `src/pages.json` 的 pages 数组中添加路径 3. 如需添加 tabbar 页面,同时在 tabBar.list 和 stores/modules/tabbar.ts 中配置 ## easycom 组件规则 ```json { "my-(.*)": "@/components/my/my-$1/my-$1.vue" } ``` 自定义组件:``, ``, ``, ``, ``