微信小程序开发学习:掌握5个核心模块与3个实战项目,快速提升项目交付能力
刚接触微信小程序开发时,容易陷入“看文档都会,一动手就废”的困境。这往往是因为文档只告诉你“这个API怎么用”,却没告诉你“真实项目里为什么要这么用”。下面我会把学习路径拆解成几个关键阶段,用实际踩坑经验帮你绕过那些隐藏的坑。
一、先别急着写代码,把“双线程模型”刻进脑子里
这是小程序最特别的地方,也是新手最容易懵的地方。传统网页是单线程,DOM操作和JS跑在同一个线程里。但小程序分成了渲染层(WebView)和逻辑层(JSCore)。你写的setData本质是在跨线程传数据——通过Native层把JSON字符串从逻辑层拷贝到渲染层。
实操坑点:以为频繁setData和操作DOM一样没成本,结果页面卡成PPT。比如一个列表页,有人把每条数据的每个字段都单独setData一次。正确的做法是:合并数据,一次传一个大的JSON对象过去。再比如,setData的数据大小限制是1MB,传大图base64会直接崩溃。
没有DOM树、没有BOM、不能操作节点。你没办法document.getElementById,所有界面的变化都得靠数据驱动。举个例子:你想让一个按钮在点击后变红,网页里可以直接element.style.color='red',小程序里必须在data里定义一个isRed:false,点击时setData({isRed:true}),然后在WXML里写<button style="color:{{isRed?'red':'black'}}">。
对比一下:这种模式像React的state,但更严格。如果你用过Vue,会觉得setData有点像this.$set,但注意它不支持计算属性。想实现类似效果?要么在setData前自己算好,要么用wxs(但wxs不能调API,只能做纯计算)。
用wx.navigateTo跳转,结果返回时发现前一页的数据变了——因为navigateTo会保留当前页,但不会重新触发onLoad。这时候如果你在onLoad里请求了数据,返回时数据不会刷新。
解决方案:把数据请求放在onShow里。但要注意,onShow在页面切到后台再回来时也会触发,所以得加个判断:如果是首次加载才请求,或者用getCurrentPages()拿到当前页面栈深度来做逻辑区分。
再比如,wx.redirectTo会关掉当前页,wx.reLaunch会关掉所有页。如果你在支付成功后想跳回首页,用wx.switchTab(只针对tabBar页面)或者wx.reLaunch。
很多新手会把所有逻辑塞进一个页面文件里,一个.js文件上千行。小程序支持自定义组件,但它的组件和Vue/React的组件有个大区别:组件间通信很麻烦。父传子用properties,子传父用triggerEvent,兄弟组件之间?要么通过父级中转,要么用全局数据(app.globalData或getApp())。
举例:一个购物车页面,商品列表是一个组件,底部结算栏是另一个组件。用户点击商品组件里的“+”按钮,结算栏要更新总价。你可以在商品组件里triggerEvent('add', {price: item.price}),父页面监听这个事件,然后setData更新总价,再通过properties传给结算组件。但如果你有十几个这样的交互,代码会变得很散。这时候不如用mobx-miniprogram或者westore这类状态管理库——但注意,小程序官方没有Vuex那样的标准方案,第三方库要自己评估兼容性。
云开发确实省了后端,但把它当“不用写后端的数据库”来用。直接在前端db.collection('orders').where({user:openid}).get(),结果发现权限控制一塌糊涂。云开发的数据库权限是基于用户身份的,你必须在云函数里写查询,而不是前端直接调。
实操步骤:
1. 在云函数里用cloud.database().collection('orders').where({_openid: cloud.getWXContext().OPENID}).get()。
2. 前端调用这个云函数,而不是直接查数据库。
3. 数据库权限设置为“仅创建者可读写”,这样别人没法通过控制台直接改你的数据。
另外,云函数冷启动问题很烦人。第一次调用可能要等2-3秒。解决方案是:定时触发器每隔几分钟调一次云函数,让它保持热状态,或者用云函数常驻内存(但这是付费功能)。
六、性能优化:别等用户骂你卡才动手小程序包大小限制是2MB(主包)+2MB(分包),但光一个echarts的min.js就800KB。这时候要用分包加载:把不常用的页面(比如设置页、关于我们)放到分包里,用户访问时才下载。注意,分包不能互相引用,所以公共组件要放在主包。
图片懒加载是个老话题,但小程序里有个坑:image组件的lazy-load属性只对wx:if或hidden控制的图片有效。如果你用wx:for渲染列表,图片会全部加载。正确做法是:用IntersectionObserver(小程序版)监听图片是否进入可视区域,再动态设置src。
还有一个容易被忽略的点:事件绑定不要传参。比如<view bindtap="handleClick" data-id="{{item.id}}">,在handleClick里通过e.currentTarget.dataset.id获取参数。图省事写成bindtap="handleClick({{item.id}})",这会导致每次渲染都生成一个新函数,性能暴跌。
很多新手遇到bug就疯狂打console.log,其实小程序开发者工具里有个“AppData”面板,可以看到当前页面所有data的实时值,还能直接修改。比如你怀疑某个字段没更新,点开AppData看一眼就知道了,比打log快十倍。
网络请求的调试用“NetWork”面板,但注意它只显示wx.request的请求,不显示云函数调用。云函数的调试要在云开发控制台的“日志”里看,或者用console.log在云函数里打日志。
还有一个隐藏功能:wxml面板的“Wxml”标签可以查看渲染层最终生成的节点树,比用wx.createSelectorQuery查节点直观得多。
以为代码能跑就提交审核,结果被拒。下面这几条是审核常踩的雷:
- 用户隐私协议:必须弹窗让用户同意,不能默认勾选。而且协议内容要包含“收集了什么信息、怎么用、怎么删除”。
- 虚拟支付:小程序里不能卖虚拟商品(比如会员、课程),除非你是苹果的“非续期订阅”类型。安卓端可以用微信支付,但iOS端只能用苹果内购,否则审核不通过。
- 类目资质:如果你的小程序涉及社交、医疗、金融等类目,需要提供对应的资质文件(比如ICP证、医疗执业许可证)。随便选个“工具”类目,结果上线后被人举报下架。
- 性能测试:用开发者工具的“Audits”面板跑一次性能检测,分数低于80分可能会被警告。常见扣分项是:setData频率过高、图片太大、未使用分包。
学习小程序开发,最忌讳的是“看完文档就觉得自己会了”。真正能让你成长的,是动手写一个完整的小项目——比如一个带登录、列表、详情、购物车的二手交易平台。在写的过程中,你会遇到数据同步、页面栈管理、组件通信、云函数权限、分包加载、审核被拒……把这些坑都踩一遍,你才算真的入了门。

