引言
小程序已成为移动互联网生态中不可或缺的一部分。作为前端开发者,掌握小程序开发技能能够极大扩展我们的技术边界。本文将深入探讨微信小程序原生开发和跨平台框架 uni-app 的使用,帮助你快速上手小程序开发。
一、微信小程序开发基础
1.1 项目结构
微信小程序采用独特的文件组织方式:
project/
├── app.js # 全局逻辑
├── app.json # 全局配置
├── app.wxss # 全局样式
├── pages/ # 页面目录
│ ├── index/
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
├── components/ # 自定义组件
└── utils/ # 工具函数
1.2 核心 API 示例
页面跳转与传参:
// pages/index/index.js
Page({
// 跳转到详情页并传参
goToDetail() {
wx.navigateTo({
url: '/pages/detail/detail?id=123&name=商品'
});
},
// 接收参数
onLoad(options) {
console.log(options.id); // 123
console.log(options.name); // 商品
}
});
// 详情页接收
Page({
onLoad(options) {
this.setData({
productId: options.id,
productName: options.name
});
}
});
数据请求与状态管理:
Page({
data: {
productList: [],
loading: false
},
async fetchProducts() {
this.setData({ loading: true });
try {
const res = await wx.request({
url: 'https://api.example.com/products',
method: 'GET',
header: {
'Authorization': `Bearer ${wx.getStorageSync('token')}`
}
});
this.setData({
productList: res.data.data,
loading: false
});
} catch (error) {
wx.showToast({
title: '加载失败',
icon: 'none'
});
}
}
});
1.3 组件化开发
创建自定义组件:
// components/product-card/product-card.js
Component({
properties: {
product: {
type: Object,
value: {}
},
showFavorite: {
type: Boolean,
value: true
}
},
data: {
isFavorite: false
},
methods: {
onFavorite() {
this.setData({ isFavorite: !this.data.isFavorite });
this.triggerEvent('favorite', {
productId: this.data.product.id,
isFavorite: !this.data.isFavorite
});
},
onBuy() {
this.triggerEvent('buy', {
productId: this.data.product.id
});
}
}
});
使用组件:
<!-- pages/index/index.wxml -->
<view class="product-list">
<block wx:for="{{productList}}" wx:key="id">
<product-card
product="{{item}}"
show-favorite="{{true}}"
bind:favorite="onFavorite"
bind:buy="onBuy"
/>
</block>
</view>
二、uni-app 跨平台开发
2.1 为什么选择 uni-app
uni-app 基于 Vue.js,一套代码可编译到:
- 微信小程序
- 支付宝小程序
- H5
- App (iOS/Android)
- 字节小程序
- 百度小程序
2.2 项目初始化
# 使用 Vue CLI 创建
vue create -p dcloudio/uni-preset-v3 my-app
# 或使用 HBuilderX 创建(推荐)
# 下载 HBuilderX → 创建 uni-app 项目
2.3 核心代码示例
页面开发:
<!-- pages/index/index.vue -->
<template>
<view class="container">
<view class="header">
<text class="title">{{ pageTitle }}</text>
</view>
<view class="product-list">
<view
v-for="(item, index) in productList"
:key="item.id"
class="product-item"
@click="goToDetail(item.id)"
>
<image :src="item.image" mode="aspectFill" />
<view class="info">
<text class="name">{{ item.name }}</text>
<text class="price">¥{{ item.price }}</text>
</view>
</view>
</view>
<!-- 下拉刷新 -->
<uni-load-more :status="loadStatus" />
</view>
</template>
<script>
export default {
data() {
return {
pageTitle: '商品列表',
productList: [],
page: 1,
loadStatus: 'loading'
};
},
onPullDownRefresh() {
this.loadProducts(true);
},
onReachBottom() {
this.loadProducts(false);
},
methods: {
async loadProducts(isRefresh = false) {
if (isRefresh) {
this.page = 1;
} else if (this.loadStatus === 'noMore') {
return;
}
try {
const res = await uni.request({
url: 'https://api.example.com/products',
method: 'GET',
data: { page: this.page, pageSize: 20 }
});
const newProducts = res.data.data;
this.productList = isRefresh
? newProducts
: [...this.productList, ...newProducts];
this.loadStatus = newProducts.length < 20 ? 'noMore' : 'loading';
} finally {
if (isRefresh) {
uni.stopPullDownRefresh();
}
}
},
goToDetail(id) {
uni.navigateTo({
url: `/pages/detail/detail?id=${id}`
});
}
},
onLoad() {
this.loadProducts();
}
};
</script>
<style>
.container {
padding: 20rpx;
}
.product-item {
background: #fff;
border-radius: 16rpx;
margin-bottom: 20rpx;
overflow: hidden;
}
.image {
width: 100%;
height: 400rpx;
}
.info {
padding: 20rpx;
}
.name {
font-size: 32rpx;
display: block;
margin-bottom: 10rpx;
}
.price {
color: #ff6700;
font-size: 36rpx;
font-weight: bold;
}
</style>
条件编译实现平台适配:
// 平台特定的代码
if (uni.getSystemInfoSync().platform === 'ios') {
// iOS 特定逻辑
console.log('iOS 设备');
}
// 条件编译 - uni-app 特有语法
#ifdef H5
// 仅 H5 平台执行
window.location.href = '/login';
#endif
#ifdef MP-WEIXIN
// 仅微信小程序执行
wx.login({
success: res => {
// 获取微信登录凭证
}
});
#endif
2.4 状态管理(Pinia)
// stores/product.js
import { defineStore } from 'pinia';
export const useProductStore = defineStore('product', {
state: () => ({
productList: [],
favoriteList: []
}),
getters: {
totalProducts: (state) => state.productList.length,
favoriteCount: (state) => state.favoriteList.length
},
actions: {
addProduct(product) {
this.productList.push(product);
},
toggleFavorite(productId) {
const index = this.favoriteList.indexOf(productId);
if (index > -1) {
this.favoriteList.splice(index, 1);
} else {
this.favoriteList.push(productId);
}
}
}
});
三、性能优化技巧
3.1 图片优化
// 图片压缩与懒加载
const optimizeImage = (url) => {
// 微信小程序:压缩图片
if (uni.getSystemInfoSync().platform === 'wechat') {
return url + '?imageView2/1/w/300/q/80';
}
return url;
};
// 懒加载
<image
:src="item.image"
lazy-load
mode="aspectFill"
@error="handleImageError"
/>
3.2 列表优化
// 虚拟列表(uni-app)
<uni-virtual-list
:list="productList"
:height="600"
:itemHeight="150"
@scroll="onScroll"
>
<template #default="{ item }">
<product-card :product="item" />
</template>
</uni-virtual-list>
四、常见问题与解决方案
4.1 登录鉴权
// 微信小程序登录流程
async wxLogin() {
// 1. 获取 code
const { code } = await wx.login();
// 2. 发送到后端换取 openid 和 session_key
const res = await uni.request({
url: 'https://api.example.com/auth/wechat',
method: 'POST',
data: { code }
});
// 3. 存储 token
uni.setStorageSync('token', res.data.token);
uni.setStorageSync('userInfo', res.data.userInfo);
}
4.2 支付集成
// 微信支付
async handlePay() {
// 1. 创建订单
const orderRes = await uni.request({
url: 'https://api.example.com/order/create',
method: 'POST',
data: { products: this.cartList }
});
// 2. 调起支付
#ifdef MP-WEIXIN
wx.requestPayment({
timeStamp: orderRes.data.timeStamp,
nonceStr: orderRes.data.nonceStr,
package: orderRes.data.package,
signType: orderRes.data.signType,
paySign: orderRes.data.paySign,
success: () => {
uni.showToast({ title: '支付成功' });
},
fail: (err) => {
uni.showToast({ title: '支付失败', icon: 'none' });
}
});
#endif
}
总结
小程序开发已经成为前端工程师的必备技能。微信小程序原生开发适合深度利用微信生态的场景,而 uni-app 则提供了跨平台开发的便利。
关键要点:
- 掌握小程序的组件化开发模式
- 理解平台差异,善用条件编译
- 重视性能优化,特别是图片和列表
- 熟悉登录、支付等核心功能实现
选择适合你项目的方案,开始你的小程序开发之旅吧!