阶段 1 -- 菜单浏览(超详细版)
目标:完成「首页=菜品卡片列表」
- 打好 UI 地基
- 会从 云数据库 拉取
categories
/dishes
并渲染- 打 Git Tag
v1.0‑menu
1. 技术/知识点速览
知识点 | 关键词 | 说明 |
---|---|---|
云数据库 | db.collection().where().get() |
小程序端查询示例 |
图片优化 | <image lazy-load /> |
懒加载,减少首屏体积 |
性能 | Skeleton / 分段加载 | 骨架屏 + 滚动分页(可选) |
2. 前置准备
-
创建首页页面
bash# 工具中新建 miniprogram/pages/index/
3. 设计数据结构(仅 2 张核心表)
集合 | 主要字段 | 备注 |
---|---|---|
categories |
_id , name , sort |
sort 用于 Tab 顺序 |
dishes |
_id , name , price , img , categoryId , spicyLevel , sold |
后续统计销量可用 |
种子数据 :在 阶段 0 的
db/seed.js
里补充 3‑5 个分类、每类 4‑5 道菜。
你可以在微信开发者工具「云开发控制台 → 数据库」中手动插入测试数据:
java
// categories
{ "_id": "001", "name": "热菜", "sort": 1 }
{ "_id": "002", "name": "凉菜", "sort": 2 }
// dishes
{ "name": "宫保鸡丁", "price": 18, "img": "xxx", "categoryId": "001" }
{ "name": "拍黄瓜", "price": 10, "img": "xxx", "categoryId": "002" }
4. 页面文件详解
4.1 index.json
json
{
"navigationBarTitleText": "点餐"
}
4.2 index.wxml
------ 结构布局
xml
<view class="dish-list">
<view wx:for="{{dishes}}" wx:key="_id" class="dish-card">
<image class="thumb" src="{{item.img}}" mode="aspectFill" lazy-load />
<view class="info">
<text class="name">{{item.name}}</text>
<text class="price">¥{{item.price}}</text>
</view>
<button class="add-btn" data-dish="{{item}}" bindtap="onAddCart">加入</button>
</view>
</view>
lazy-load
属性让图片只在进入视口时加载,提高性能。
4.3 index.wxss
------ 简易样式
css
.dish-list {
display: flex;
flex-direction: column;
padding: 16rpx;
}
.dish-card {
display: flex;
align-items: center;
margin-bottom: 20rpx;
background: #fff;
border-radius: 12rpx;
overflow: hidden;
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.05);
}
.thumb {
width: 100rpx;
height: 100rpx;
flex-shrink: 0;
border-radius: 8rpx;
margin: 12rpx;
}
.info {
flex: 1;
display: flex;
flex-direction: column;
}
.name {
font-size: 30rpx;
font-weight: bold;
}
.price {
color: #fa541c;
margin-top: 8rpx;
}
.add-btn {
background-color: #07c160;
color: white;
font-size: 24rpx;
padding: 0 20rpx;
margin-right: 12rpx;
height: 60rpx;
line-height: 60rpx;
border-radius: 30rpx;
}
4.4 index.js
------ 业务逻辑
javascript
const cart = require('../../store/cart')
Page({
data: {
dishes: []
},
onLoad() {
this.loadDishes()
},
async loadDishes() {
const db = wx.cloud.database()
const res = await db.collection('dishes').get()
this.setData({ dishes: res.data })
},
onAddCart(e) {
const dish = e.currentTarget.dataset.dish
cart.add(dish)
wx.setTabBarBadge({ index: 1, text: String(cart.totalCount()) })
wx.showToast({ title: '已加入购物车', icon: 'success' })
}
})
5. 性能小贴士(可选提升)
场景 | 做法 |
---|---|
图片很多时 | 给 <image> 加 mode="aspectFill" + lazy-load ,并在云存储里裁剪到 300×300 |
数据过多 | 分页:limit(20).skip(page*20) ;滑到列表底部触发 onReachBottom 追加 |
切换 Tab 卡顿 | 预取下一分类的菜品(Promise.all)或使用本地缓存 |
6. Git Tag & 自测清单
git add . && git commit -m "feat: menu browse"
git tag v1.0-menu && git push --tags
- 打开开发者工具 → 真机预览,确认:
- 菜品卡片加载、价格/销量显示正确
- 图片懒加载生效(网络面板可观察请求)
- 点击卡片能弹出「已加入」提示
7. 练习(巩固 & 拓展)
难度 | 练习内容 |
---|---|
⭐ | 给 dishes 增加 spicyLevel 字段(0‑3),在卡片右侧用 🌶️ 图标展示辣度。 |
⭐⭐⭐ | 实现「下拉刷新」:onPullDownRefresh 重新拉取当前分类数据。 |
⭐⭐⭐ | 引入 IntersectionObserver ,把列表改成 瀑布流 + 懒加载分页(体验电商式长列表)。 |
阶段小结
-
至此,你已掌握 页面结构 → 云数据库查询 → 图片优化 的完整闭环。
-
代码行数 ≈ 150,适合新手阅读。
-
下一阶段(购物车)将基于本页数据做 状态管理 ,建议 保持当前目录结构 并直接开新分支:
bashgit checkout -b feat/cart
祝你编码愉快,继续加油!