
我一直觉得“如何从零开始写小程序”这个问题真正的难度不在代码而在信息差。你搜到的内容大部分在讲某个具体功能怎么实现却很少有人告诉你在动手写第一行代码之前你需要先在账号类型、技术路线、功能范围这三个问题上做决策。一旦选错后面就是连环坑——代码写完了发现支付开通不了界面做完了发现类目没有营业资质开发到一半发现备案备注不会填又被打回来。我这些年从小程序商城、婚礼邀请函到内部工具类小程序都做过想按一条真实走过的路径把这些前置问题、开发过程中的高频坑、以及上线前的注意事项串起来给还在迷茫的人一条能直接照着走的路。1. 动手写之前先想通三件事路线、技术栈和“最小范围”很多人打开微信开发者工具之前根本不知道自己的目标是什么只看到一个“小程序商城”就觉得别人怎么写我也怎么写。这是新手最大的误区。在注册账号之前先回答三个问题你是打算自己从零开发还是买现成的模板平台你的前端基础在哪个水平第一版上线你至少需要几个页面1.1 根据目的选择正确路线自研、模板还是外包先别急着当程序员先当自己的项目经理。我把目前主流的做法分成三条路适合完全不同的情况路线适用场景优点代价完全自研想长期迭代、有技术团队或自己愿意学代码完全可控、数据归自己、定制空间大开发周期长对新手不友好购买小程序平台快速上线、功能通用、不想养技术几天就能上线便宜定制能力弱核心数据在别人手里后续扩展受限找公司/外包半定制有预算、有明确业务需求按需开发交付质量相对有保障贵沟通成本高后期维护要看合同如果你的目标是“把线下的生意搬到微信里”小程序商城确实是最常见的选择。但你要清楚小程序商城和淘宝这类公域电商逻辑完全不同淘宝靠平台流量小程序商城靠你自己的私域运营比如微信群、公众号、线下扫码。所以小程序商城第一版不需要做成淘宝那样的大而全能把商品展示、在线支付、订单管理跑通就够了。我的建议是想靠小程序赚钱的人第一版别自研想靠小程序积累长期资产、后续不断调功能的人从零自研是值得投入的。最怕的是两种心态一种是觉得写代码很简单一上来就想做复杂商城另一种是花钱买了模板结果连后台都懒得改。1.2 主流技术栈对比原生微信小程序、uni-app还是Taro确定自研之后你需要选技术栈。目前最主流的三个方向原生微信小程序用官方提供的WXML、WXSS、JS来写。优点是官方文档最全、调试最直接、性能最好缺点是只能跑在微信里换到支付宝小程序或抖音小程序要重写。适合只做微信生态、且想深入理解小程序底层机制的人。uni-app基于Vue语法用HBuilderX编辑器开发。编译后可发布到微信小程序、App、H5等平台。如果你未来有App需求或者已经会Vue这个选型很香。但要注意它是“编译到微信小程序”排查底层问题时你还是要理解小程序本身的运行机制。Taro京东开源基于React语法也能一套代码多端发布。适合React技术栈的团队或个人。作为从零起步的小白我给一个反直觉的建议先学原生微信小程序哪怕以后要用uni-app。原因很简单——uni-app的Bug最终都要小程序开发者工具来解释你不懂原生原理看到编译后的报错根本无从下手。而原生逻辑熟练之后再去看uni-app的文档基本是降维打击。1.3 一份真正能落地的MVP功能清单别一上来就做十几个页面。我见过最夸张的新手规划第一版就要做会员积分、分销裂变、直播带货、多商户入驻结果代码写了一万行连支付都没调通。第一版小程序请控制在这个范围首页展示你的核心商品或服务放一个清晰的转化入口列表页分类或筛选功能详情页图文信息、价格、规格选择用户登录区授权手机号或微信身份下单结算流程支付、订单状态个人中心订单查看、联系客服五个以内页面够检验你的产品逻辑是否成立。我见过很多第一版做复杂的项目最后连审核都过不了因为类目或资质根本不匹配。你先用最简单版本跑通全流程拿到用户真实反馈再迭代第二版这才是高效路径。2. 开发环境搭建从注册账号到跑通“Hello小程序”路线定了开始搭环境。这一步的坑非常隐蔽很多人卡在“注册”和“备案”上甚至卡了一周时间。我尽量说清楚。2.1 小程序账号的主体类型与备案意识到微信公众平台注册小程序账号第一步是选主体类型个人、企业、个体工商户、政府等。这里有一个决定后续命运的选择个人主体无法开通微信支付。你只要想做商城、卖东西、收任何钱就必须是企业或个体工商户主体。我看到太多人用个人身份证注册完账号做完了界面才发现开通支付时被驳回。到这一步基本等于重来因为主体类型不能后期随意更改。另外现在小程序上线前都要完成备案。这不是上架之后才想的事而是开发之前就要准备好的资料。企业主体需要营业执照、法人信息个体工商户也需要营业执照。具体流程在小程序后台“设置-基本设置-小程序备案”里填写。备案备注信息怎么填不要写“测试”不要写“个人练习”最好按照实际用途写比如“用于展示公司产品信息并提供在线咨询”“用于餐饮门店扫码点餐和会员管理”类目和备注信息要一致。否则会被审核退回浪费时间。2.2 下载开发者工具拿到AppID创建第一个项目注册完成后到微信官方下载“微信开发者工具”稳定版。安装好后用管理员或项目成员身份的微信扫码登录。创建项目时要填写AppID——这个ID在小程序后台“开发-开发管理-开发设置”里可以找到。新手容易犯的一个错误为了省事选择“测试号”创建项目。测试号确实能让你快速看效果但它无法调用支付、跳转、部分设备能力。我建议直接用自己的AppID哪怕主体资料还在审核中也可以先用测试号跑通代码等AppID下发后再做一次替换。创建项目时的模板选择我建议选“不使用模板”自己建一个空目录然后手动创建四个同名文件js、json、wxml、wxss。这样你能彻底搞懂页面是怎么被组织起来的而不是被模板带着走。2.3 “登录用户不是该小程序的开发者”的排查闭环这是开发群里的高频报错用微信扫码后开发者工具提示“登录用户不是该小程序的开发者”或者后端接口返回“错误: 登录用户不是该小程序的开发者”。完整的排查链路应该是这样先在微信公众平台后台左侧菜单找到“成员管理”把当前微信添加为“项目成员”或“体验成员”。注意你注册的账号是管理员管理员一定可以登录但如果你是被别人拉进去的成员需要管理员在微信里确认邀请。添加完后退出开发者工具重新用微信扫码登录而不是刷新页面。工具经常缓存权限不彻底退出没用。还不行就删掉项目重新导入。进入到项目详情页检查AppID是否真的填写正确是不是复制到了别人的项目ID。这套排查我做过太多次90%的情况是第一步和第三步没做对。权限问题别急着改代码先检查后台配置。3. 第一个业务页面的完整链路结构、生命周期、标题与导航栏环境好了开始写页面。这里我带你完整走一遍“页面是怎么跑起来的”同时把动态设置标题、顶部导航栏高度这两个高频需求一并讲了。3.1 小程序页面文件结构与app.json配置一个原生小程序的页面由四个同名的文件组成index.js逻辑、index.wxml结构、index.wxss样式、index.json页面配置。页面所在目录要注册到app.json的pages数组里。例如{ pages: [ pages/index/index, pages/list/list, pages/detail/detail ] }app.json里还可以配置window、tabBar、networkTimeout等。小程序是全局配置驱动的很多时候你找不到某个页面为何没生效就是因为在错误的层级配了参数。页面自己的json配置会覆盖app.json里的同名配置比如那个页面要单独设置标题或背景色写在页面的json里就够了。首页其实是小程序的“脸面”我建议第一版首页直接使用开发者工具自带的模拟器调试把wxml和wxss写熟再进入真实手机预览。手机预览时注意开启“真机调试”真机上才能看到网络请求和部分组件在不同机型的表现。3.2 onLoad、onShow、onReady的执行顺序决定代码写在哪小程序的页面生命周期是新手最容易懵的地方。我帮你记住一个口诀一个页面第一次打开先走onLoad再走onShow最后走onReady。但如果页面被切到后台再回来只走onShow不再走onLoad。这意味着数据请求写在哪里第一次打开需要的数据写在onLoad里每次进入页面都需要刷新的数据写在onShow里。DOM相关的操作写在哪要等到onReady之后页面真正渲染完成才能操作。你可以用wx.nextTick等待渲染完成。页面间通过参数跳转参数在onLoad的options里拿到。我踩过的一个坑把请求写在onLoad里然后从详情页返回列表页时列表数据没有刷新。原因就是返回时不会重新触发onLoad只能触发onShow。遇到这种情况把刷新逻辑挪到onShow即可。3.3 动态设置标题与顶部导航栏高度适配“小程序动态设置标题”是搜索热词我重点讲。静态标题在页面json里写navigationBarTitleText打开页面就是这个标题简单可靠。动态标题想根据页面内容变化用wx.setNavigationBarTitlewx.setNavigationBarTitle({ title: 订单详情 - 订单号123 });但这里有一个很多人不知道的坑如果页面是tabBar页面也就是在app.json的tabBar配置里注册过的页面调用setNavigationBarTitle会不生效。因为tabBar页面的标题必须在tabBar里统一配置。解决办法要么改用非tab页面要么接受统一标题或者用自定义导航栏完全自己控制渲染内容。顶部导航栏高度适配主要发生在你要做自定义导航栏的时候。设置页面json{ navigationStyle: custom }然后手动计算导航栏高度。获取状态栏高度用wx.getSystemInfoSync().statusBarHeight。导航栏内容区域高度通常是胶囊按钮高度约32px加上上下间距。我常用的公式const systemInfo wx.getSystemInfoSync(); const capsule wx.getMenuButtonBoundingClientRect(); const navBarHeight (capsule.top - systemInfo.statusBarHeight) * 2 capsule.height;拿到高度后顶部占位视图的高度就是statusBarHeight navBarHeight。这个公式在大多数安卓和iOS机型上都能适配但iPhone带安全区域的机型还要配合env(safe-area-inset-top)做兜底。4. 写业务逻辑绕不开的四道坎请求、登录、支付与参数编码页面结构写好后你就要面对小程序真正“有技术含量”的部分网络请求、登录鉴权、支付能力和参数编码。这四个点几乎决定一个项目能不能上线。4.1 wx.request封装和常见的网络错误小程序不能直接使用浏览器的XMLHttpRequest要用wx.request。我建议第一件事就封装一个统一请求函数别想到哪写到哪。function request(url, method, data) { return new Promise((resolve, reject) { wx.request({ url: getApp().globalData.baseUrl url, method: method || GET, data: data || {}, header: { Content-Type: application/json, Authorization: wx.getStorageSync(token) || }, success: (res) { if (res.statusCode 200 res.statusCode 300) { resolve(res.data); } else { handleError(res.statusCode); reject(res); } }, fail: (err) { handleError(err.errMsg); reject(err); } }); }); }常见错误有两个一是域名没有配置到小程序后台的request合法域名里。开发时可以在开发者工具里勾选“不校验合法域名”但真机预览就无法绕过必须去后台“开发管理-服务器域名”里添加域名。二是请求全部走HTTPS。微信小程序不允许明文HTTP请求开发工具里可以临时打开线上必须HTTPS。4.2 GET参数里的等号和中文为什么变成百分号有一个经典问题使用GET参数时参数里边有等号结果被转换成百分号问怎么避免。直接说结论这不是错误而是URL编码的标准行为。URL里不允许出现原始的中文、等号、空格这些字符所以客户端会把它们变成百分号形式的编码。等号变成%3D中文按UTF-8编码成几组百分号字节。这是所有现代网络库的标准处理方式不需要“避免”。服务端收到请求时框架会自动解码。如果你在服务端拿到了百分号说明服务端没有调用解码方法。比如在Node.js里没有用decodeURIComponent解析参数而是直接取了rawQuery字符串。搭配场景再提醒一个要点对参数的每个值使用encodeURIComponent而不是对整个URL编码。举个反面例子如果你把整个URL都encodeURIComponent掉那么和会被全部编码服务端就无法拆分参数了。正确做法const key encodeURIComponent(a123); const url https://api.example.com/getData?key key;这样URL实际发送的是keya%3D123服务端解码后拿到的还是a123。4.3 支付能力到底要怎么开通为什么会被限制搜索里有句话很典型“小程序对应支付能力已被限制”。我见过很多人在开发完成后才发现这个问题。根本原因通常有三类主体不支持。个人主体不能开通微信支付这是硬性规定必须换成企业或个体工商户。后台没开通。在小程序后台左侧菜单“微信支付”入口要完成商户号申请或绑定。支付能力不是自动开放的需要提供营业执照、经营资质等材料审核。类目或风控问题。小程序的类目如果和你实际卖的商品不一致比如你填的是“工具”实际卖食品支付审核会被驳回甚至上线后风控会限制支付能力。还有一个很隐蔽的点如果你要做类似“骑手分账”“多商户入驻”这种模式除了小程序支付还要在微信支付商户平台开通“分账”能力。有些人连分账协议和隐私政策都看不到后台就提示无法注册大概率是主体类型或经营范围不匹配。这种情况没有捷径先把主体资质和经营范围核实清楚再到商户平台发起申请。4.4 wx.login换token时容易踩的地基问题微信小程序登录的标准流程是前端调用wx.login拿到一个code把code发给后端后端拿code到微信接口换取openid和session_key后端自己生成一个自定义登录态token返回给前端前端把token存起来后续请求带上用它识别用户。注意code只能用一次而且有效期很短。有些人把code存起来反复用后端一直报40029 invalid code这就是原因。正确的每次要重新调用wx.login获取新code。另外绝对不要把appid和secret写在小程序前端代码里。secret相当于你后端接口的钥匙一旦暴露别人可以冒充你的服务端。正确做法是secret只保存在后端服务器环境变量里前端拿不到。5. 地图、导出Excel、拖拽排序三个高频需求的标准做法从这一步开始你已经不是小白了开始接触“功能型页面”。我选了三个出现频率特别高的需求接入高德地图、导出Excel表格、长按拖拽滚动。这三个方向都能直接套用到实际业务里。5.1 高德地图在小程序里的接入步骤小程序内接入高德地图一般不是直接在高德官网申请而是用小程序的map组件再配合高德提供的微信小程序SDK来实现定位、POI搜索、路径规划等能力。具体步骤去高德开放平台注册账号创建应用申请一个Key。类型选“微信小程序”。在小程序后台配置服务器域名或下载高德官方的小程序SDK文件到项目里。使用wx.getLocation获取当前坐标。使用SDK的Geocoding和Regeocoding获取详细地址信息。有一个容易踩的坑小程序map组件本质是原生组件层级会盖住普通页面元素。如果你要在页面盖一个自定义弹窗或按钮需要用到cover-view组件。否则你会发现弹窗总是在地图下面出不来。5.2 前端导出Excel的两种可行方案“微信小程序导出excel”这个需求常见于订单数据导出、后台报表场景。方案有两种方案一后端生成Excel文件返回一个下载链接。前端用wx.downloadFile下载再用wx.openDocument打开预览。这是最成熟可靠的方式推荐优先使用。方案二纯前端用SheetJSxlsx库生成Excel的Base64数据再通过wx.getFileSystemManager().writeFile写入本地文件最后用wx.openDocument打开。适合数据量小、不想麻烦后端的情况。但要注意小程序包体积会变大框架库大约几百KB最好用分包或动态加载处理。我在实际项目里更推荐方案一。原因是纯前端导出Excel受限于小程序沙箱环境处理复杂样式、多sheet时会有兼容问题而且处理大数据量时容易内存溢出。5.3 长按拖拽滚动与特殊组件在iOS和鸿蒙上的注意点长按拖拽滚动常见的实现是基于movable-area和movable-view组件。先渲染一个容器然后把每个可拖拽项目封装成movable-view在长按事件触发后动态设置movable-view的偏移量。数据模型上你还要维护每个项目的index拖拽到位后重新排序。这里要注意微信小程序的拖拽排序没有现成的list组件需要自己处理边界判断。一个偷懒但有效的方案是长按开始时震动反馈拖拽过程中不逐帧更新数据而是利用transform做视觉位移松手后再一次性更新数组这样性能会好很多。特殊组件兼容性问题在iOS上最容易出现的是uni-datetime-picker放在scroll-view里选择器弹不出来的Bug。原因是iOS渲染机制对原生组件的层级和滚动容器有特殊处理。如果遇到优先把picker移到滚动容器外层或者使用微信官方picker组件替代。用鸿蒙系统手机测试时视频播放异常的现象也比较常见多半是video组件的真机兼容问题建议降低码率或改用了live-player等组件测试。6. 调试、白屏优化与上线最后一个阶段的实战经验功能写完了不代表能上线。在这个阶段你会遇到很多“开发环境正常真机就抽风”的问题。我挑三个最常见的用实际经验告诉你怎么处理。6.1 用Charles和Wireshark抓包小程序请求开发阶段有个让人头疼的场景后端说“我接口没问题”你看到前端报错但不知道请求到底长什么样。这时候抓包工具就派上用场了。Charles是调试HTTPS请求的主力工具。抓包步骤手机和电脑连同一个Wi-Fi电脑端打开Charles查看本机IP在Help-Local IP Address里。手机Wi-Fi设置里把HTTP代理改为手动服务器填电脑IP端口默认8888。手机首次访问任意网页会弹出证书安装提示安装并信任Charles根证书。然后在Charles里开启SSL Proxying并添加你要抓的域名。这样小程序的所有HTTPS请求就都能在电脑上看到明文内容了。Wireshark则是更底层的网络抓包。它能看到TCP三次握手、TLS握手过程、连接是否被中断。业务调试一般用不上但如果遇到网络时通时不通、上传下载卡住这类问题Wireshark能帮你判断是服务器主动断开还是网络层面丢包。一个重要提示抓包结束后一定要关闭手机代理设置不然手机会上不了网。另外证书只应在自己测试环境安装不要下载来路不明的证书文件。6.2 tab切换白屏闪动的排查思路“小程序底部tab切换页面一瞬间白屏闪动”这个现象特别像格式化故障常见原因和排查方向如下第一页面首次创建时onLoad里做了太多同步任务比如同步读取大量Storage数据、执行复杂计算。每个tab页首次创建都会加载如果加载时间过长切换时就会出现白屏。解决方案把非必要的初始化逻辑放到onReady或setTimeout里延迟执行页面顶部先渲染骨架屏。第二原生组件与普通组件层级冲突。比如首页用了map或canvas切换tab时原生组件被强制重新绘制视觉上就像闪白。这类问题要测试排查单独去掉某个组件看是否消失。第三页面数据在onShow里同步刷新导致切换时先渲染空数据再渲染完整数据。这种“白屏闪动”其实是数据驱动的。优化方案缓存上一次的页面数据在onShow里先显示缓存请求完成后再更新。排查这类问题的核心思路是“二分法”先禁用tabBar改成普通页面跳转看是否还闪再逐一注释页面里的组件和代码块。别一上来就怀疑框架很多问题出在你自己的渲染逻辑上。6.3 备案备注信息怎么填以及上线前哪些问题必须自查备案备注信息是个看似简单但翻车率极高的字段。搜索里问“小程序备案备注信息怎么填”的人特别多。我的建议是直接写清小程序的实际用途并和你选择的类目保持一致。例如你选了“餐饮-餐饮服务”类目备注就写“用于为用户提供餐饮门店信息展示和在线点餐服务”你选了“电商平台”备注就写“用于商家在平台展示商品与用户完成在线交易”。千万别写“个人学习”“空”“无”否则审核人员无法判断你的用途很容易退回。上线前我还建议你自查以下项目隐私保护指引后台要配置“用户隐私保护指引”特别是你收集了手机号、位置、头像昵称等信息必须明确告知用户用途。用户协议商城类小程序一定要有用户协议页面说明注册、交易、售后和争议处理规则。类目资质上传的营业执照经营范围要覆盖你实际售卖的商品和服务。体验版测试把代码上传为体验版让至少三个不同机型的手机实测一遍。大部分审核驳回都发生在真机测试阶段而不是代码本身。这一套流程走下来你的“从零开始写小程序”就不只是一个口号而是一条实际跑通的路径。能把上面这些坑都趟过去的人才有资格说一句“我真会做小程序了”。