以下架构经过了多个项目的实践检验,遵循了良好的工程化原则。
🏗️ 推荐的 uni-app 多端应用目录架构
my-uniapp-project/ # 项目根目录
├── src/ # 源代码目录(核心)
│ ├── api/ # 接口请求层
│ │ ├── modules/ # 按模块划分的接口文件
│ │ │ ├── user.js # 用户相关接口
│ │ │ ├── product.js # 商品相关接口
│ │ │ └── order.js # 订单相关接口
│ │ ├── request.js # 请求封装(拦截器、基地址等)
│ │ └── index.js # 统一导出所有接口
│ ├── components/ # 全局通用组件
│ │ ├── base/ # 基础UI组件(可复用性最高)
│ │ │ ├── ui-button/
│ │ │ ├── ui-loading/
│ │ │ └── ui-modal/
│ │ ├── business/ # 业务组件
│ │ │ ├── product-card/
│ │ │ ├── search-bar/
│ │ │ └── tab-bar/
│ │ └── index.js # 全局组件自动注册
│ ├── pages/ # 页面文件(uni-app约定目录)
│ │ ├── index/
│ │ │ └── index.vue # 首页
│ │ ├── user/
│ │ │ ├── index.vue # 用户中心
│ │ │ └── setting.vue # 设置页
│ │ └── ... # 其他页面
│ ├── static/ # 静态资源(uni-app约定目录)
│ │ ├── images/ # 图片资源
│ │ │ ├── icons/ # 图标类图片
│ │ │ ├── tabbar/ # 标签栏图片
│ │ │ └── common/ # 通用图片
│ │ └── data/ # 静态数据(如省市区JSON)
│ ├── store/ # 状态管理(Vuex)
│ │ ├── modules/ # 模块化store
│ │ │ ├── user.js # 用户状态模块
│ │ │ ├── app.js # 应用状态模块
│ │ │ └── cart.js # 购物车状态模块
│ │ └── index.js # store入口文件
│ ├── utils/ # 工具函数库
│ │ ├── request.js # 网络请求封装
│ │ ├── utils.js # 通用工具函数
│ │ ├── filter.js # 全局过滤器
│ │ ├── const.js # 全局常量
│ │ ├── cache.js # 缓存封装
│ │ └── utils.js # 通用工具函数
│ ├── mixins/ # 混入(可选)
│ ├── styles/ # 全局样式
│ │ ├── index.scss # 主样式文件(引入其他文件)
│ │ ├── variables.scss # Scss变量(颜色、字体等)
│ │ ├── mixins.scss # Scss混入
│ │ └── common.scss # 通用样式类
│ ├── uni_modules/ # uni-app插件市场安装的模块
│ ├── App.vue # 应用入口组件
│ ├── main.js # 应用入口文件
│ └── manifest.json # 应用配置文件
├── platforms/ # 各平台差异化代码(条件编译)
│ ├── mp-weixin/ # 微信小程序专用代码
│ ├── mp-alipay/ # 支付宝小程序专用代码
│ ├── app-plus/ # App专用代码
│ └── h5/ # H5专用代码
├── nativeplugins/ # 原生插件(如果需要)
├── unpackage/ # 打包输出目录(编译生成)
├── static/ # 纯粹的静态资源(不经过构建)
├── pages.json # 页面配置文件(路由、导航栏等)
├── uni.scss # uni-app内置的常用样式变量
├── index.html # H5模板文件
├── package.json # 项目配置和依赖
└── vue.config.js # Vue CLI配置(如果使用)
⚙️ 核心配置文件详解
1. pages.json(路由和全局样式配置)
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页",
"enablePullDownRefresh": true
}
}
],
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#007AFF",
"list": [
{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "static/images/tabbar/home.png",
"selectedIconPath": "static/images/tabbar/home-active.png"
}
]
},
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "我的应用",
"navigationBarBackgroundColor": "#F8F8F8"
}
}
2. manifest.json(多端配置)
{
"name": "我的应用",
"appid": "__UNI__XXXXXX",
"description": "应用描述",
"h5": {
"publicPath": "./",
"router": {
"mode": "hash"
}
},
"mp-weixin": {
"appid": "wxxxxxxx",
"setting": {
"urlCheck": false
}
},
"app-plus": {
"usingComponents": true
}
}
🔧 关键代码规范与最佳实践
1. 请求封装 (utils/request.js)
// 基于 uni.request 的封装
const request = (options) => {
return new Promise((resolve, reject) => {
uni.request({
url: options.url,
method: options.method || 'GET',
data: options.data,
header: {
'Content-Type': 'application/json',
'Authorization': uni.getStorageSync('token') || '',
...options.header
},
success: (res) => {
if (res.statusCode === 200) {
resolve(res.data)
} else {
reject(res)
}
},
fail: (reject)
})
})
}
export default request
2. 状态管理 (store/index.js)
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
import app from './modules/app'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
user,
app
}
})
export default store
3. 全局组件自动注册 (components/index.js)
import Vue from 'vue'
// 自动注册 base 目录下的所有组件
const requireComponent = require.context(
'./base',
true,
/\.vue$/
)
requireComponent.keys().forEach(fileName => {
const componentConfig = requireComponent(fileName)
const componentName = fileName
.split('/')
.pop()
.replace(/\.\w+$/, '')
Vue.component(componentName, componentConfig.default || componentConfig)
})
4. 样式变量管理 (styles/variables.scss)
// 颜色
$primary-color: #007AFF;
$success-color: #4CD964;
$warning-color: #F0AD4E;
$error-color: #DD524C;
// 字体
$font-size-small: 24rpx;
$font-size-base: 28rpx;
$font-size-large: 32rpx;
// 间距
$spacing-base: 20rpx;
$spacing-large: 40rpx;
在 App.vue中引入:
<style lang="scss">
@import '@/styles/variables.scss';
@import '@/styles/common.scss';
/* 全局样式 */
</style>
📱 多端适配策略
1. 条件编译
// #ifdef H5
console.log('只在H5平台执行')
// #endif
// #ifdef MP-WEIXIN
console.log('只在微信小程序执行')
// #endif
// #ifdef APP-PLUS
console.log('只在App平台执行')
// #endif
2. 平台差异化样式
.header {
height: 88rpx;
// #ifdef H5
padding-top: 44px; // H5需要考虑导航栏
// #endif
// #ifdef MP-WEIXIN
padding-top: 44px; // 微信小程序自定义导航栏
// #endif
}
3. 组件多端适配
<template>
<view class="container">
<!-- 通用内容 -->
<text>通用内容</text>
<!-- 平台特定内容 -->
// #ifdef H5
<button @click="h5Method">H5特有按钮</button>
// #endif
// #ifdef MP-WEIXIN
<button open-type="share">微信分享</button>
// #endif
</view>
</template>
🚀 开发规范与工作流
| 规范类别 | 具体规则 | 示例 |
|---|---|---|
| 文件命名 | 组件、页面使用kebab-case,JS文件使用camelCase | user-center.vue, userApi.js |
| 目录命名 | 统一使用kebab-case | product-detail/ |
| CSS类名 | 使用BEM命名规范 | .product-card__title--highlight |
| Git分支 | 主分支main,开发分支develop,功能分支feature/xxx | feature/user-auth |
| 提交信息 | 使用约定式提交 | feat: 添加用户登录功能 |
💡 高级目录扩展(针对大型项目)
对于更复杂的项目,可以考虑以下扩展:
src/
├── router/ # 路由管理(H5需要)
├── directives/ # 自定义指令
├── filters/ # 全局过滤器
├── types/ # TypeScript类型定义
├── locales/ # 国际化
│ ├── zh-CN.js
│ └── en-US.js
└── hooks/ # Composition API 复用
├── useUser.js
└── useRequest.js