ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

微信外卖点餐小程序模板二次开发:从zip导入到购物车订单联调

微信外卖点餐小程序模板二次开发:从zip导入到购物车订单联调 简介美食餐饮外卖点餐微信小程序模板是为餐饮商户与小程序开发者打造的一站式解决方案帮助快速搭建外卖点餐与门店展示平台无需从零编写代码适合预算有限或希望快速试水的团队。压缩包共68个文件其中22个png格式UI切图、15个json数据配置、10个js逻辑脚本、9个wxss样式表、8个wxml页面结构以及少量jpeg示例图和gitignore工程文件整体仅1.33MB目录包括页面、工具、配置等模块便于二次开发与替换素材。目前已有136人学习下载模板内置用户端点餐、购物车、订单列表、地址管理、优惠券展示、门店介绍等页面并预留支付与配送相关接口商家可据品牌需要调整主题颜色、菜单分类和配送规则快速生成个性化小程序。依托微信扫码即用、分享裂变及模板消息推送能力可有效缩短点餐路径、刺激复购是低成本进入微信生态的实用选择。1. 一个餐饮外卖模板的 zip不是下载完就结束的做外卖点餐这类微信小程序最常用的起步方式不是从零搭框架而是找一份成品模板下载回来改造。交付形态通常是一个 .zip 压缩包里面装着菜品列表、分类菜单、购物车和订单确认页的完整页面代码以及全局配置文件。这类模板的易用性建立在“代码结构和演示数据都完整”的基础上但脱离原作者账号和服务端之后直接导入微信开发者工具一定会遇到几个现实问题AppID 对不上导致编译失败、模板自带菜品写死在 data 文件里、请求接口还指着一个已经失效的域名。接下来的内容把“拿到 zip 之后”这条路走通从解压前检查到工具导入从页面结构拆解到菜品展示、分类切换、购物车、提交订单的主链路替换最后给出上线前真机验证的检查点。适合手里已经有一个模板、想快速改成自己业务的人按顺序操作。2. zip 解压后先核对结构再用微信开发者工具把模板跑起来2.1 解压前看什么目录层级、文件完整度与隐藏文件拿到模板压缩包先不要急着解压。用归档工具打开 zip看一眼根目录下方是否嵌套了一层同名文件夹。微信开发者工具的导入逻辑是你选中的那个文件夹里必须直接能看到 app.json、app.js、project.config.json。如果在导入时选错了层级工具会报“未找到 project.config.json”或直接提示该目录不是一个有效的小程序项目。解决方式不是改代码而是把导入路径往内层再移一级。这类嵌套在多人分享的模板里很常见先确认这一步能避免卡在开头。第二件值得核对的事是 project.config.json 的 appid 字段。模板公开传播时作者通常会把自己注册的小程序 AppID 清空写一个 touristappid 占位。导入时用测试号还是自己的 AppID取决于你接下来的联调计划测试号适合只在本地看界面效果因为很多接口拿不到真实用户身份自己的 AppID 可以从登录、支付到订阅消息完整走一遍但需要在小程序后台配置服务器域名。这个字段在开发者工具的“详情—基本信息”里也能直接改不强制手动编辑文件。第三是压缩包完整性的快速测试。模板链接经过网盘转存或多次下载后zip 文件偶发损坏。解压工具解到一半提示 CRC 校验失败时不要选择“全部跳过”那会让后续导入缺文件。macOS 终端可以直接对压缩包做一次测试unzip -t 美食餐饮外卖点餐的微信小程序模板.zip输出里出现 No errors detected 就说明 zip 没坏Windows 端的压缩软件一般也有“测试压缩文件”入口跑一遍没有红色报错即可。模板包内如果带了 node_modules 或 .git 这类目录不影响编译但体积大、导入慢。准备做二次开发前先删掉它们再打进自己的版本管理里。2.2 导入微信开发者工具时AppID 和编译模式的三个关键选择解压完毕进入导入流程。开发者工具“导入项目”的面板里需要填三个东西目录路径、AppID、后端服务。目录选到包含 app.json 的那一层这一点上一节已经说过AppID 按场景选后端服务如果不需要云开发选“不使用云服务”就行避免工具自动安装云开发相关依赖。结合外卖模板的联调阶段AppID 的选择可以做这样的对应阶段选什么要注意的问题本地看界面测试号测试号无法调用微信登录、支付等涉用户身份接口对接自己的后端自己的 AppID需要在管理后台配置 request 合法域名开通微信支付自己的 AppID 商户号商户号与 AppID 必须绑定模板里没有这步配置首次编译时如果页面白屏先看“调试器—Console”里的报错。高频的有三种某个图片路径 404属于 assets 目录没匹配某个模块 require 失败属于文件在解压时没完整落地某个页面 json 文件里的 navigationBarTitleText 出现乱码属于文件编码不是 UTF-8。前两种回 2.1 检查压缩包完整性最后一种把 json 文件另存为 UTF-8 编码即可。编译成功之后工具顶部有一个“普通编译”下拉框。开发者工具默认的启动页面是上次保存时的页面而模板的默认启动页可能是登录页或品牌页。想在开发时直接看到菜品列表就选择“添加编译模式”启动页面填点餐主页的实际路径比如 pages/index/index。这个操作只影响开发启动对线上用户无感。线上的首页路径由 app.json 里 pages 数组的第一项决定同时微信后台“页面设置”里的“首页路径”也会覆盖它两处要保持一致。这里还需要分清 wxml 与 HTML 的差别。wxml 是微信定义的一套模板标记它把数据绑定、循环wx:for、条件渲染wx:if和事件绑定bindtap都揉进了标签属性里。模板里的“模板语言”指的就是这套标记它不是 JavaScript也不直接跑在浏览器里而是由小程序的视图层解析。改菜品展示时重点去动 wxml 和对应 js 的 data而不是去找 HTML 文件——模板包里根本没有 HTML 文件。2.3 目录结构拆解pages、components、utils 在点餐模板里的分工微信小程序项目对内部目录结构没有强制规定只有根目录的 app.js、app.json、app.wxss 是必须的。餐饮外卖模板常见的额外目录包括 pages、components、utils、data、assets它们各自承担不同的职责目录/文件在模板里管什么改造时会碰到的点app.json页面注册、tabBar、窗口表现调整首页与 tab 图标pages/index菜品列表、分类菜单替换 mock 菜品改布局样式pages/cart购物车检查存储键名与 index 页一致pages/order收货信息、备注、提交对齐后端字段处理金额精度utils/request.jswx.request 的封装层改 baseURL、token、超时时间data/goods.js演示用 mock 菜品数据接真实接口后可以删除模板最容易让后期踩坑的位置在购物车页与其数据源之间。有的模板用wx.setStorageSync(cart, …)写入本地缓存结算页用wx.getStorageSync(cart)读取键名只要差一个字符就会导致列表页能看到加购数量、结算页却为空。有的模板把购物车放到了app.globalData.cart这个方案在小程序冷启动之后会自动清空等于用户每次打开都要重新点菜。拿到模板后建议先在工具里全局搜索 cart顺着读取路径把存储介质统一掉。如果原模板没有做持久化购物车就按下一章的写法自己补上。3. 从菜品列表到提交订单外卖模板的 4 段核心改造3.1 菜品数据替换模板的 mock 数据结构和 wx:for 渲染模板作者为了让你打开就能看到效果会把一批演示菜品写在本地文件里最常见的位置是data/goods.js。改写前先别急着套用自己的接口结构而是保持模板字段不变、照原样替换数据。菜品对象的常见结构如下// data/goods.js module.exports [ { id: 1, cateId: 1, name: 招牌黄焖鸡, price: 26, sales: 120, image: /assets/images/chicken.png }, { id: 2, cateId: 2, name: 冰镇酸梅汤, price: 6, sales: 80, image: /assets/images/drink.png } ]字段说明id 是菜品的唯一标识购物车合并时靠它做判断cateId 指向分类 id分类切换时靠它做过滤price 是展示单价单位是元image 是本地图片路径。如果后端返回的价格单位是分前端展示前要除以 100并保留两位小数不要直接渲染一个 2600 的大整数。sales 字段决定菜品排序真实接口里一般由后端计算。列表页 wxml 的循环渲染是这段view classgoods-list view classgoods-item wx:for{{goods}} wx:keyid >// pages/index/index.js Page({ data: { categories: [], // [{ id: 1, name: 热销 }] goods: [], // 每个商品带 cateId 字段 activeCatId: 1 }, onCategoryTap(e) { // Number() 防止 dataset 返回字符串与 id 数字类型不匹配 const catId Number(e.currentTarget.dataset.catid) this.setData({ activeCatId: catId }) } })wxml 里右侧 scroll-view 绑定 scroll-into-viewview classmenu-body scroll-view classleft-side scroll-y view classcat-item {{activeCatId item.id ? on : }} wx:for{{categories}} wx:keyid >// pages/index/index.js handleAddCart(e) { // dataset 中取出的是当前菜品对象 const goods e.currentTarget.dataset.item // 读取本地缓存key 为 cart首次读取时为空数组 const cart wx.getStorageSync(cart) || [] // 按 id 判断购物车里是否已有同款 const index cart.findIndex(item item.id goods.id) if (index -1) { cart[index].count 1 } else { // 不存在时 push 新记录只保留后续展示需要的字段 cart.push({ id: goods.id, name: goods.name, price: goods.price, count: 1 }) } wx.setStorageSync(cart, cart) // 刷新购物车角标避免与当前页面的 data 不同步 this.updateBadge(cart.length) }购物车对象里每个条目的字段构成可以按这个表格来对照字段类型用途idNumber商品唯一标识决定合并逻辑nameString结算页展示菜名priceNumber单价金额计算基数countNumber购买数量累加这里的关键是每次更新后都要立刻写回缓存而不是只在页面 data 里维护一份 cart 数组。结算页读取同一个 key再根据所选条目重新计算金额。模板如果另写了一个 key 放结算商品下单前要注意两边一致性。storage 单个 key 的容量上限是 10MB餐饮点餐的购物车数量级完全够用不需要引数据库。3.4 提交订单的 wx.request 封装与联调地址配置结算按钮点击后订单数据要发给服务端。模板一般已经把 wx.request 封装成 utils/request.js但 baseURL 还指向旧演示接口。改模板时把三处对齐baseURL、请求头、返回码约定。下面是订单提交最直接的写法// pages/order/order.js Page({ data: { phone: , address: , note: }, submitOrder() { // 从购物车缓存中读出本次要结算的商品 const items wx.getStorageSync(cart) || [] if (items.length 0) { wx.showToast({ title: 购物车是空的, icon: none }) return } // 组装后端约定的 payload 结构 const payload { items: items, phone: this.data.phone, address: this.data.address, note: this.data.note } wx.request({ url: https://api.example.com/order/create, method: POST, data: payload, header: { content-type: application/json }, success: (res) { // 约定的返回码code 0 表示成功 if (res.data res.data.code 0) { wx.removeStorageSync(cart) wx.redirectTo({ url: /pages/pay-result/pay-result }) } else { wx.showToast({ title: res.data.msg || 下单失败, icon: none }) } }, fail: (err) { wx.showModal({ title: 网络错误, content: err.errMsg || 请稍后重试 }) } }) } })这段代码里有三个在模板改造中容易漏掉的点。第一method 不显式写 POST 时wx.request 默认是 GETpayload 会拼到查询字符串上后端如果按 POST body 接收就会收不到。第二header 的 content-type 要写成 application/json与服务端接口的 JSON 解析对应模板里如果有上传文件的需求把 content-type 改成了 multipart/form-data提交 JSON 时必须改回来。第三success 回调里要以业务返回码为准不能只看 HTTP 状态码。联调阶段想知道请求发没发、返回了什么打开开发者工具的“调试器—Network”面板找到对应对应请求看 Preview 或 Response 标签里的返回体——这比盲目地加 console.log 更直接。4. 上线前的最后一公里真机调试、域名白名单与启动页调整4.1 修改“刚进入小程序的加载页面”的落点模板自带的“首页”常常是一个品牌欢迎页要改成菜品列表页。开发环境下通过“添加编译模式”改启动页面只影响开发调试线上的首页由两处决定。第一处是 app.json 中 pages 数组的第一项把点餐主页路径移到第一位第二处是微信公众平台后台“设置—页面设置”里的首页路径后台配置的优先级高于前端代码。两处都改了重新发布之后用户进入看到的才是菜品列表。模板如果用了自定义导航栏风格还需要把顶部导航栏高度算准。获取方式在基础库 2.20.1 以上用wx.getWindowInfo()状态栏高度是statusBarHeight导航栏高度可以按胶囊按钮的位置动态算出来const winInfo wx.getWindowInfo() const menuButton wx.getMenuButtonBoundingClientRect() const navBarHeight (menuButton.top - winInfo.statusBarHeight) * 2 menuButton.height模板里硬编码 44 或 64 的写法在部分机型上会顶到状态栏菜单页这类有滚动区域的页面表现就是首屏内容被遮住一块。算出来的高度用于占位 view 的 style比写死兼容性好得多。4.2 真机调试中 wx.request 失败的三个必查项真机与开发者工具体验差异最大的是网络层高频故障就三类照顺序排查最快。小程序后台配置的 request 合法域名必须是已备案的 HTTPS 域名不能带端口和路径。开发阶段可以勾选“不校验合法域名”在工具里跑通真机预览不会忽略这条必须把域名加进后台白名单配置后等一两分钟再试。模板里演示接口的 url 可能还停在http://协议iOS 端明文 HTTP 请求会被直接拦截必须改成https://证书要有效期内且链完整自签名证书不能用。联调时的现象和对应原因可以先做一张表对照现象原因处理提示 request:fail域名不在白名单或协议非 https后台加白名单url 改 https返回数据是 HTML 结构接口域名做了 302 跳转或配置错误在 Network 看响应头确认没有重定向请求成功但页面没数据渲染字段名与后端不一致用真机 vConsole 打开请求返回体逐字段对照第三payload 字段与后端字段要对齐。协同开发时前端把 items 传成数组后端可能期望一个 JSON 字符串模板会依据后端接口文档调整提交前的组装步骤不要在后端没动的情况下反复排真机。下单成功后记得把购物车缓存清掉代码里已经写了wx.removeStorageSync(cart)。4.3 扫掉模板残留的 mock 数据与调试输出上线前最后做一次全局搜索。在微信开发者工具里全局搜索require(../../data/和console.log把页面里引用 mock 数据的代码替换为 wx.request 获取远端数据的调用调试日志可以保留但打印整份购物车对象这类高负载日志在生产环境最好删掉。mock 文件data/goods.js本身可以留着备份只要不参与编译路径即可。再搜一遍setStorage确认购物车键名全项目唯一没有两套并存的存储逻辑然后提交发布。这样处理之后模板的演示参数不会带到用户端后面接真实后端时也只需要改请求层的 baseURL不再需要逐页翻代码。本文还有配套的精品资源点击获取
返回列表