1. 项目背景与技术选型
最近接到一个饰品商城的微信小程序开发需求,客户要求使用Vue.js+uni-app技术栈实现完整的电商功能,包括商品展示、购物车、订单管理和物流跟踪等模块。之所以选择这个技术组合,主要基于以下几点考虑:
-
跨平台优势:uni-app的"一次开发,多端发布"特性,可以让我们用同一套代码同时发布到微信小程序、H5和App端,大大降低了后续多端适配的成本。实测下来,核心业务逻辑的代码复用率能达到85%以上。
-
开发效率:Vue.js的组件化开发模式配合uni-app丰富的UI组件库(如uView),可以快速搭建出符合电商需求的界面。特别是对于商品列表、分类筛选这类常见场景,uni-app提供的scroll-view和swiper等优化组件性能表现优异。
-
微信生态集成:uni-app对微信小程序API的封装非常完善,从登录授权到支付接口都有现成的插件可用。我们在调试时发现,uni-app的wx.requestPayment封装比原生开发更稳定,特别是在处理iOS端支付回调时。
技术选型时的一个教训:最初考虑过直接用微信原生开发,但后来发现商品详情页需要复用H5版本的内容,而uni-app的rich-text组件可以完美兼容两端,这才确定了技术方案。
2. 项目初始化与基础配置
2.1 环境搭建
首先需要安装必要的开发环境:
bash复制# 全局安装vue-cli
npm install -g @vue/cli
# 创建uni-app项目
vue create -p dcloudio/uni-preset-vue my-mall
# 进入项目目录安装依赖
cd my-mall
npm install
关键依赖版本控制(package.json节选):
json复制{
"dependencies": {
"uni-app": "^2.0.0",
"vuex": "^3.6.2",
"uview-ui": "^1.8.4",
"dayjs": "^1.10.7"
},
"devDependencies": {
"@dcloudio/uni-helper-json": "^1.0.13",
"@dcloudio/vue-cli-plugin-uni": "^4.0.0"
}
}
2.2 微信小程序配置
在manifest.json中配置小程序特有设置:
json复制{
"mp-weixin": {
"appid": "你的小程序APPID",
"setting": {
"urlCheck": false,
"es6": true,
"postcss": true
},
"usingComponents": true,
"permission": {
"scope.userLocation": {
"desc": "需要获取您的位置信息用于物流跟踪"
}
}
}
}
特别注意:微信小程序要求所有网络请求域名必须备案并加入白名单。我们在这个项目中使用uni.request时,需要提前在微信公众平台配置request合法域名,包括:
- 商品API域名
- 支付回调域名
- 物流查询接口域名
3. 核心功能实现
3.1 商品展示模块
商品列表页采用瀑布流布局,关键实现代码如下:
vue复制<template>
<view class="goods-list">
<waterfall
:list="goodsList"
@click="handleGoodsClick"
>
<template v-slot:item="item">
<goods-card
:price="item.price"
:title="item.name"
:thumb="item.image"
:tags="item.tags"
/>
</template>
</waterfall>
<uni-load-more
:status="loadingStatus"
@clickLoadMore="loadMore"
/>
</view>
</template>
<script>
export default {
data() {
return {
goodsList: [],
page: 1,
loadingStatus: 'more'
}
},
methods: {
async fetchGoods() {
this.loadingStatus = 'loading'
const res = await uni.request({
url: '/api/goods',
data: { page: this.page }
})
this.goodsList = [...this.goodsList, ...res.data.list]
this.loadingStatus = res.data.hasMore ? 'more' : 'noMore'
}
}
}
</script>
性能优化点:
- 图片懒加载:使用uni-app的
lazy-load属性 - 分页加载:每次加载20条数据,滚动到底部自动加载下一页
- 数据缓存:对商品基础信息使用vuex持久化存储
3.2 购物车与订单系统
购物车数据结构设计:
javascript复制// store/modules/cart.js
const state = {
items: [
{
id: 1,
goodsId: 1001,
name: "星空项链",
price: 199,
count: 2,
selected: true,
image: "/static/goods/1001.jpg"
}
],
selectedAll: false
}
订单创建关键流程:
- 前端组装订单数据(含商品、收货地址、优惠信息)
- 调用后端创建订单接口
- 获取预支付信息后调起微信支付
- 支付成功后更新订单状态
支付代码示例:
javascript复制async submitOrder() {
const orderRes = await this.$http.post('/order/create', this.orderData)
const payRes = await uni.requestPayment({
provider: 'wxpay',
orderInfo: orderRes.payParams,
timeStamp: orderRes.timeStamp,
nonceStr: orderRes.nonceStr,
package: orderRes.package,
signType: orderRes.signType,
paySign: orderRes.paySign
})
if (payRes.errMsg === 'requestPayment:ok') {
uni.redirectTo({
url: `/pages/order/result?id=${orderRes.orderId}`
})
}
}
3.3 物流跟踪实现
物流信息查询方案:
- 接入快递鸟API作为物流数据源
- 后端定时轮询更新物流状态
- 前端通过WebSocket获取实时推送
物流组件实现:
vue复制<template>
<view class="logistics-track">
<view
v-for="(step, index) in tracks"
:key="index"
class="track-step"
:class="{ active: index === 0 }"
>
<view class="dot"></view>
<view class="content">
<text class="status">{{ step.status }}</text>
<text class="time">{{ step.time }}</text>
<text class="location" v-if="step.location">{{ step.location }}</text>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
expressNo: String,
expressCode: String
},
data() {
return {
tracks: []
}
},
async mounted() {
const res = await uni.request({
url: '/api/logistics',
data: {
no: this.expressNo,
code: this.expressCode
}
})
this.tracks = res.data.tracks.reverse()
}
}
</script>
4. 项目优化与踩坑记录
4.1 性能优化实践
- 分包加载:将商品详情、订单确认等非首屏页面放到子包中
json复制// pages.json
{
"subPackages": [
{
"root": "pages/subpackage",
"pages": [
{
"path": "goods/detail",
"style": { "navigationBarTitleText": "商品详情" }
}
]
}
]
}
-
图片优化:
- 使用WebP格式图片(体积比PNG小30%)
- 实现图片懒加载和渐进式加载
- 对商品列表图片使用CDN加速
-
数据缓存策略:
- 商品分类信息使用localStorage缓存
- 用户信息使用vuex持久化
- 购物车数据实时同步到服务端
4.2 常见问题解决方案
问题1:微信支付回调延迟
- 现象:用户支付成功后,订单状态没有实时更新
- 解决方案:
- 前端轮询查询订单状态(每5秒一次)
- 后端接收到微信通知后通过WebSocket推送
- 增加支付超时提醒(15分钟未支付自动取消)
问题2:iOS端rich-text渲染异常
- 现象:商品详情中的富文本在iOS设备上样式错乱
- 解决方案:
- 使用正则过滤掉不支持的HTML标签
- 将px单位转换为rpx
- 对图片添加最大宽度限制
问题3:物流信息更新不及时
- 解决方案:
- 后端定时任务每2小时同步一次物流数据
- 重要状态变更(如已签收)触发服务端推送
- 前端显示最后更新时间并提供手动刷新按钮
5. 项目部署与上线
5.1 小程序发布流程
- 开发环境构建:
bash复制npm run build:mp-weixin
-
使用微信开发者工具:
- 导入生成的
/dist/build/mp-weixin目录 - 配置合法域名
- 上传代码提交审核
- 导入生成的
-
审核注意事项:
- 确保所有功能都有完整的用户授权提示
- 支付功能必须提供测试账号
- 物流跟踪需要说明位置权限用途
5.2 后端API部署
采用Docker容器化部署方案:
dockerfile复制FROM node:14-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
部署命令:
bash复制docker build -t mall-api .
docker run -d -p 3000:3000 --name mall-api-prod mall-api
5.3 监控与统计
接入的监控方案:
- 前端错误监控:使用uni-app的onError全局捕获
- 接口性能监控:Nginx日志分析
- 业务数据统计:自定义埋点+uni统计
关键埋点示例:
javascript复制// 商品曝光埋点
const observer = uni.createIntersectionObserver(this)
observer.relativeToViewport()
observer.observe('.goods-item', (res) => {
if (res.intersectionRatio > 0) {
this.$track('goods_show', { id: res.dataset.id })
}
})
这个项目从技术选型到最终上线共耗时6周,期间最大的收获是深入理解了uni-app在复杂电商场景下的应用技巧。特别是对于状态管理和性能优化,我们总结出一套适合中小型电商项目的实践方案。如果开发类似项目,建议重点关注支付流程的健壮性和物流信息的实时性,这两个环节直接关系到用户体验。
