微信小程序是一种不需要下载安装、即用即走的轻量级应用形态,依托微信生态,天然具备社交传播和低成本获客的优势。本文从账号注册、开发环境搭建、项目结构、核心语法、网络请求、登录授权、真机调试到最终的上传审核发布,完整梳理一遍微信小程序的开发流程。
一、准备工作
1. 注册小程序账号
- 打开 微信公众平台,点击「立即注册」,选择「小程序」。
- 填写一个未绑定过公众平台的邮箱,完成邮箱验证。
- 选择主体类型(个人、企业等),按提示填写主体信息。个人主体免费,企业主体需要营业执照。
- 注册完成后登录后台,在「开发 → 开发管理 → 开发设置」中可以查看到小程序唯一的 AppID。
2. 安装微信开发者工具
到 微信开发者工具下载页 下载并安装稳定版。首次启动使用微信扫码登录,新建项目时填入刚才获取的 AppID,即可创建一个空项目。
如果只是体验学习,也可以选择「测试号」,不需要注册 AppID,但部分能力(如微信支付)无法使用。
二、项目结构
一个标准的小程序项目目录如下:
project/
├── pages/ # 页面目录,每个页面一个文件夹
│ ├── index/ # 首页
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ └── logs/
├── utils/ # 工具函数目录
├── app.js # 小程序入口逻辑
├── app.json # 全局配置
├── app.wxss # 全局样式
└── sitemap.json # 搜索索引配置
每个页面由四个同名文件组成,职责各不相同:
| 文件后缀 | 作用 | 是否必需 |
|---|---|---|
.wxml | 页面结构(类似 HTML) | 是 |
.wxss | 页面样式(类似 CSS) | 否 |
.js | 页面逻辑与数据 | 是 |
.json | 页面级配置(导航栏、窗口表现) | 否 |
全局配置 app.json
app.json 是整个小程序的核心配置文件,必须包含 pages 字段:
{
"pages": [
"pages/index/index",
"pages/logs/logs"
],
"window": {
"navigationBarTitleText": "我的小程序",
"navigationBarBackgroundColor": "#ffffff",
"backgroundColor": "#eeeeee"
},
"tabBar": {
"list": [
{
"pagePath": "pages/index/index",
"text": "首页"
},
{
"pagePath": "pages/logs/logs",
"text": "日志"
}
]
}
}
pages:页面路径数组,第一项就是小程序的首页。新建页面时在这里注册后会自动创建对应文件。window:全局窗口表现,包括导航栏标题、颜色、下拉背景色等。tabBar:底部 Tab 栏配置,最少 2 项、最多 5 项。
三、WXML 与 WXSS
1. WXML 模板语法
WXML 通过数据绑定把逻辑层的数据渲染到界面上:
<view class="container">
<text>{{message}}</text>
<text wx:if="{{count > 0}}">共 {{count}} 条记录</text>
<text wx:else>暂无数据</text>
</view>
列表渲染使用 wx:for:
<view wx:for="{{list}}" wx:key="id" class="item">
{{index}} - {{item.name}}
</view>
条件渲染支持 wx:if、wx:elif、wx:else;与条件渲染不同,hidden 只是控制显示隐藏,元素始终会被渲染。
2. WXSS 样式
WXSS 在 CSS 的基础上扩展了两个特性:
- 尺寸单位 rpx:响应式像素,规定屏幕宽度为 750rpx,在不同机型上自动换算,适合做等比布局。
- 样式导入:使用
@import引入其他样式文件,如@import "common.wxss";。
样式优先级遵循就近原则:页面私有样式 page.wxss > 全局样式 app.wxss。
四、页面逻辑与生命周期
1. Page 实例
每个页面的 .js 文件调用 Page() 注册一个页面实例,数据放在 data 中:
Page({
data: {
count: 0
},
onLoad(options) {
// 页面加载,options 为路由参数
},
onShow() {
// 页面显示
},
onPullDownRefresh() {
// 下拉刷新
},
add() {
this.setData({ count: this.data.count + 1 });
}
});
修改data后必须调用this.setData()才能触发视图更新,直接赋值this.data.count = 1不会刷新界面。
2. 生命周期总览
小程序的生命周期分为应用级、页面级和组件级三层:
| 生命周期 | 触发时机 | 典型用途 |
|---|---|---|
onLaunch | 小程序初始化完成 | 获取全局缓存、初始化配置 |
onLoad | 页面加载,一个页面只会调用一次 | 请求数据、读取路由参数 |
onShow | 页面显示 | 每次返回页面时刷新数据 |
onReady | 首次渲染完成 | 操作节点、初始化 canvas |
onHide | 页面隐藏 | 暂停计时器、保存草稿 |
onUnload | 页面卸载 | 清理资源 |
3. 事件绑定
在 WXML 中通过 bindtap、catchtap 等属性绑定事件处理函数:
<button bindtap="onTap" data-id="{{item.id}}">点击</button>
Page({
onTap(e) {
// 自定义数据通过 dataset 传递
const id = e.currentTarget.dataset.id;
console.log('点击了', id);
}
});
bind冒泡绑定:事件会向父节点冒泡。catch阻止冒泡:事件只在当前节点处理。
五、页面路由与导航
常用的页面跳转 API:
| API | 行为 | 说明 |
|---|---|---|
wx.navigateTo | 保留当前页,打开新页面 | 页面栈最多 10 层,可通过 wx.navigateBack 返回 |
wx.redirectTo | 关闭当前页,打开新页面 | 无法返回原页面 |
wx.switchTab | 跳转到 tabBar 页面 | 会关闭所有非 tabBar 页面 |
wx.reLaunch | 关闭所有页面,打开新页面 | 任意页面可用 |
wx.navigateBack | 返回上一层或多层 | 通过 delta 指定层数 |
wx.navigateTo({
url: '/pages/detail/detail?id=123'
});
目标页面在 onLoad(options) 中通过 options.id 接收参数。
六、网络请求
小程序通过 wx.request 发起 HTTPS 请求。生产环境要求域名必须在小程序后台「开发设置 → 服务器域名」中配置白名单,且必须是 HTTPS。
1. 基础用法
wx.request({
url: 'https://api.example.com/list',
method: 'GET',
data: { page: 1 },
success(res) {
if (res.statusCode === 200) {
console.log(res.data);
}
},
fail(err) {
console.error('请求失败', err);
}
});
2. 封装 Promise 版请求
实际项目中通常封装一层,统一处理域名、加载提示和错误码:
const BASE_URL = 'https://api.example.com';
function request(options) {
return new Promise((resolve, reject) => {
wx.showLoading({ title: '加载中' });
wx.request({
url: BASE_URL + options.url,
method: options.method || 'GET',
data: options.data || {},
header: {
'Authorization': wx.getStorageSync('token') || ''
},
success(res) {
if (res.statusCode === 200 && res.data.code === 0) {
resolve(res.data.data);
} else {
reject(res.data);
}
},
fail: reject,
complete() {
wx.hideLoading();
}
});
});
}
module.exports = { request };
页面中使用:
const { request } = require('../../utils/request');
Page({
data: { list: [] },
async onLoad() {
try {
const list = await request({ url: '/list' });
this.setData({ list });
} catch (err) {
wx.showToast({ title: '加载失败', icon: 'none' });
}
}
});
七、登录与用户授权
1. 登录流程
小程序登录采用「临时凭证 code 换会话」的模式,整体流程如下:
前端调用 wx.login():
wx.login({
success(res) {
if (res.code) {
// 将 code 发送给开发者服务器换取登录态
wx.request({
url: 'https://api.example.com/login',
method: 'POST',
data: { code: res.code }
});
}
}
});
服务端拿到 code 后,请求微信接口换取 openid 和 session_key:
GET https://api.weixin.qq.com/sns/jscode2session
?appid=APPID
&secret=SECRET
&js_code=CODE
&grant_type=authorization_code
session_key 是对用户数据进行加密签名的密钥,只能保存在服务端,绝不能下发到前端。
2. 获取用户头像昵称
新版本基础库已回收 wx.getUserProfile,现在推荐的方式是「头像昵称填写能力」:
<button open-type="chooseAvatar" bindchooseavatar="onChooseAvatar">
选择头像
</button>
<input type="nickname" placeholder="请输入昵称" bindinput="onInputNickname">
用户选择头像后在回调中拿到临时文件路径,上传到服务器保存:
Page({
onChooseAvatar(e) {
const avatarUrl = e.detail.avatarUrl;
wx.uploadFile({
url: 'https://api.example.com/upload',
filePath: avatarUrl,
name: 'file'
});
},
onInputNickname(e) {
this.setData({ nickname: e.detail.value });
}
});
3. 获取手机号
手机号获取属于敏感能力,仅认证的企业主体可用:
<button open-type="getPhoneNumber" bindgetphonenumber="onGetPhone">
获取手机号
</button>
回调中拿到加密的 code,提交给服务端调用微信的手机号解密接口即可得到明文手机号。
八、本地存储与状态共享
1. 本地缓存
wx.setStorageSync / wx.getStorageSync 提供同步的本地存储能力,单个 key 上限 1MB,总上限 10MB:
wx.setStorageSync('token', 'abc123');
const token = wx.getStorageSync('token');
wx.removeStorageSync('token');
2. 全局数据
跨页面共享少量全局状态,可以挂在 App 实例上:
// app.js
App({
globalData: {
userInfo: null
}
});
// 页面中
const app = getApp();
app.globalData.userInfo = userInfo;
如果页面间需要传递的数据量较大,更推荐通过路由参数或后端接口传递,而不是依赖 globalData。
九、常用内置组件
| 组件 | 用途 |
|---|---|
view | 通用容器,类似 div |
text | 文本,支持 selectable 长按选择 |
image | 图片,支持多种裁剪模式 mode |
scroll-view | 可滚动区域 |
swiper | 轮播图 |
navigator | 页面链接,类似 a 标签 |
button | 按钮,可配合 open-type 使用开放能力 |
input | 输入框 |
form | 表单容器 |
图片组件常见用法:
<image src="{{imgUrl}}" mode="aspectFill" lazy-load binderror="onImgError">
十、真机调试与预览
微信开发者工具提供三种运行方式:
- 模拟器:在工具内直接预览,适合快速开发调试,但与真机存在表现差异。
- 预览:点击工具栏「预览」生成二维码,手机扫码体验,仅自己可用,二维码 30 分钟有效。
- 真机调试:点击「真机调试」,手机端的运行日志、断点调试会实时回传到工具面板,排查真机问题必备。
开发期间建议在工具「详情 → 本地设置」中勾选「不校验合法域名」,方便调试本地接口;上线前务必关闭并配置好正式域名。
十一、发布上线
1. 上传代码
开发完成后点击工具栏「上传」,填写版本号和备注,代码会上传到微信服务器,成为「开发版本」。
2. 提交审核
登录微信公众平台 →「版本管理」,把开发版本「提交审核」。审核一般需要填写每个页面的功能说明,通常 1~3 个工作日出结果,可在「审核设置」中配置加急审核。
3. 发布与回滚
- 审核通过后,在版本管理页点击「发布」,用户即可搜索访问。
- 如果线上版本出现问题,可以一键「版本回退」,回退到上一个线上版本(每个版本仅可回退一次)。
- 建议使用「分阶段发布」,先灰度 5%~20% 的用户,观察无异常后再全量。
十二、常见问题与优化建议
- setData 频繁调用导致卡顿:合并多次 setData 为一次;长列表只更新变化的字段,避免整体替换数组。
- 图片加载慢:使用 CDN,配合
lazy-load懒加载,列表缩略图请求小尺寸规格。 - 包体积超限:主包上限 2MB,使用分包加载(
subpackages)拆分页面,静态资源放到 CDN。 - 白屏兜底:接口失败时给出明确的错误提示和重试按钮,避免空白页。
- 安全:不要把 AppSecret、session_key 等敏感信息放在前端代码里。
总结
小程序开发的核心流程可以归纳为:注册账号拿 AppID → 开发者工具建项目 → 理解四文件结构与 app.json 配置 → 用 WXML/WXSS 搭建界面 → 在 Page 生命周期里组织逻辑 → wx.request 对接后端 → 完成登录授权 → 真机调试 → 上传、审核、发布。掌握这条主线之后,再去学习自定义组件、云开发、分包等进阶能力,会顺畅很多。