《uni-app跨平台开发完全指南》- 02 - 项目结构与配置文件详解
项目结构与配置文件
掌握uni-app项目结构就像学开车前先熟悉车内布局,看似繁琐却能让你在开发路上游刃有余。本文用大量图表和实战案例,帮你彻底搞懂uni-app项目的"五脏六腑"。
一、初识uni-app项目结构
1.1 项目结构图
当你创建第一个uni-app项目时,看到的目录结构可能是这样的:
my-uni-app/
├── pages/ # 页面文件目录
│ ├── index/
│ │ ├── index.vue # 首页
│ │ └── components/ # 页面私有组件
│ └── detail/
│ └── detail.vue # 详情页
├── static/ # 静态资源目录
│ ├── images/
│ │ ├── logo.png
│ │ └── banners/
│ └── icons/
├── components/ # 全局组件目录
│ ├── base/ # 基础组件
│ └── business/ # 业务组件
├── uni_modules/ # 插件市场模块
├── wxcomponents/ # 微信小程序原生组件
├── App.vue # 应用配置和全局样式
├── main.js # 应用入口文件
├── manifest.json # 应用配置文件
├── pages.json # 页面路由和样式配置
└── uni.scss # 全局样式变量
项目结构关系图:
┌─────────────────────────────────────────────────────────────┐
│ uni-app项目结构关系图 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ manifest │ │ pages.json│ │ App.vue │ │
│ │ .json │ │ │ │ │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ ┌──────┴──────────────────┴──────────────────┴──────┐ │
│ │ 应用配置层 (Configuration) │ │
│ └──────────────────────────┬─────────────────────────┘ │
│ │ │
│ ┌──────────────────────────┼─────────────────────────┐ │
│ │ 框架层 (Framework) │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ main.js │ │ uni.scss │ │ pages/ │ │ │
│ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │
│ └─────────┼────────────────┼────────────────┼────────┘ │
│ │ │ │ │
│ ┌─────────┴────────────────┴────────────────┴────────┐ │
│ │ 业务层 (Business) │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ components/ │ │ static/ │ │uni_modules/ │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
1.2 目录职责
如果把目录结构比作一家公司,那么每个目录的作用如下:
pages/- 各个部门办公室(每个页面都是独立部门)static/- 公司仓库(存放不会变动的资产)components/- 标准化工作台(可复用的工具和模板)uni_modules/- 外包服务团队(第三方功能模块)App.vue- 总经理办公室(全局决策和管理)main.js- 公司大门(所有人进入公司的入口)manifest.json- 公司营业执照(应用身份证明)pages.json- 公司组织架构图(页面关系和样式规范)
1.3 项目目录结构设计
实战项目中,推荐的目录结构如下:
src/
├── api/ # API接口层
│ ├── index.js # 请求拦截器和全局配置
│ ├── user.js # 用户相关接口
│ ├── product.js # 商品相关接口
│ └── order.js # 订单相关接口
├── common/ # 公共资源
│ ├── css/ # 公共样式
│ │ ├── reset.scss # 样式重置
│ │ ├── variables.scss # 样式变量
│ │ └── mixins.scss # 样式混合
│ ├── js/ # 工具函数
│ │ ├── utils.js # 通用工具
│ │ ├── validate.js # 表单验证
│ │ └── constants.js # 常量定义
│ └── filters/ # 全局过滤器
├── components/ # 组件库
│ ├── base/ # 基础组件
│ │ ├── button/ # 按钮组件
│ │ ├── input/ # 输入框组件
│ │ └── modal/ # 弹窗组件
│ └── business/ # 业务组件
│ ├── user-card/ # 用户卡片
│ ├── product-list/# 商品列表
│ └── order-item/ # 订单项
├── pages/ # 页面目录
│ ├── home/ # 首页模块
│ │ ├── home.vue # 首页
│ │ └── components/ # 首页专用组件
│ ├── user/ # 用户模块
│ │ ├── login/ # 登录页
│ │ ├── profile/ # 个人资料
│ │ └── settings/ # 设置页
│ └── product/ # 商品模块
│ ├── list/ # 商品列表
│ ├── detail/ # 商品详情
│ └── search/ # 商品搜索
├── store/ # 状态管理(Vuex)
│ ├── index.js # store入口文件
│ ├── modules/ # 模块化store
│ │ ├── user.js # 用户状态
│ │ ├── product.js # 商品状态
│ │ └── cart.js # 购物车状态
│ └── types.js # 类型常量
├── utils/ # 工具函数
│ ├── request.js # 网络请求封装
│ ├── storage.js # 缓存管理
│ ├── auth.js # 权限管理
│ └── router.js # 路由工具
└── static/ # 静态资源├── images/ │ ├── common/ # 公共图片│ ├── icons/ # 图标│ └── banners/ # 广告图├── fonts/ # 字体文件└── json/ # 静态数据
目录结构设计原则:
┌─────────────────────────────────────────────────────────────┐
│ 目录设计原则 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 单一职责原则 高内聚低耦合 易于维护扩展 │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ 每个目录只 │ │ 相关功能放 │ │ 新功能容易 │ │
│ │ 做一件事 │ │ 在同一目录 │ │ 添加和修改 │ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ │
│ 分层清晰明确 按功能模块化 团队协作友好 │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ API/组件/ │ │ 用户/商品/ │ │ 不同开发者 │ │
│ │ 页面分离 │ │ 订单分模块 │ │ 负责不同模块│ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
二、pages.json 深度解析
2.1 pages.json 的作用机制
pages.json 是uni-app的路由中枢和样式调度中心,它决定了:
- 页面路由关系 - 哪个路径对应哪个页面
- 全局样式规范 - 导航栏、背景色等统一设置
- 页面个性配置 - 每个页面的特殊样式需求
- 底部导航管理 - TabBar的配置和交互
pages.json 配置流程图:
2.2 完整配置实例分析
下面以一个电商应用为例,完整 pages.json 配置如下:
{// ==================== 全局样式配置 ===================="globalStyle": {// 导航栏相关"navigationBarTextStyle": "white", // 标题文字颜色"navigationBarTitleText": "智能商城", // 默认标题"navigationBarBackgroundColor": "#FF6B35", // 导航栏背景色"backgroundColor": "#F8F8F8", // 窗口背景色// 下拉刷新"enablePullDownRefresh": false, // 默认关闭下拉刷新"backgroundTextStyle": "dark", // 下拉loading样式"onReachBottomDistance": 50, // 上拉触底距离// 页面动画"animationType": "pop-in", // 页面切换动画"animationDuration": 300, // 动画时长// H5配置"h5": {"titleNView": { // H5标题栏"titleText": "智能商城","backgroundColor": "#FF6B35","titleColor": "#FFFFFF"}},// App配置"app-plus": {"background": "#F8F8F8", // 应用背景色"bounce": "vertical" // 回弹效果}},// ==================== 页面路由配置 ===================="pages": [// 首页必须放在第一个位置!{"path": "pages/index/index","style": {"navigationBarTitleText": "智能商城首页","enablePullDownRefresh": true, // 首页开启下拉刷新"backgroundTextStyle": "dark","navigationBarBackgroundColor": "#FF6B35",// 首页特殊配置"app-plus": {"bounce": "vertical" // iOS回弹效果}}},// 分类页面{"path": "pages/category/category","style": {"navigationBarTitleText": "商品分类","enablePullDownRefresh": false,"navigationBarBackgroundColor": "#4CD964" // 绿色主题}},// 购物车页面{"path": "pages/cart/cart","style": {"navigationBarTitleText": "购物车","navigationBarBackgroundColor": "#FF9500" // 橙色主题}},// 个人中心{"path": "pages/user/user", "style": {"navigationBarTitleText": "个人中心","navigationBarBackgroundColor": "#5856D6" // 紫色主题}},// 商品详情页{"path": "pages/product/detail","style": {"navigationBarTitleText": "商品详情","navigationBarBackgroundColor": "#FF6B35",// 详情页禁用下拉刷新"enablePullDownRefresh": false,// 自定义配置"app-plus": {"bounce": "none" // 禁用回弹}}}],// ==================== 底部TabBar配置 ===================="tabBar": {// 基础样式"color": "#7F7F7F", // 默认颜色"selectedColor": "#FF6B35", // 选中颜色"backgroundColor": "#FFFFFF", // 背景色"borderStyle": "black", // 边框颜色"blurEffect": "none", // 毛玻璃效果(iOS)// 图标和文字样式"iconWidth": "24px", // 图标宽度"spacing": "3px", // 图标与文字间距"height": "50px", // TabBar高度"fontSize": "10px", // 文字大小// Tab项列表"list": [{"pagePath": "pages/index/index", // 页面路径"iconPath": "static/tabbar/home.png", // 默认图标"selectedIconPath": "static/tabbar/home-active.png", // 选中图标"text": "首页", // 文字// 角标配置"badge": "12", // 角标数字"badgeStyle": "background-color: #FF3B30; color: #FFFFFF;" // 角标样式},{"pagePath": "pages/category/category","iconPath": "static/tabbar/category.png","selectedIconPath": "static/tabbar/category-active.png", "text": "分类","badge": "NEW", // 文字角标"badgeStyle": "background-color: #4CD964; color: #FFFFFF;"},{"pagePath": "pages/cart/cart","iconPath": "static/tabbar/cart.png","selectedIconPath": "static/tabbar/cart-active.png","text": "购物车","badge": "3", // 购物车商品数量"badgeStyle": "background-color: #FF9500; color: #FFFFFF;"},{"pagePath": "pages/user/user","iconPath": "static/tabbar/user.png","selectedIconPath": "static/tabbar/user-active.png","text": "我的"}],// 中间凸起按钮"midButton": {"width": "50px", // 按钮宽度"height": "50px", // 按钮高度"text": "发布", // 按钮文字"iconPath": "static/tabbar/add.png", // 按钮图标"iconWidth": "25px", // 图标宽度"backgroundImage": "" // 背景图片}},// ==================== 组件自动引入配置 ===================="easycom": {"autoscan": true, // 开启自动扫描"custom": {// 自定义组件匹配规则"^uni-(.*)": "@/components/uni-$1.vue", // uni-开头组件"^my-(.*)": "@/components/my-$1.vue", // my-开头组件"^base-(.*)": "@/components/base/$1.vue", // base-开头基础组件"^biz-(.*)": "@/components/business/$1.vue" // biz-开头业务组件}},// ==================== 条件编译配置 ===================="condition": {"current": 0, // 当前启动模式"list": [{"name": "商品详情测试", // 模式名称"path": "pages/product/detail", // 启动页面"query": "id=1001&type=test" // 启动参数},{"name": "订单列表测试","path": "pages/order/list","query": "status=1"}]},// ==================== 平台差异化配置 ====================// H5平台配置"h5": {"publicPath": "/", // 静态资源路径"router": {"mode": "hash", // 路由模式: hash/history"base": "./" // 路由基路径},"title": "智能商城H5版", // 页面标题"template": "template.h5.html", // 自定义模板"optimization": {"treeShaking": {"enable": true // 开启摇树优化}}},// 微信小程序专属配置"mp-weixin": {"appid": "wx1234567890abcdef", // 小程序AppID"setting": {"urlCheck": false, // 关闭域名校验"es6": true, // 启用ES6转ES5"enhance": true, // 增强编译"postcss": true, // 样式自动补全"minified": true // 代码压缩},"usingComponents": true, // 使用自定义组件"permission": 