UniApp 系统结构
目录
1. 功能说明
概述
本文档详细介绍 Niucloud UniApp 端的系统架构和目录结构,UniApp 用于开发移动端应用,支持编译到微信小程序、H5、App 等多个平台。
适用场景
- 移动端功能开发
- 跨平台应用开发
- 小程序开发
2. 设计思路
技术栈
- 框架:UniApp (Vue 3)
- 状态管理:Pinia
- UI 组件库:uni-ui / uview-plus
- HTTP 客户端:uni.request 封装
- 样式:SCSS
架构特点
- 一套代码,多端运行
- 组件化开发
- 平台差异化处理
- 统一的 API 封装
3. 系统架构
3.1 整体架构
┌─────────────────────────────────────────────────────────────┐
│ 多端输出层 │
│ 微信小程序 H5 App(iOS/Android) 快应用 │
└──────────────────────────┬──────────────────────────────────┘
│
┌──────────────────────────▼──────────────────────────────────┐
│ UniApp 框架层 │
│ 条件编译、组件系统、API 封装 │
└──────────────────────────┬──────────────────────────────────┘
│
┌──────────────────────────▼──────────────────────────────────┐
│ 业务逻辑层 │
│ 页面组件、业务组件、状态管理、工具函数 │
└──────────────────────────┬──────────────────────────────────┘
│
┌──────────────────────────▼──────────────────────────────────┐
│ 后端 API 接口 │
└─────────────────────────────────────────────────────────────┘3.2 平台适配
src/
├── pages/ # 主包页面
├── pages-sub/ # 分包页面
├── components/ # 公共组件
├── static/ # 静态资源
│ ├── images/ # 图片资源
│ └── icons/ # 图标资源
├── utils/ # 工具函数
├── api/ # API 接口
├── stores/ # 状态管理
├── styles/ # 公共样式
└── App.vue # 应用入口4. 目录结构
4.1 整体目录
uni-app/ # UniApp 项目
├── src/
│ ├── api/ # API 接口
│ ├── components/ # 公共组件
│ ├── composables/ # 组合式函数
│ ├── dict/ # 数据字典
│ ├── layouts/ # 布局组件
│ ├── pages/ # 主包页面
│ ├── pages-sub/ # 分包页面
│ ├── static/ # 静态资源
│ ├── stores/ # 状态管理
│ ├── styles/ # 公共样式
│ ├── utils/ # 工具函数
│ ├── App.vue # 应用入口
│ ├── main.ts # 主入口
│ ├── manifest.json # 应用配置
│ ├── pages.json # 页面配置
│ └── uni.scss # 全局样式
├── index.html # H5 模板
├── package.json # 依赖配置
├── tsconfig.json # TypeScript 配置
├── vite.config.ts # Vite 配置
└── ...4.2 页面目录 (src/pages/)
src/pages/
├── index/ # 首页
│ └── index.vue
├── category/ # 分类页
│ └── index.vue
├── cart/ # 购物车
│ └── index.vue
├── user/ # 用户中心
│ ├── index.vue # 用户主页
│ ├── setting.vue # 设置
│ └── info.vue # 个人信息
├── login/ # 登录相关
│ ├── index.vue # 登录页
│ ├── register.vue # 注册页
│ └── forgot.vue # 找回密码
└── ...4.3 分包目录 (src/pages-sub/)
src/pages-sub/
├── order/ # 订单相关
│ ├── list.vue # 订单列表
│ ├── detail.vue # 订单详情
│ └── confirm.vue # 确认订单
├── pay/ # 支付相关
│ ├── result.vue # 支付结果
│ └── method.vue # 支付方式
└── ...4.4 组件目录 (src/components/)
src/components/
├── common/ # 通用组件
│ ├── empty/ # 空状态
│ ├── loading/ # 加载状态
│ └── navbar/ # 导航栏
├── business/ # 业务组件
│ ├── goods-item/ # 商品卡片
│ ├── order-item/ # 订单卡片
│ └── address-item/ # 地址卡片
└── ...4.5 API 目录 (src/api/)
src/api/
├── auth.ts # 认证相关
├── member.ts # 会员相关
├── goods.ts # 商品相关
├── order.ts # 订单相关
├── pay.ts # 支付相关
└── index.ts # 统一导出4.6 工具目录 (src/utils/)
src/utils/
├── request.ts # 请求封装
├── auth.ts # 认证工具
├── storage.ts # 存储工具
├── validate.ts # 验证工具
├── platform.ts # 平台判断
├── router.ts # 路由工具
└── index.ts # 统一导出4.7 状态管理 (src/stores/)
src/stores/
├── modules/
│ ├── user.ts # 用户状态
│ ├── app.ts # 应用配置
│ └── cart.ts # 购物车状态
└── index.ts # 统一导出5. 常见问题
Q1: 如何进行条件编译
vue
<template>
<!-- #ifdef H5 -->
<view>H5 平台显示</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view>微信小程序显示</view>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<view>App 平台显示</view>
<!-- #endif -->
</template>
<script setup>
// #ifdef H5
console.log('H5 平台');
// #endif
// #ifdef MP-WEIXIN
console.log('微信小程序');
// #endif
</script>
<style>
/* #ifdef H5 */
.h5-style { color: red; }
/* #endif */
</style>Q2: 如何配置分包
json
// pages.json
{
"pages": [
{
"path": "pages/index/index",
"style": { "navigationBarTitleText": "首页" }
}
],
"subPackages": [
{
"root": "pages-sub/order",
"pages": [
{ "path": "list", "style": { "navigationBarTitleText": "订单列表" } },
{ "path": "detail", "style": { "navigationBarTitleText": "订单详情" } }
]
}
],
"preloadRule": {
"pages/index/index": {
"network": "all",
"packages": ["pages-sub/order"]
}
}
}Q3: 如何封装请求
typescript
// src/utils/request.ts
import { useUserStore } from '@/stores';
const baseURL = import.meta.env.VITE_API_BASE_URL;
export function request<T>(options: UniApp.RequestOptions): Promise<T> {
return new Promise((resolve, reject) => {
const userStore = useUserStore();
uni.request({
...options,
url: baseURL + options.url,
header: {
'Authorization': `Bearer ${userStore.token}`,
...options.header
},
success: (res) => {
if (res.statusCode === 200) {
resolve(res.data as T);
} else {
reject(res);
}
},
fail: reject
});
});
}
// 使用
import { request } from '@/utils/request';
const getUserInfo = async () => {
const res = await request({
url: '/api/member/info',
method: 'GET'
});
};修订记录
| 版本 | 日期 | 修订人 | 修订内容 |
|---|---|---|---|
| v1.0 | 2026-04-08 | Niucloud Team | 初始版本 |
