从零到一:7步实战掌握微信小程序核心开发技能
微信小程序的开发,一开始会被它的各种文件类型和配置项吓到。但如果你拆开来看,它其实就像搭积木——wxml负责结构,wxss负责样式,js负责逻辑,json负责配置。今天我们就从零开始,用最直观的方式,把这些积木怎么拼、怎么改、怎么调,一步步说清楚。
从零搭建你的第一个页面
打开微信开发者工具,新建一个小程序项目。你会看到一个默认的“Hello World”页面。别急着删代码,先看看它的骨架:app.json这个文件是整个小程序的“总调度室”。它里面有个pages数组,里面写着的路径,就是小程序里所有页面的“门牌号”。
比如你看到"pages/index/index",这意味着小程序启动时,会自动寻找pages/index文件夹下的index.wxml、index.wxss、index.js和index.json四个文件。如果你想让首页变成另一个页面,比如pages/home/home,那就把pages数组里的第一项改成它,同时保证pages/home/文件夹里有这四个文件。
一个小技巧:手动在pages数组里添加一行路径,比如"pages/about/about",保存后,开发者工具会自动帮你生成对应的文件夹和四个文件。这比手动新建文件夹、再一个个创建文件要快得多。
wxml:用标签“画”出页面
wxml长得像HTML,但很多标签是微信自己封装的。比如<view>相当于<div>,<text>相当于<span>。但有个关键区别:小程序里没有DOM操作,你不能用document.getElementById去改内容。所有数据都得通过js里的data对象来驱动。
举个例子,你想在页面上显示一个用户名。在wxml里写:<text>{{userName}}</text>。然后在同目录的js文件里,找到data对象,写上userName: '张三'。页面就会显示“张三”。如果你想让点击按钮后名字变成“李四”,那就写一个函数,用this.setData({userName: '李四'})来更新。记住:setData是唯一能修改页面显示的方法,直接改this.data.userName是不会生效的。
很多新手会问:为什么我改了data,页面没变?十有八九是忘了用setData,或者setData里写错了属性名。
wxss:让页面“穿衣服”
wxss基本就是CSS,但有一些扩展。比如单位rpx,它根据屏幕宽度自动适配。设计稿如果是750px宽,你就把设计稿上的尺寸直接写rpx值:设计稿上100px的按钮,写width: 100rpx,在不同手机上会自动缩放。这比用百分比或者vw要省心得多。
另一个常见坑是样式隔离。小程序里,每个页面的wxss默认只作用于当前页面。如果你在app.wxss里写了一个.red{color:red},所有页面都能用。但如果你在pages/index/index.wxss里写同样的类名,它不会影响到其他页面。这避免了样式冲突,但也意味着你需要规划好哪些样式是全局的。
实战中,喜欢把常用的按钮、卡片样式写在app.wxss里,然后每个页面只写自己特有的样式。这样既减少了重复代码,又不会互相干扰。
js:让页面“活”起来
小程序js和浏览器里的js最大的不同是:没有window对象,也没有document。你不能用window.innerWidth,得用wx.getSystemInfoSync().windowWidth。也不能用alert,得用wx.showToast。
生命周期函数是另一个重点。比如onLoad在页面加载时触发,适合做数据初始化;onShow在页面每次显示时触发,适合做刷新操作。举一个实际场景:你的页面从列表页跳转到详情页,修改了数据后返回,列表页需要刷新。如果在onLoad里写加载数据,返回时不会重新触发,因为页面没有被销毁。这时候就该把刷新逻辑放在onShow里。
还有一个容易被忽略的是页面栈。用wx.navigateTo跳转时,页面会一层层压栈。如果跳了太多层,返回时可能会卡顿。一般建议用wx.redirectTo或wx.reLaunch来避免栈过深。如果你需要传参,可以在跳转路径后加查询字符串,比如wx.navigateTo({url:'/pages/detail/detail?id=123'}),然后在目标页面的onLoad里通过options.id拿到这个值。
json:控制页面的“开关”
每个页面都有自己的json文件,用来配置该页面的导航栏、窗口样式等。比如你想让某个页面的导航栏标题变成“我的收藏”,就在它的json里写:{"navigationBarTitleText": "我的收藏"}。这个配置只影响当前页面,不会干扰全局。
还有一个常用配置是enablePullDownRefresh,设为true后,用户下拉页面就会触发onPullDownRefresh事件。但要注意:这个配置默认只在全局app.json里生效,如果你想单独给某个页面开启下拉刷新,必须在该页面的json里也写上这个配置,否则不会生效。
会在这里踩坑:明明在app.json里写了"enablePullDownRefresh": true,但某个页面就是不能下拉。检查一下,八成是那个页面的json里没有写这个配置,或者写成了false。
组件化:复用代码的利器
如果你发现多个页面里都有相同的“卡片”结构——比如商品卡片、用户头像卡片——那就该把它抽成组件。组件有自己的wxml、wxss、js和json,和页面几乎一样,但它的js里用的是Component函数,而不是Page。
创建一个组件,比如components/card/card。在它的js里定义properties,用来接收外部传入的数据。比如properties: { title: String, price: Number }。然后在wxml里直接用{{title}}和{{price}}。在父页面里,通过<card title="商品A" price="99"></card>来使用。
组件还有一个好处:样式隔离更彻底。组件内部的wxss默认不会影响父页面,父页面的样式也不会渗透进组件。如果你想让父页面控制组件内某个元素的颜色,可以通过externalClasses来实现,但一般情况下,保持隔离反而更安全。
调试:那些让你抓狂的问题
开发中最常见的错误是路径写错。比如在wxml里引用图片,写成src="images/logo.png",但小程序里的路径是相对于当前文件的,如果你在pages/index/index.wxml里写这个路径,它实际会去找pages/index/images/logo.png。正确的做法是写成绝对路径:src="/images/logo.png",这样不管在哪个页面,都会从项目根目录的images文件夹里找。
另一个是数据绑定不更新。如果你在js里用this.data.list.push(newItem),然后this.setData({list: this.data.list}),你会发现页面没变。因为push修改的是原数组,setData检测到新旧数组是同一个引用,就不更新了。解决办法是const newList = [...this.data.list, newItem]; this.setData({list: newList}),创建新数组再赋值。
还有网络请求问题。小程序里用wx.request发请求,但必须配置request合法域名。开发阶段可以在开发者工具里勾选“不校验合法域名”,但上线前一定要在微信公众平台后台把域名加进白名单。另外,wx.request默认超时时间是60秒,如果你需要更长的等待时间,可以在app.json里设置"networkTimeout": {"request": 10000}(单位毫秒)。
发布前必须检查的几件事
代码写完后,别急着上传。先检查appid是否替换成你自己的。直接复制别人的demo,结果上传时提示appid不合法。然后检查project.config.json里的appid字段,确保和微信公众平台的一致。
接着,在开发者工具里点击“预览”,用手机扫码测试一遍。特别关注:真机上的字体大小、按钮点击区域、图片加载速度。模拟器里看着完美,真机上可能按钮太小点不到,或者字体过大撑破布局。如果发现真机上某个样式不对,可以用wx.getSystemInfoSync()获取设备信息,然后动态调整样式。
最后,上传代码时,版本号要规范。比如v1.0.0,然后在微信公众平台提交审核。审核通常需要1-2个工作日,如果急着上线,可以备注“紧急修复”或者“节假日活动”,有时会加快审核速度。
如果你按照这些步骤走下来,一个小程序从零到上线,基本不会遇到大坑。遇到问题时,先检查路径、再检查setData、最后检查配置项——这三个地方解决了90%的bug。剩下的10%,多在社区里搜一搜,或者看看官方文档的更新日志,往往能找到答案。

