979 字
5 分钟
家庭餐单小程序:uni-app 组件化与云开发的实战经验

家里每天最头疼的问题是”今天吃什么”。做了个家庭餐单小程序来治这个病:记录日常菜品,智能生成一周餐单,一键分享给家人。项目还在迭代中,这篇记录目前开发过程中觉得值得说的几个点。

产品思路#

痛点很具体:做饭的人每天都在决策,决策成本其实很高。小程序要做的不是”菜谱大全”,而是”决策工具”——把”吃什么”从每天想 20 分钟,变成 10 秒内出结果。

核心功能三条:

  • 菜品库:家人各自录入常做的菜,按分类整理
  • 智能排餐:根据菜品库自动生成每日/每周餐单,均衡搭配、尽量不重复
  • 分享协作:餐单一键分享到家庭群,家人可见、可点赞可吐槽

技术选型:uni-app + 微信云开发#

选 uni-app 是为了保留跨端可能(以后可能上支付宝/抖音小程序),UI 层用微信原生组件风格开发,适配 rpx 基准。

后端直接用微信云开发:云数据库存储菜品和餐单,云函数处理业务逻辑,免运维。对小团队和个人项目来说,这是性价比最高的方案——不用管服务器,按量付费,量小几乎免费。

组件化:把 UI 变成积木#

小程序开发最容易变成”一个页面 500 行 WXML”。这次我强制自己做了组件拆分:

  • dish-card:菜品卡片,展示图片、名称、标签、操作按钮
  • meal-plan:一周餐单视图,支持横向滑动切换
  • category-tabs:分类筛选栏
  • share-card:分享海报卡片

组件用 properties 接收数据、triggerEvent 抛事件,父子通信规范。好处是页面代码大幅瘦身,改样式只动组件不动页面。餐单生成算法放在独立的工具模块里,和 UI 完全解耦:

// 简单版:按分类均衡取菜,尽量不连续重复
function generatePlan(dishPool, days, slotsPerDay) {
const plan = [];
const lastUsed = new Map(); // dish -> 上次出现的下标
for (let d = 0; d < days; d++) {
const dayPlan = [];
for (let s = 0; s < slotsPerDay; s++) {
const candidates = dishPool.filter(
(dish) => !dayPlan.includes(dish) && (lastUsed.get(dish.id) ?? -9) < d - 2
);
const pick = candidates[Math.floor(Math.random() * candidates.length)]
|| dishPool[Math.floor(Math.random() * dishPool.length)];
lastUsed.set(pick.id, d);
dayPlan.push(pick);
}
plan.push(dayPlan);
}
return plan;
}

算法很朴素,核心约束就两条:同一天不重复、同一道菜间隔至少两天。够用,且家人能看懂逻辑,好提需求。

踩过的坑#

云函数超时。 第一版把餐单生成逻辑放云函数里,菜品库大了之后偶尔超时。后来把生成逻辑挪到前端本地执行(菜品数据本来就在本地缓存),云函数只做数据读写,问题消失。

分享卡片。 微信的 onShareAppMessage 只能自定义标题和图片路径,不能直接分享带参数的富文本卡片。方案是做了一张 Canvas 海报图:wx.createCanvasContext 画菜品图 + 文字 + 二维码,分享出去既有信息量又能引流回小程序。

rpx 的适配陷阱。 750 基准下,1rpx = 屏幕宽 / 750,听起来简单,但给 Canvas 画海报时用的是 px,两边换算忘了一除,海报文字直接飞出屏幕。教训:混用 rpx 和 px 的场景,换算要在同一个函数里做,别散落在各处。

下一步#

  • 菜品库接入家人协作编辑,权限简化成”家庭成员均可增删”
  • 按营养标签做更聪明的均衡搭配
  • 上线后根据真实使用数据调排餐逻辑

做这个小程序最大的体会:工具类产品的核心是”决策效率”,功能可以简单,但决策链路必须短。这个思路在写企业系统时同样适用。

家庭餐单小程序:uni-app 组件化与云开发的实战经验
https://blog.cqfly.xyz/posts/wechat-mini-program-lessons/
作者
陈庆飞
发布于
2026-04-18
许可协议
CC BY-NC-SA 4.0