项目实战:美妆商城小程序 ------ 知识点详解与案例代码
本章围绕"美妆商城小程序"项目,系统讲解微信小程序开发的核心知识点。以下将从项目结构、页面开发、组件使用、API 调用、数据绑定、路由跳转、表单处理、本地存储等多个维度,结合具体案例代码进行详细说明。
一、项目创建与文件结构
知识点:小程序项目结构
微信小程序项目结构如下:
美妆商城/
├── app.js // 小程序逻辑
├── app.json // 小程序全局配置
├── app.wxss // 全局样式
├── project.config.json // 项目配置
├── sitemap.json // 页面索引配置
├── pages/ // 页面目录
│ ├── index/ // 首页
│ ├── goodsList/ // 商品列表页
│ ├── goodsDetail/ // 商品详情页
│ ├── order/ // 订单信息页
│ ├── address/ // 收货地址页
│ └── orderResult/ // 订单结果页
└── utils/ // 工具函数
案例:app.json 配置示例
json
// app.json
{
"pages": [
"pages/index/index",
"pages/goodsList/goodsList",
"pages/goodsDetail/goodsDetail",
"pages/order/order",
"pages/address/address",
"pages/orderResult/orderResult"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#ff6f91",
"navigationBarTitleText": "美妆商城",
"navigationBarTextStyle": "white"
},
"sitemapLocation": "sitemap.json"
}
说明:
pages
数组定义页面路径,第一项为首页。window
配置全局导航栏样式。- 页面路径必须在
pages
中注册,否则无法访问。
二、首页开发(index)
知识点1:WXML 数据绑定与列表渲染
语法说明:
- 使用
{``{}}
进行数据绑定。 - 使用
wx:for
渲染列表,wx:key
优化性能。
案例代码:首页轮播图 + 商品推荐
html
<!-- pages/index/index.wxml -->
<view class="container">
<!-- 轮播图 -->
<swiper autoplay="true" interval="3000" duration="500" indicator-dots="true">
<block wx:for="{{banners}}" wx:key="id">
<swiper-item>
<image src="{{item.url}}" mode="aspectFill" class="banner-img" />
</swiper-item>
</block>
</swiper>
<!-- 推荐商品 -->
<view class="goods-list">
<view class="goods-item" wx:for="{{recommendGoods}}" wx:key="id" bindtap="goToDetail" data-id="{{item.id}}">
<image src="{{item.image}}" class="goods-img" />
<text class="goods-name">{{item.name}}</text>
<text class="goods-price">¥{{item.price}}</text>
</view>
</view>
</view>
javascript
// pages/index/index.js
Page({
data: {
banners: [
{ id: 1, url: 'https://example.com/banner1.jpg' },
{ id: 2, url: 'https://example.com/banner2.jpg' }
],
recommendGoods: [
{ id: 101, name: '口红', price: 129, image: 'https://example.com/lipstick.jpg' },
{ id: 102, name: '粉底液', price: 258, image: 'https://example.com/foundation.jpg' }
]
},
goToDetail(e) {
const id = e.currentTarget.dataset.id;
wx.navigateTo({
url: `/pages/goodsDetail/goodsDetail?id=${id}`
});
}
});
css
/* pages/index/index.wxss */
.banner-img {
width: 100%;
height: 300rpx;
}
.goods-list {
display: flex;
flex-wrap: wrap;
padding: 20rpx;
}
.goods-item {
width: 48%;
margin: 1%;
background: #fff;
border-radius: 10rpx;
padding: 10rpx;
box-sizing: border-box;
}
.goods-img {
width: 100%;
height: 200rpx;
border-radius: 8rpx;
}
.goods-name {
display: block;
font-size: 28rpx;
margin-top: 10rpx;
}
.goods-price {
color: #ff6f91;
font-weight: bold;
}
关键点:
bindtap
绑定点击事件。data-id
传递商品 ID。wx.navigateTo
跳转页面并传参。
三、商品详情页(goodsDetail)
知识点2:页面传参与 onLoad 接收参数
案例代码:
javascript
// pages/goodsDetail/goodsDetail.js
Page({
data: {
goods: null
},
onLoad(options) {
const id = options.id; // 从 URL 获取参数
// 模拟从数据库或 API 获取商品数据
const mockGoods = {
101: { id: 101, name: '口红', price: 129, image: 'https://example.com/lipstick.jpg', desc: '持久显色' },
102: { id: 102, name: '粉底液', price: 258, image: 'https://example.com/foundation.jpg', desc: '轻薄遮瑕' }
};
this.setData({
goods: mockGoods[id] || {}
});
},
addToCart() {
wx.showToast({ title: '已加入购物车', icon: 'success' });
},
buyNow() {
wx.navigateTo({ url: '/pages/order/order' });
}
});
html
<!-- goodsDetail.wxml -->
<view class="detail-container" wx:if="{{goods}}">
<image src="{{goods.image}}" class="detail-img" />
<view class="detail-info">
<text class="name">{{goods.name}}</text>
<text class="price">¥{{goods.price}}</text>
<text class="desc">{{goods.desc}}</text>
<button bindtap="addToCart">加入购物车</button>
<button type="primary" bindtap="buyNow">立即购买</button>
</view>
</view>
说明:
onLoad
是页面加载时的生命周期函数,options
包含 URL 参数。- 使用
wx:if
控制内容是否渲染。
四、收货地址页(address)
知识点3:表单处理与本地存储(wx.setStorageSync)
案例:地址表单提交并保存到本地
html
<!-- address.wxml -->
<form bindsubmit="formSubmit">
<view class="form-item">
<input name="name" placeholder="收货人" value="{{formData.name}}" bindinput="onInput" />
</view>
<view class="form-item">
<input name="phone" placeholder="手机号" value="{{formData.phone}}" bindinput="onInput" />
</view>
<view class="form-item">
<input name="address" placeholder="详细地址" value="{{formData.address}}" bindinput="onInput" />
</view>
<button form-type="submit" type="primary">保存地址</button>
</form>
javascript
// address.js
Page({
data: {
formData: {
name: '',
phone: '',
address: ''
}
},
onInput(e) {
const { name, value } = e.detail;
this.setData({
[`formData.${name}`]: value
});
},
formSubmit() {
const { formData } = this.data;
// 简单校验
if (!formData.name || !formData.phone || !formData.address) {
wx.showToast({ title: '请填写完整信息', icon: 'none' });
return;
}
try {
wx.setStorageSync('shippingAddress', formData);
wx.showToast({ title: '地址保存成功' });
wx.navigateBack(); // 返回上一页
} catch (e) {
console.error('保存失败', e);
}
},
onLoad() {
// 页面加载时读取已保存的地址
const saved = wx.getStorageSync('shippingAddress') || {};
this.setData({ formData: saved });
}
});
关键点:
- 使用
bindinput
动态更新表单数据。wx.setStorageSync
同步保存数据到本地。wx.getStorageSync
读取本地数据。
五、订单结果页(orderResult)
知识点4:页面间数据传递(通过全局变量或缓存)
案例:显示订单成功信息
javascript
// app.js
App({
globalData: {
lastOrder: null
}
});
javascript
// order.js(下单后)
const app = getApp();
Page({
confirmOrder() {
const order = {
id: Date.now(),
time: new Date().toLocaleString(),
amount: 258
};
app.globalData.lastOrder = order;
wx.navigateTo({ url: '/pages/orderResult/orderResult' });
}
});
javascript
// orderResult.js
const app = getApp();
Page({
data: {
order: null
},
onLoad() {
this.setData({ order: app.globalData.lastOrder });
}
});
html
<!-- orderResult.wxml -->
<view class="result">
<text class="success">✓ 订单提交成功!</text>
<text>订单号:{{order.id}}</text>
<text>金额:¥{{order.amount}}</text>
<text>时间:{{order.time}}</text>
<button bindtap="goHome">返回首页</button>
</view>
javascript
// orderResult.js 补充
goHome() {
wx.reLaunch({ url: '/pages/index/index' }); // 重定向到首页,清空栈
}
六、综合性案例:完整购物流程模拟
场景:用户从首页 → 商品详情 → 下单 → 填写地址 → 订单成功
关键流程代码整合:
- 首页点击商品 → 跳转详情页(传 id)
- 详情页点击"立即购买" → 跳转订单页
- 订单页点击"提交订单" → 检查地址,若无则跳转地址页
- 地址页保存后返回 → 自动提交订单
- 跳转订单结果页
订单页逻辑(pages/order/order.js):
javascript
Page({
data: {
address: null,
goods: { name: '口红', price: 129 }
},
onLoad() {
const addr = wx.getStorageSync('shippingAddress');
this.setData({ address: addr });
},
submitOrder() {
if (!this.data.address) {
wx.navigateTo({ url: '/pages/address/address?from=order' });
return;
}
// 模拟下单
const app = getApp();
app.globalData.lastOrder = {
id: Date.now(),
goods: this.data.goods,
address: this.data.address,
amount: this.data.goods.price
};
wx.navigateTo({ url: '/pages/orderResult/orderResult' });
}
});
增强功能 :可在
address
页面的onUnload
或onShow
中检测是否来自订单页,自动返回并提交。
七、本章核心知识点总结
知识点 | 说明 | 对应 API/语法 |
---|---|---|
页面配置 | app.json 定义页面路径和窗口样式 | pages , window |
数据绑定 | WXML 中动态显示数据 | {``{variable}} |
列表渲染 | 循环渲染商品、轮播图等 | wx:for , wx:key |
事件处理 | 点击、输入等交互 | bindtap , bindinput |
页面跳转 | 导航到其他页面 | wx.navigateTo , wx.redirectTo , wx.reLaunch |
页面传参 | URL 传参与 onLoad 接收 | ?id=101 , options.id |
表单处理 | input 输入与 submit 提交 | <form> , bindsubmit |
本地存储 | 保存用户地址、购物车等 | wx.setStorageSync , wx.getStorageSync |
全局数据 | 跨页面共享数据 | getApp().globalData |
八、扩展建议
- 使用
wx.request
接入真实后端 API。 - 引入
vant-weapp
组件库提升 UI。 - 使用
云开发
实现无后端数据库存储。 - 添加购物车功能(使用数组 + 本地存储)。
通过以上知识点与案例,可完整构建一个功能健全的美妆商城小程序,覆盖用户浏览、下单、地址管理、订单展示等核心流程。