小程序工程模板设计
# 一、工程目标(先定设计原则)
这套模板的目标是:
- ✅ 页面薄、逻辑集中
- ✅ 可测试、可扩展
- ✅ 避免 setData 性能坑
- ✅ 符合微信审核 & 规范
- ✅ 不依赖重型框架(原生 + 轻封装)
适合:原生小程序 / Taro / uni-app 思维都能套
# 二、推荐目录结构(核心)
miniprogram/
├─ app.js
├─ app.json
├─ app.wxss
├─ pages/ # 页面(只放 Page 壳)
│ ├─ home/
│ │ ├─ index.js
│ │ ├─ index.wxml
│ │ ├─ index.wxss
│ │ └─ index.logic.js # 页面业务逻辑
│ └─ detail/
│
├─ components/ # 通用组件
│ ├─ Base/
│ │ ├─ Button/
│ │ ├─ Modal/
│ └─ Business/ # 业务组件
│ └─ ProductCard/
│
├─ services/ # 所有接口层
│ ├─ request.js # 请求封装
│ ├─ auth.js # 登录 / token
│ ├─ user.api.js
│ └─ order.api.js
│
├─ store/ # 全局状态
│ ├─ index.js
│ └─ user.store.js
│
├─ utils/ # 工具函数
│ ├─ logger.js
│ ├─ debounce.js
│ ├─ validate.js
│ └─ env.js
│
├─ config/ # 配置
│ ├─ index.js
│ ├─ api.config.js
│ └─ permission.config.js
│
├─ constants/ # 常量
│ ├─ error-code.js
│ └─ storage-key.js
│
├─ styles/ # 全局样式
│ ├─ variables.wxss
│ └─ mixin.wxss
│
└─ subpackages/ # 分包
└─ profile/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# 三、页面“瘦身”模式(非常重要)
# ❌ 错误做法
Page({
data: {},
onLoad() {
wx.request(...)
},
onTap() {
// 一堆业务逻辑
}
})
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# ✅ 正确做法:Page + Logic 分离
# pages/home/index.js
import logic from './index.logic'
Page({
...logic
})
1
2
3
4
5
2
3
4
5
# pages/home/index.logic.js
import { getHomeData } from '../../services/home.api'
export default {
data: {
list: []
},
async onLoad() {
const data = await getHomeData()
this.setData({ list: data })
},
onItemTap(e) {
const id = e.currentTarget.dataset.id
wx.navigateTo({ url: `/pages/detail/index?id=${id}` })
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
👉 好处:
- 页面只是「壳」
- 逻辑可测试
- 后期可迁移到 Taro / React
# 四、请求层设计(最关键)
# 1️⃣ request 封装
# services/request.js
import { getToken } from './auth'
const BASE_URL = 'https://api.xxx.com'
export function request(options) {
return new Promise((resolve, reject) => {
wx.request({
url: BASE_URL + options.url,
method: options.method || 'GET',
data: options.data || {},
header: {
Authorization: getToken()
},
success(res) {
if (res.statusCode === 200) {
resolve(res.data)
} else {
reject(res)
}
},
fail(err) {
reject(err)
}
})
})
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 2️⃣ API 分模块
# services/user.api.js
import { request } from './request'
export function getUserInfo() {
return request({
url: '/user/info'
})
}
1
2
3
4
5
6
7
2
3
4
5
6
7
👉 禁止在 Page 里写 wx.request
# 五、全局状态管理(轻量)
# store/index.js
const store = {
user: null,
setUser(user) {
this.user = user
}
}
export default store
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 使用
import store from '../../store'
store.setUser(res)
1
2
3
2
3
👉 小程序不适合 Redux 重方案 👉 “能不用全局就不用”
# 六、setData 性能规范(必须写进团队规范)
# ❌ 禁止
this.setData({ bigList })
this.setData({ count })
1
2
2
# ✅ 推荐
this.setData({
'bigList[3].title': 'xxx'
})
1
2
3
2
3
# 约定
- setData ≤ 1 次 / 事件
- 大对象拆字段
- 列表分页加载
# 七、组件设计规范
# 组件结构
ProductCard/
├─ index.js
├─ index.wxml
├─ index.wxss
└─ index.json
1
2
3
4
5
2
3
4
5
# 组件通信
- 父 → 子:properties
- 子 → 父:triggerEvent
- ❌ 不直接操作父 data
# 八、配置 & 环境隔离
# config/env.js
export const ENV = 'prod'
1
# config/api.config.js
export const API_HOST = {
dev: 'https://dev.api.com',
prod: 'https://api.com'
}
1
2
3
4
2
3
4
# 九、分包设计(上线前必做)
{
"subpackages": [
{
"root": "subpackages/profile",
"pages": ["index"]
}
]
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
👉 主包 ≤ 2MB 👉 非首屏页面全进分包
# 十、你可以直接复用的 Checklist
- ✅ 页面 + logic 分离
- ✅ API 层集中
- ✅ 禁止业务代码进 Page
- ✅ 分包
- ✅ setData 规范
- ✅ 权限延迟申请
上次更新: 2026/01/09, 03:42:28