简介:这是一套开箱即用的微信小程序商城前端源码,面向小程序初学者、前端开发者及小型电商项目快速原型搭建者,解决无后台依赖下的基础商城展示与交互需求。资源共172个文件,包含38个JS逻辑文件(处理商品筛选、订单流程、模板消息调用等)、23个WXML结构文件(构建首页、分类页、购物车、支付页等10+核心页面)、26个WXSS样式文件(支持响应式适配与主题定制),以及55张PNG图标与8张JPG轮播图素材,整体压缩包仅907KB,轻量易部署。已有618人学习下载,源码结构清晰,涵盖轮播图、分类、品牌、商品、订单、促销六大管理模块的完整前端呈现逻辑,并内置客服电话、运费策略、VIP标识、模板消息ID配置等实用业务字段,配合主页、购物车、在线支付等多张界面预览图,可直接调试运行并快速二次开发。 拿到一份"不带后台"的微信小程序商城网站源码,很多人第一反应是:这玩意儿能干嘛?没有后台,商品数据往哪儿放?用户下单了怎么处理?其实我接触这类源码的次数挺多,今天想认真聊聊它到底怎么用、怎么改、怎么从本地Demo变成能上线的小程序。这篇内容不只讲代码,还把数据来源、核心模块、改造路径和排查经验都串起来,适合刚接触小程序商城开发、或者准备拿现有源码做二次开发的人。
先给这类源码定个性:它不是半成品,而是一种更轻量的技术方案。传统商城系统通常是"小程序前端 + Web管理后台 + 数据库 + 接口服务",但"不带后台"的源码砍掉了后半部分,所有业务逻辑都集中在小程序内部处理。好处是部署成本低,个人开发者只用微信开发者工具就能跑通;坏处是数据不能动态维护,支付、会员这些能力需要自己补。如果你能接受这个前提,后面很多问题其实都有明确的解法。
1. "不带后台"的商城源码,不是半成品,而是另一种思路
1.1 先搞清楚"不带后台"到底不含什么
你在网上下载、或者同事交接过来的商城小程序源码,经常能看到这样的目录结构:
miniprogram/ ├── pages/ │ ├── index/ # 首页 │ ├── goods/ # 商品详情 │ ├── cart/ # 购物车 │ ├── order/ # 订单列表 │ └── user/ # 个人中心 ├── utils/ │ ├── request.js # 网络请求封装 │ └── util.js # 公共方法 ├── app.js ├── app.json ├── app.wxss └── project.config.json注意,这套结构里没有admin目录,没有server目录,也没有接口域名配置文件。所谓的"不带后台",指的是它没有独立的Web管理端,也没有后端服务代码。它的小程序前端是完整的,页面、交互、跳转逻辑都在,但数据可能是写死在代码里的,也可能走的是第三方云平台。
这类源码最典型的特征是:你打开微信开发者工具,导入项目,填一个测试号AppID,就能直接看到商城界面。首页有轮播图、商品分类、推荐商品列表,点击商品能进详情页,加购物车能看到角标变化,部分连下单流程都有。但当你准备真正部署上线时就会发现,没有后台意味着没有商品管理、没有订单管理,换句话说,前端演示得再好,真要拿来经营,还得靠你自己补全后端能力。
1.2 这类源码最适合谁用
我在实际项目中接过的商城小程程序大概分三类,每一类对"不带后台"源码的态度都不一样。
第一类是学习用途。初学者想搞懂小程序商城的前端实现,比如列表渲染、页面传参、本地缓存、组件化,这类源码是最好的教学样本。因为不需要搭环境,不需要配数据库,导入即跑,读代码就能理解整个业务流程。
第二类是出Demo给客户确认需求。接外包的时候,拿一套现成的商城前端Demo给甲方看效果,比从头写快得多。这个时候"不带后台"反而是优势,你不用额外部署服务器,在开发者工具里演示一遍首页、分类、购物车、结算流程,客户看到的就是最终交互形态。
第三类是个人开发者做轻量生意。假设你只卖几个单品,商品数量少,一天也没几单,完全可以不用上传统后台。微信云开发本身就提供了数据库和云函数,"不带后台"的前端代码配合云开发改造后,能直接跑通真实业务,连服务器都不用买。
如果你不属于这三类,而是想做一个需要复杂运营、多角色管理、大量SKU拆分的大商城,"不带后台"这套东西就只能当参考,最终还是会走上自建后台或采购成熟系统的路。
1.3 和"带后台"版本的核心差异
为了更直观地说明问题,我把自己判断是否选用这类源码的维度整理成了表格:
| 对比项 | 不带后台的商城源码 | 带后台的完整商城系统 |
|---|---|---|
| 部署环境 | 微信开发者工具即可 | 需要服务器、数据库、域名、HTTPS证书 |
| 商品管理 | 改代码/改云数据库 | 后台可视化上架、改价、库存管理 |
| 订单处理 | 需自己写或放弃线下处理 | 后台查看、发货、退款 |
| 支付能力 | 需额外开发对接 | 通常内置微信支付/支付宝 |
| 运维成本 | 极低,几乎零维护 | 需要关注服务器安全和备份 |
| 学习门槛 | 适合前端初学者 | 前后端+运维都要懂 |
| 上线周期 | 短,改完即用 | 长,开发联调测试部署流程多 |
说句实在话,我见过不少创业者被"带后台"三个字绑架,明明产品还在验证期,就花两周搭后台、做权限、写日志,结果前端还没做好。如果你真的在起步阶段,"不带后台"的源码完全可以作为第一版跑起来,用户量上来了再补后台都不迟。
2. 没有后台服务,商城的商品和订单数据到底从哪儿来
这是整个"不带后台"方案的核心问题。没有后端接口,前端代码里的数据不可能凭空产生。我归纳了三种主流方案,顺序是按照手动程度从高到低排的。
2.1 方案一:本地Mock数据,最原始但最直观
很多源码默认就是这么干的。数据通常藏在utils/data.js或者直接在Page的data对象里。比如:
// pages/index/data.js const goodsList = [ { id: 1, title: "测试商品A", price: 99.9, image: "/images/goods-a.jpg", categoryId: 1, stock: 100 }, { id: 2, title: "测试商品B", price: 59.9, image: "/images/goods-b.jpg", categoryId: 2, stock: 50 } ]页面里直接 require 进来使用:
const { goodsList } = require('../../utils/data.js') Page({ data: { goods: [] }, onLoad() { this.setData({ goods: goodsList }) } })这种方式的优点是零成本、跑起来绝对不会跨域、也不会遇到网络请求失败。缺点也明显:改商品要改代码重新上传代码包,用户下单也没人记录。它只适合技术演示和学习源码时用。
2.2 方案二:微信云开发,给"不带后台"源码补上真正的动态数据
微信小程序自带的云开发,本质上是一套Serverless平台。不需要你自己买服务器,它提供了云数据库、云函数、云存储三个核心能力。我给好几套"不带后台"的商城源码做过云开发改造,思路都类似。
先开通云开发环境(在开发者工具里点云开发按钮,按提示建环境即可),然后在云数据库里创建商品集合、订单集合,把Mock数据导入进去。小程序端通过SDK直接读库:
const db = wx.cloud.database() Page({ data: { goods: [] }, onLoad() { db.collection('goods') .where({ status: true }) .orderBy('sort', 'asc') .get() .then(res => { this.setData({ goods: res.data }) }) } })注意,云开发数据库权限默认是"仅创建者可读写",你在云开发控制台手动导入的商品记录,创建者是你自己,那小程序端用户就看不到数据了。这时候要在云开发控制台把集合权限改成"所有用户可读,仅创建者可写",或者用云函数做服务端读取。我习惯用云函数,因为能控制返回字段、做分页、防刷,权限也更安全。
云开发的接入难度不大,但有几个坑:集合名称建议用连续小写字母,不要用大写或中文,不然排查起来很烦;数据库请求有个数限制,一次最多返回20条(基础版),真要做商品列表必须自己写分页逻辑。
2.3 方案三:对接已有API,让"不带后台"变成"假装有后台"
如果你手头已经有一个品牌商城的后端接口,或者团队里其他人负责维护服务端,那前端源码完全可以对接真实HTTP接口。只要把代码里所有直接读取本地数据的地方,换成wx.request请求即可。
// utils/request.js const request = (url, method = 'GET', data = {}) => { return new Promise((resolve, reject) => { wx.request({ url: `https://api.example.com${url}`, method, data, header: { 'Content-Type': 'application/json', // 通常要带上登录态 token 'Authorization': wx.getStorageSync('token') }, success: (res) => { if (res.statusCode === 200) { resolve(res.data) } else { reject(res) } }, fail: (err) => reject(err) }) }) } module.exports = request这种方式本质上是"没有后台源码,但借了别人后台的接口",适合你有API文档,但不需要把后台代码也一起拿过来的场景。
这三种方案不是互斥的。我经常先本地Mock跑通界面,然后用云开发把商品动态化,最后如果客户要求对接他们的后端,再把请求层切到真正的HTTP接口。改造的过程是一次性的,只要前端数据流设计得清楚,切换数据源的成本很低。
| 方案 | 适用人群 | 是否需要服务器 | 数据动态性 | 实施成本 |
|---|---|---|---|---|
| 本地Mock | 初学者、纯演示 | 不需要 | 无 | 极低 |
| 微信云开发 | 个人开发者、小团队 | 不需要 | 高 | 中 |
| 对接真实API | 有后端配合者 | 已有 | 高 | 中高 |
2.4 我一般怎么选
如果你拿到的"不带后台"源码里,数据都是写死的,我建议第一步先别急着接云开发,而是把所有写死的商品数据整理成一份独立的JS模块,统一导出。这样做的好处是,将来不管换云数据库还是走HTTP接口,你只需要改这一个模块,页面里的代码不用动。这是很多新手容易忽略的一点——数据结构约定好了,替换数据源才轻松。
如果这个商城是给自己用,我推荐直接上云开发,它解决了小程序登录(通过openid识别用户)、消息推送、数据存储这几件事,相当于一个被裁剪过的后台,但没有传统后台那些复杂的权限和界面。
3. 商城前端核心模块的实现思路拆解
一套商城小程序,不管带不带后台,前端页面绕不开这几个模块:首页/商品列表、商品详情、购物车、订单流程、个人中心。我在看源码时,也是按这个顺序去确认代码质量。
3.1 商品列表与商品详情:从静态渲染到分类筛选
绝大多数"不带后台"源码都会实现商品列表,但实现质量差异很大。合格的做法是:首页只展示推荐位,分类页根据categoryId筛选数据,商品详情页通过id拿到对应商品的完整信息。
页面之间的传参方式是关键。小程序页面跳转时,URL拼接是基本功:
<!-- goods-list.wxml --> <view class="goods-item" wx:for="{{goodsList}}" wx:key="id" bindtap="goDetail">// goods-list.js Page({ goDetail(e) { const id = e.currentTarget.dataset.id wx.navigateTo({ url: `/pages/goods/detail?id=${id}` }) } })商品详情页在onLoad里通过options.id接收参数,再根据id找到完整数据。
3.2 购物车:本地缓存持久化与状态同步
购物车在"不带后台"源码里通常用 wx.setStorageSync / wx.getStorageSync 实现,因为购物车是用户的个人数据,在没有用户体系的情况下,本地缓存是唯一靠谱的存储位置。
基础的购物车数据结构长这样:
// utils/cart.js const CART_KEY = 'cart' function getCart() { return wx.getStorageSync(CART_KEY) || [] } function addToCart(goods, count = 1) { const cart = getCart() const index = cart.findIndex(item => item.id === goods.id) if (index > -1) { cart[index].count += count } else { cart.push({ ...goods, count }) } wx.setStorageSync(CART_KEY, cart) } function updateCount(id, count) { const cart = getCart() const index = cart.findIndex(item => item.id === id) if (index > -1) { cart[index].count = count wx.setStorageSync(CART_KEY, cart) } } function removeFromCart(id) { const cart = getCart().filter(item => item.id !== id) wx.setStorageSync(CART_KEY, cart) } module.exports = { getCart, addToCart, updateCount, removeFromCart }一个小细节:购物车里存的数据最好是商品快照,包括标题、价格、图片、规格,不要只存id。如果未来后台改了商品价格,旧订单里的商品信息还能对上账。这个问题在"有后台"的商城里常常被忽略,"不带后台"的本地缓存版反而天然规避了。
购物车页面要注意的是总价计算。用 setData 更新整个数组性能没问题,但总价必须遍历当前购物车数组动态计算,不要自己维护一个totalCount变量,因为任何一次数量和勾选状态的变化都会导致总价失效。
3.3 订单流程:没有支付网关的时候怎么模拟
"不带后台"源码的订单模块通常有两种实现。一种是完全本地模拟:用户在购物车点击结算,跳转确认订单页,选择收货地址,点击提交订单后生成一个订单对象存到本地缓存里,同时清空购物车。另一种利用云开发,把订单写入云数据库。
模拟支付的代码通常长这样:
submitOrder() { const order = { id: Date.now().toString(), goodsList: this.data.cartList, totalPrice: this.data.totalPrice, status: 'pending', createTime: new Date() } // 没有真实支付能力,只更新订单状态,模拟支付成功 order.status = 'paid' const orders = wx.getStorageSync('orders') || [] orders.unshift(order) wx.setStorageSync('orders', orders) wx.setStorageSync('cart', []) this.setData({ cartList: [], totalPrice: 0 }) }这里我需要特别提醒:如果将来要接真实微信支付,模拟支付阶段的代码结构不能乱。建议在提交订单时,只生成待支付订单,别急着把状态改成paid。真实支付流程是:小程序端调用云函数或后端接口创建预支付单,后端调微信支付统一下单接口拿到paySign,然后小程序端wx.requestPayment唤起收银台,支付成功回调之后再更新订单状态为paid。你提前把状态机设计成pending -> paid -> shipped -> completed,比后期返工简单得多。
3.4 个人中心:登录态的设计与变化
个人中心在"不带后台"源码里是最容易被忽视的模块,很多源码直接展示一个头像加昵称,然后下面一排"我的订单""收货地址""联系客服"的入口。
这里必须知道一个事情:wx.getUserInfo 接口已经改版,不能直接弹窗获取用户头像和昵称了。如果你用的源码还是老写法,在现在的基础库版本下会静默失败,或者只能拿到灰色默认头像和"微信用户"昵称。
新的推荐方案是使用头像昵称填写能力:
<button class="user-info-btn" open-type="chooseAvatar" bind:chooseavatar="onChooseAvatar"> <image src="{{avatarUrl}}" /> </button> <input type="nickname" placeholder="请输入昵称" bindblur="onNicknameChange" />也就是说,用户主动选择头像路径,主动输入昵称,小程序再把这个头像上传到云存储或自己的服务器,昵称随业务接口提交。在"不带后台"的本地版源码里,你可以把昵称存到本地缓存,展示没问题;如果要跨设备同步,就得上云开发了。
4. 从拿到源码到跑通整个商城,完整流程与关键配置
这一节我按实际操作顺序讲,每一步都给出我踩过坑之后总结的经验。
4.1 环境准备和导入项目的四个注意点
第一步是打开微信开发者工具,选择"导入项目",然后选中源码根目录。很多人这里会卡住,原因是源码目录选错了。注意 project.config.json 所在的那一层才是小程序项目根目录,不是miniprogram目录的父目录,你自己看源码结构来确认。
导入时有四个配置需要注意:
- AppID选择:如果有自己的小程序AppID就填自己的;没有的话选"测试号"也能跑通大部分功能,但云开发、微信支付这些能力测试号不支持,需要真正注册小程序账号。
- 项目名称:不需要和源码里的名字一致,工具会读取project.config.json里的projectname,自己可以改。
- ES6转ES5:工具默认开启,保持默认即可,部分老源码依赖这个转换才能跑。
- 不校验合法域名:开发阶段必开,否则wx.request请求http地址或未备案域名时会报"url not in domain list"。这个选项在"详情-本地设置"里。
4.2 app.json与页面路径的检查清单
导入项目后如果白屏或页面空白,优先检查app.json。它是小程序的全局配置,pages数组的第一项是启动页面。
{ "pages": [ "pages/index/index", "pages/goods/list", "pages/goods/detail", "pages/cart/cart", "pages/order/confirm", "pages/order/list", "pages/user/index" ], "window": { "navigationBarTitleText": "商城", "navigationBarBackgroundColor": "#ffffff" }, "tabBar": { "list": [ { "pagePath": "pages/index/index", "text": "首页" }, { "pagePath": "pages/goods/list", "text": "分类" }, { "pagePath": "pages/cart/cart", "text": "购物车" }, { "pagePath": "pages/user/index", "text": "我的" } ] } }如果pages数组里某个路径指向不存在的文件,开发者工具会直接报错,但报错信息可能不直观,只是一句"文件不存在"。排查思路是打开控制台,看编译日志的红色warning,它会定位到具体缺哪个文件。
sitemap.json 也值得看一眼。它是微信搜索索引的配置,对商城这种需要被搜索到的项目来说,默认允许索引即可,但权限敏感页面比如用户个人中心不建议开启,可以在页面json里覆盖配置。
4.3 从开发者工具到真机预览,最容易出问题的三个环节
在开发者工具里一切正常,真机上却各种问题,这是小程序开发的经典玄学。我遇到最多的是下面三种情况。
图片加载不出来。开发工具能显示,真机显示空白,绝大多数原因是图片地址是http协议或者域名没有配置到后台白名单。解决方案有两个:要么把图片改用云存储里的地址,要么下载到本地放到images目录,要么在微信公众平台配置downloadFile合法域名。如果是http的图片,微信直接屏蔽,不能通过"不校验合法域名"选项绕过。
canvas相关接口层级问题。比如热搜词里提到的video在部分安卓手机上层级最高,挡住弹窗。这是小程序原生组件的历史遗留问题,原生video、map、canvas组件的层级没法通过z-index控制。解决方案是使用cover-view覆盖,或者换成同层渲染支持的基础库版本,再或者用云开发的组件库/第三方组件里的替代实现。
网络请求失败。真机上如果用了自签证书的HTTPS接口,或者后端没配置好证书链,wx.request会直接报失败。排查时用真机调试看Network面板,不要只看开发者工具。开发者工具的request不会校验证书链那么严格,真机更敏感。
4.4 顶部导航栏高度与安全区域适配
这是一个容易被忽略、但经常被搜索结果反复提问的点。小程序普通页面的导航栏由导航栏标题、胶囊按钮(右上角的胶囊形状菜单按钮)组成。胶囊按钮的位置在不同机型上不一样,所以需要动态获取:
const info = wx.getMenuButtonBoundingClientRect() const systemInfo = wx.getSystemInfoSync() const navBarHeight = (info.top - systemInfo.statusBarHeight) * 2 + info.height这段代码获取的是自定义导航栏时,导航栏的整体高度。如果源码里做了自定义导航栏,页面顶部内容很容易被刘海屏挡住。正确做法是在onLoad里获取胶囊按钮信息,把页面容器的paddingTop设置为胶囊按钮的top值,或者用CSS变量来统一处理:
.page { padding-top: var(--nav-bar-height); }在"不带后台"源码里,这条适配代码很可能缺失,真机预览时你会发现首页首屏内容顶到了最上面,观感很差。这也是检查源码质量时一眼能看出来的点。
5. 从"不带后台"到真正上线:改造路径与选型建议
如果打算把这套源码变成真实运营的商城,改造是必须的。我按改造顺序给出靠谱的路径。
5.1 第一步:把数据模型定清楚
不要一上来就写代码。先列个清单:商品需要哪些字段?分类是单级还是多级?订单有哪些状态?要不要加收货地址?要不要优惠券?
我一个个人项目的实际字段是下面这样的:
商品集合(goods):
- _id
- title
- cover
- images
- price
- originalPrice
- categoryId
- stock
- sales
- status
- sort
订单集合(orders):
- _id
- orderNo
- userId
- goodsList
- totalPrice
- status
- address
- createTime
- payTime
地址集合(address):
- _id
- userId
- name
- phone
- region
- detail
注意,在云开发里 _id 是数据库自动生成的,不需要手动维护。订单号建议用时间戳加随机数生成,不要用自增id,并发情况下容易冲突。
5.2 第二步:选择"云开发"还是"自建后端"
这个问题我每次都会被问到。直接给结论:
如果你是个人开发者,或者项目预期用户量不超过几千,直接用微信云开发。理由很实际:不需要域名备案、不需要买服务器、不需要配HTTPS证书,云函数天然解决了session和权限问题,云存储解决了商品图片问题。
如果你是团队开发,有专业后端,那"不带后台"源码只是一个前端资源,后端自己搭Node.js/Java/PHP服务都行。前端请求层用我上面给的request封装改为对接后端接口,页面逻辑基本不动。
下表是我做方案评估时常用的对比:
| 维度 | 微信云开发 | 自建后端 |
|---|---|---|
| 服务器成本 | 基础版按量,免费额度内够用 | 需要买云服务器 |
| 域名备案 | 不需要 | 需要 |
| 开发效率 | 快,前后端同构 | 慢,需要接口联调 |
| 数据控制权 | 依赖微信平台 | 完全自主 |
| 适合场景 | 小工具、轻商城 | 中大型业务系统 |
5.3 第三步:登录、支付、消息推送这些要接的微信能力
不带后台的源码通常跳过登录,直接用本地缓存存一个假user。上线的第一步是把用户体系建立起来。
用云开发时,云函数里可以直接拿到用户的openid:
// 云函数 getUserInfo const cloud = require('wx-server-sdk') cloud.init() exports.main = async (event, context) => { const wxContext = cloud.getWXContext() return { openid: wxContext.OPENID, appid: wxContext.APPID, unionid: wxContext.UNIONID } }前端通过 wx.cloud.callFunction,拿到openid后作为用户的唯一标识,存入用户集合,后续的订单、购物车、地址都挂在这个openid下面。这就是自建用户体系最省事的方案。
支付要单独说:云开发目前支持"云调用"微信支付,需要在小程序商户平台绑定商户号,然后云函数里通过 cloud.cloudPay.unifiedOrder 创建订单。这个流程比较长,建议在开发阶段先用模拟支付,把下单、订单列表、支付成功回调这些状态的流转先调通,最后再接入支付参数,避免调试支付时浪费大量时间。
订阅消息也一样,它是点对点的服务通知,比如商品发货提醒。云开发里同样可以通过云调用发送订阅消息,但订阅消息需要用户在小程序里主动授权一次模板,授权后只能发送一次,所以设计时不要让用户频繁授权。
5.4 第四步:把Mock数据替换成真实数据的操作顺序
我推荐分三步走,每一步都能验证。
第一步,把所有写死的数据集中到一个目录,比如constants/mockData.js,商品、分类、购物车、订单都从这里导入。
第二步,页面调用方式改成异步,统一通过商城数据服务模块(比如services/shop.js)返回Promise,页面里用then或await拿数据。这样将来无论切换云开发还是后端接口,页面代码都不用动。
第三步,实现services/shop.js的云端版本,内部调用云数据库或HTTP接口完成数据获取。验证通过后,把入口从mockData切换成云端实现。
这套模式在大型项目里叫Repository模式,在小程序里不需要那么重,但"页面不直接操作数据存储"这个习惯,能让你以后改造时省掉大量时间。
6. 开发调试中容易踩的坑,按实际排查顺序整理
最后这部分,我把自己在调试商城小程序时遇到频率最高的问题,按排查的先后顺序整理出来。
6.1 开发者工具正常,真机不显示图片或数据
处理顺序是:先看图片域名,再看数据是否异步返回,最后看是否有报错堆栈。
如果是本地图片没问题,远程图片要在微信公众平台后台配置downloadFile合法域名。域名配置是全局生效的,但是有缓存,改完等几分钟再试是正常的。
如果是数据问题,在真机调试面板里打断点,或者console打印返回结果。真机调试的Network面板能看到请求状况,比开发者工具更接近线上环境。
6.2 购物车数据"删不掉"或者"改了不生效"
这类问题的根源基本都出在缓存读写时机上。小程序setStorageSync是同步操作,一般不会丢,但如果多个页面同时读写同一个key,就有可能出现覆盖。我的经验是:购物车操作统一走utils/cart.js的封装的函数,不要在某一个页面里直接setStorageSync写死数据,否则整个项目里购物车逻辑有七八处,根本改不动。
另一个容易忽略的细节是,商品数量加减到0时,到底是从购物车里移除,还是保留但显示置灰不可选中?很多源码在数量减到0时会留下一个count:0的商品,页面会显示"小计¥0",看起来很差。好的做法是数量小于等于0时直接在数组里过滤掉。
6.3 网络请求间歇性失败,报net::err_connection_aborted
这个报错我在对接第三方接口时经常遇到。在小程序里最常出现的原因有几个:
- 后端接口响应太慢,超过了小程序默认的60秒超时。
- 后端接口的HTTPS证书链不完整,部分设备和网络环境会拒绝连接。
- 同一个接口在同一时间被并发请求太多次,后端扛不住主动断连。
排查顺序是:先在开发者工具里看请求耗时,把耗时超过3秒的接口列出来;再用浏览器或curl测试接口是否正常;最后检查后端日志确认有没有服务端异常。
我遇到过一种情况是小程序端自己同时发起了多个相同请求,导致后端重复处理。解决办法是在request封装里做一个简单的请求去重,同一url同一参数的请求,短时间内的重复请求直接复用第一个Promise。
6.4 分包异步化和整体包体积的控制
很多"不带后台"商城源码没有做分包。小程序主包体积上限是2MB,一旦商品图片以base64形式内嵌在代码里,或者把整个图表库打进去,很容易超限。
这时候要配置分包。把一些不常访问的页面,比如订单详情、售后、会员中心,放到分包里。分包配置在app.json里:
{ "subpackages": [ { "root": "packageOrder", "pages": [ "pages/order/detail", "pages/order/refund" ] } ] }分包的异步化是一个高级优化点:当用户从分包A跳转到分包B时,如果B还没有下载完成,默认会走"等待下载"的逻辑。微信提供了分包异步化的能力,可以让公共逻辑代码异步加载,减少首屏等待时间。但说实话,商城类项目一般用不到那么精细,只要图片不塞进代码包、接口返回数据不大量内嵌到页面json里,主包控制在1.5MB以内,体验都不会差。
6.5 页面白屏,控制台却看不到任何明文报错
这是最玄的坑。我自己的排查顺序是:
先看app.js里是否有同步的wx.getStorageSync读取,如果有,读取失败或数据结构异常会直接阻塞整个app启动。很多老源码在app.js里放初始化逻辑,一旦报错,所有页面全白。
再看app.json里页面路径是否正确。一个常见的低级错误是,文件叫list.js,页面路径里写的是index.js,编译时不报错,但真机运行白屏,开发者工具也只能看到一个warn。
最后检查页面的onLoad里有没有awaited一个没有被catch的Promise。如果数据源是云数据库,而云开发环境没有开通或环境ID错误,云函数调用会报错,这个错误不会被页面捕获,导致渲染数据一直是空的。解决方法是做一层错误兜底,在页面上显示"加载失败"和重试按钮,而不是默默白屏。
结尾
我把这套排查逻辑用在一个从网上下载的"不带后台"商城源码上,前前后后只花了半天时间,就把它从纯静态Demo改造成了基于云开发的可用小程序,商品数据在云控制台维护,订单同步到云数据库,个人用户通过openid区分。整个过程没有引入传统后台,但商城该有的业务闭环已经成立了。如果你手里也有一份类似的源码,建议不要急着丢,先按我上面说的流程把数据流摸清楚,再做增量改造。等你真正把一款"不带后台"的商城折腾上线,你对小程序前后端数据交互的理解,会比直接套用一套完整系统深得多。
本文还有配套的精品资源,点击获取