微信小程序开发实战:5步完成从零搭建到上线部署
学微信小程序开发,卡在“看文档能懂,一动手就懵”的环节。文档写得规规矩矩,但实际开发中遇到的坑,文档里往往不会告诉你。今天咱们就拿一个真实场景——开发一个带登录、商品列表和购物车的小程序——把整个流程拆开揉碎了讲,包括那些让你抓狂的报错和逻辑混乱。
先说说项目初始化。你肯定在微信开发者工具里点过“新建项目”,但忽略了一个细节:AppID一定要填真实的小程序ID,别用“测试号”。测试号虽然能跑,但云开发、真机调试、支付这些功能全用不了。如果你只是练手,可以用测试号;如果你想发布或者对接后端API,必须用真实ID。我见过有人写了两周代码,最后发现测试号没法调用wx.request,又得重新注册,血亏。
接下来是页面结构设计。很多教程会告诉你用“pages/index/index”这种默认结构,但实际项目里,我建议按功能模块分文件夹。比如:
pages/login/ 放登录页
pages/home/ 放首页商品列表
pages/cart/ 放购物车
pages/profile/ 放个人中心
这样后期维护时,你不用在几十个文件里翻找。每个文件夹里放四个文件(wxml、wxss、js、json),命名统一。比如登录页就是login.wxml、login.wxss、login.js、login.json。千万别图省事把不同页面的代码混在一起,不然改一个bug会牵连一堆。
咱们开始写登录功能。小程序的登录跟网页完全不同,它没有session和cookie,靠的是wx.login() + 后端code2session接口。这里有个关键点:很多新手会直接在前端用wx.getUserInfo获取用户信息,然后传给后端。但2021年之后,微信调整了规则,wx.getUserInfo不能再直接弹窗了,必须用
第一步,调用wx.login()拿到code。
第二步,把code传给后端,后端用code + appid + secret去微信服务器换openid和session_key。
第三步,后端生成自己的token返回给前端,前端存到storage里。
我踩过的坑:code只能用一次,如果你在短时间内多次调用wx.login(),后面的code会失效。所以最好在app.js的onLaunch里只调一次,然后把token存全局。还有,session_key千万别泄漏,它不能传给前端,否则别人能伪造登录。
写代码时,你可能会遇到“errMsg: login:fail”的报错。别慌,这通常是网络问题或者AppID配置错误。检查一下:是不是用了测试号?是不是把appSecret写到了前端代码里?appSecret必须放在后端服务器,绝对不能暴露。我见过有人直接把appSecret写在前端js里,结果被爬虫抓走,账号直接被封。
登录搞定后,咱们做商品列表页。这里要讲一个跟网页开发完全不同的点:小程序没有DOM,不能直接操作元素。你想实现“点击商品加入购物车”,不能用jQuery或者原生JS那种“给某个class加事件监听”的方式。小程序用的是数据驱动:你在data里定义数组,wxml用wx:for循环渲染,点击事件通过bindtap绑定到具体数据项。比如:
wxml代码片段:
注意data-id这个属性,它可以把当前商品id传给事件处理函数。在js里,通过e.currentTarget.dataset.id就能取到。一开始会用e.target,结果取到的是子元素的data,导致bug。记住:用currentTarget,别用target。
再说说购物车的数据结构。如果你直接把商品列表的数据复制一份放到购物车,那更新价格或者库存时会非常麻烦。更好的做法是:购物车只存商品id + 数量,具体信息从商品列表里取。这样商品信息变了,购物车自动同步。代码上,你可以用全局数据(app.globalData)或者缓存(wx.setStorageSync)来存购物车。我习惯用缓存,因为用户关闭小程序再打开,购物车数据还在。
购物车还有一个容易翻车的地方:数量加减时的防抖。用户快速点击“+”按钮,如果连续触发setData,会导致界面卡顿甚至数据错乱。我的解决办法是加一个锁变量:
js代码片段:
let isUpdating = false;
function addCount(e) {
if (isUpdating) return;
isUpdating = true;
// 更新数据...
setTimeout(() => { isUpdating = false; }, 200);
}
200毫秒的间隔足够过滤掉大部分误触,又不影响用户体验。
到了支付环节,这是小程序开发里最坑的部分。以为调起支付只需要wx.requestPayment,但实际上,支付参数必须由后端生成。前端能做的只是:把商品信息和用户token传给后端,后端调用微信支付接口拿到prepay_id,然后返回给前端五个参数(timeStamp、nonceStr、package、signType、paySign)。前端再用这些参数调wx.requestPayment。
注意:package参数的值是“prepay_id=xxx”,不能直接传prepay_id。我见过有人传错格式,支付弹窗死活不出来。还有,签名算法必须跟微信文档一模一样,多一个空格或者换行都会失败。如果你用Node.js后端,推荐用tenpay这个npm包,它封装好了签名逻辑,比自己写靠谱。
最后说说真机调试。模拟器上跑得飞起,一上真机就白屏?最常见的原因是HTTPS证书问题。小程序要求所有请求必须是HTTPS,而且证书必须受信任。如果你用自签名证书,或者证书链不完整,真机就会报“request:fail”。解决方法是:用阿里云或者腾讯云的免费证书,或者直接用云开发环境。另一个坑是不校验合法域名:模拟器里可以勾选“不校验”,但真机不行。你必须在小程序后台的“request合法域名”里添加你的API地址,添加完等几分钟生效。
关于性能优化,有一个不知道的技巧:减少setData的数据量。setData会把整个数据对象序列化后传到渲染层,如果你一次setData一个很大的数组,页面会卡。比如购物车列表,你只修改某个商品的数量,不要setData整个购物车数组,而是用“cartList[0].count”这种路径写法。还有,避免在onPageScroll里频繁setData,如果你要做滚动监听,用IntersectionObserver代替。
扩展一个话题:小程序和Vue/React的区别。如果你有前端基础,学小程序会快很多,但要注意几个不同点:
1. 小程序没有双向绑定,只能用setData触发视图更新。
2. 小程序的生命周期跟Vue不一样,onLoad、onShow、onReady要分清。onLoad只执行一次,onShow每次进入页面都执行。
3. 小程序不支持跨域,但不需要CORS配置,因为它的请求机制就是白名单制。
如果你遇到“页面栈溢出”的报错,那是你用了太多wx.navigateTo,小程序页面栈最多10层。超过之后,用wx.redirectTo或者wx.reLaunch替代。还有一个隐藏问题:wx.navigateTo跳转时,如果目标页面已经存在,不会复用,而是新建一个实例。所以如果你从商品列表跳到详情页,再返回,列表页的滚动位置可能会丢失。解决办法是用getCurrentPages()判断页面栈,或者用自定义事件通知列表页保存状态。
最后分享一个调试神器:vConsole。在真机上,打开调试模式,底部的vConsole按钮可以看到console.log输出,还能查看网络请求和Storage。不知道这个功能,导致在真机上瞎猜bug。开启方法:在开发者工具里勾选“启用调试”,重新编译后扫码,真机上就会出现vConsole。如果还看不到,检查一下是不是微信版本太低。
以上这些,都是我在实际开发中一个一个坑踩过来的。小程序开发不难,但细节特别多。如果你按照这个流程走一遍,至少能避开90%的常见问题。遇到报错别怕,先看错误码,再查文档,最后才去搜社区。很多问题其实文档里都有,只是你没耐心看而已。
