本课聚焦微信小程序实战开发,覆盖从环境搭建到项目上线前的全流程知识点。微信小程序作为主流轻应用,语法贴合前端基础,上手难度低,传播和使用场景广泛。课程从项目结构、配置文件、页面语法,到网络请求、缓存、路由传参,用单词小程序案例贯穿全程,拆解开发细节与避坑要点。学习本课不仅能掌握小程序独立开发能力,更能理解平台规则与用户体验优化逻辑,适配企业轻量化产品开发需求。小程序项目体量小、开发周期短,是前端开发者必备的实战技能,掌握本课内容,可独立完成各类轻量化小程序开发,拓宽就业与实战方向。
一、课程学习目的
-
掌握微信小程序的开发流程、环境搭建,熟悉小程序官方开发工具。
-
理解小程序的项目结构、配置文件、页面组成,分清页面与全局逻辑。
-
熟练运用小程序基础语法、数据绑定、事件处理、列表渲染。
-
学会小程序网络请求、本地缓存、页面跳转与参数传递。
-
规避小程序开发常见坑,适配小程序平台规范。
-
独立开发完整小程序项目,实现从搭建到运行的全流程,贴合上线标准。
二、核心知识点讲解
1. 微信小程序基础认知
微信小程序是依附于微信平台的轻应用,无需下载安装,扫码即可打开,占用资源少、传播便捷,是移动端常用的产品形态。
开发门槛低,语法贴近前端三件套,配合官方开发者工具,上手速度快,适合快速落地业务、搭建轻量化工具。小程序有严格的权限管控、域名限制,开发前需完成账号注册与配置。
2. 开发环境与工具
开发必备工具:微信开发者工具(官方专属编辑器,集编写、调试、预览、发布于一体)。
前期准备:注册微信小程序账号、获取AppID、配置服务器域名、下载安装开发者工具,无AppID可使用测试号进行本地开发。
3. 小程序项目结构
小程序项目由全局配置、页面文件、静态资源组成,每个页面独立成文件夹,遵循固定命名规范。
-
app.json:全局配置文件,配置页面路由、导航栏、底部TabBar、网络域名等。
-
app.js:全局入口文件,存放全局生命周期、全局数据。
-
app.wxss:全局样式文件,作用于所有页面。
-
pages:页面文件夹,每个页面包含wxml、wxss、js、json四个文件。
-
utils:工具函数文件夹,存放封装的请求、工具方法。
4. 页面文件组成
每个小程序页面由四个文件构成,分工明确,缺一不可。
-
.wxml:结构文件,类似HTML,专用小程序组件,禁止使用HTML原生标签。
-
.wxss:样式文件,类似CSS,支持rpx响应式单位,适配移动端屏幕。
-
.js:逻辑文件,处理数据、事件、请求、生命周期、路由。
-
.json:页面配置文件,单独配置当前页面导航栏、标题。
5. 小程序核心语法
数据绑定:使用双大括号{{}}包裹变量,实现数据与视图联动。
列表渲染:使用wx:for指令循环渲染列表,必须搭配wx:key保证渲染稳定。
事件绑定:使用bind+事件名绑定点击、输入等交互,如bindtap、bindinput。
页面生命周期:onLoad(页面加载)、onShow(页面显示)、onReady(渲染完成)、onUnload(页面卸载)。
6. 小程序网络与缓存
网络请求:使用wx.request发起请求,必须配置合法域名,不支持本地localhost请求(测试可关闭域名校验)。
本地缓存:使用wx.setStorageSync、wx.getStorageSync实现数据持久化存储,用法与uni-app一致。
7. 小程序路由跳转
wx.navigateTo:保留当前页面,跳转到新页面,支持返回。
wx.switchTab:跳转到TabBar页面,关闭其他非TabBar页面。
wx.navigateBack:返回上一级或多级页面。
三、示例程序
示例1:app.json全局配置
json
{
"pages": [
"pages/index/index",
"pages/list/list",
"pages/detail/detail"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#42b983",
"navigationBarTitleText": "单词小程序",
"navigationBarTextStyle": "white"
},
"tabBar": {
"color": "#666",
"selectedColor": "#42b983",
"list": [
{
"pagePath": "pages/index/index",
"text": "首页"
},
{
"pagePath": "pages/list/list",
"text": "单词列表"
}
]
},
"sitemapLocation": "sitemap.json"
}
示例2:列表页面wxml结构
xml
<!-- pages/list/list.wxml -->
<view class="container">
<!-- 加载提示 -->
<view wx:if="{{loading}}" class="tip">加载中...</view>
<!-- 单词列表 -->
<view
wx:for="{{wordList}}"
wx:key="id"
class="item"
bindtap="goDetail"
data-id="{{item.id}}"
data-en="{{item.en}}"
data-cn="{{item.cn}}"
>
<text>{{item.en}} - {{item.cn}}</text>
</view>
<!-- 空数据提示 -->
<view wx:elif="{{wordList.length === 0}}" class="tip">暂无单词数据</view>
</view>
示例3:列表页面js逻辑
javascript
// pages/list/list.js
Page({
// 页面数据
data: {
wordList: [],
loading: false
},
// 页面加载时触发
onLoad() {
this.getWordList()
},
// 获取单词列表
getWordList() {
this.setData({ loading: true })
// 发起网络请求
wx.request({
url: 'https://xxx/api/word/list',
method: 'GET',
success: (res) => {
if (res.statusCode === 200) {
this.setData({
wordList: res.data.data
})
// 缓存数据
wx.setStorageSync('wordList', res.data.data)
}
},
fail: () => {
// 读取缓存
const cache = wx.getStorageSync('wordList')
if (cache) this.setData({ wordList: cache })
wx.showToast({ title: '网络异常', icon: 'none' })
},
complete: () => {
this.setData({ loading: false })
}
})
},
// 跳转到详情页
goDetail(e) {
const { id, en, cn } = e.currentTarget.dataset
wx.navigateTo({
url: `/pages/detail/detail?id=${id}&en=${en}&cn=${cn}`
})
}
})
示例4:详情页面接收参数
javascript
// pages/detail/detail.js
Page({
data: {
word: {}
},
// 接收路由参数
onLoad(options) {
this.setData({
word: options
})
},
// 返回上一页
goBack() {
wx.navigateBack()
}
})
四、掌握技巧与方法
-
开发前配置好合法域名,测试阶段可在开发者工具中关闭域名校验。
-
数据更新必须使用setData,直接修改data数据无法触发视图刷新。
-
列表渲染必须配置wx:key,推荐用唯一id,不建议使用index。
-
样式优先使用rpx单位,实现移动端自适应,适配不同机型。
-
网络请求失败时,读取本地缓存,提升用户体验,避免空白页面。
-
页面跳转传参,通过data-*属性传递数据,在事件对象中获取。
-
全局配置app.json中,pages数组第一项为默认首页。
-
调试使用开发者工具控制台,查看请求、缓存、报错信息。
五、课后作业
基础作业
-
安装微信开发者工具,使用测试号创建空白小程序项目。
-
配置app.json,注册首页、列表页、详情页,设置导航栏样式。
-
编写页面结构,完成数据绑定、列表渲染基础效果。
进阶作业
-
使用wx.request请求单词数据,渲染到页面,处理加载与异常状态。
-
实现页面跳转与参数传递,详情页接收并展示数据。
-
配合本地缓存,实现离线展示数据功能。
实战作业
- 开发完整单词学习小程序,包含首页、单词列表页、单词详情页,配置底部TabBar,实现网络请求数据、缓存存储、页面跳转、参数接收功能,处理加载、空数据、异常状态,符合微信小程序开发规范,可正常预览运行。
上一课 实战作业代码 答案:uni-app 网络请求与数据缓存
完整实战代码
项目结构
Plain
uni-app-request-word/
├── pages/
│ └── index/
│ └── index.vue
├── utils/
│ └── request.js
├── App.vue
├── main.js
└── pages.json
pages.json配置
json
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "单词列表"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "white",
"navigationBarBackgroundColor": "#42b983",
"backgroundColor": "#f5f5f5"
}
}
utils/request.js(封装请求)
javascript
// 基础请求地址(替换为自己的后端接口)
const baseUrl = 'http://localhost:3000'
// 封装统一请求
const request = (options) => {
// 开启加载提示
uni.showLoading({
title: '加载中...',
mask: true
})
return new Promise((resolve, reject) => {
uni.request({
url: baseUrl + options.url,
method: options.method || 'GET',
data: options.data || {},
header: {
'Content-Type': 'application/json'
},
success: (res) => {
if (res.statusCode === 200) {
resolve(res.data)
} else {
uni.showToast({
title: '请求失败',
icon: 'none'
})
reject(res)
}
},
fail: (err) => {
uni.showToast({
title: '网络异常',
icon: 'none'
})
reject(err)
},
complete: () => {
// 关闭加载提示
uni.hideLoading()
}
})
})
}
// 导出GET方法
export const get = (url, data) => {
return request({ url, method: 'GET', data })
}
// 导出POST方法
export const post = (url, data) => {
return request({ url, method: 'POST', data })
}
pages/index/index.vue(主页面)
vue
<template>
<view class="container">
<!-- 加载状态 -->
<view class="tip" v-if="loading">正在加载单词数据...</view>
<!-- 单词列表 -->
<view class="list" v-else>
<view class="item" v-for="item in wordList" :key="item.id">
<text class="en">{{ item.en }}</text>
<text class="cn">{{ item.cn }}</text>
</view>
<view class="tip" v-if="wordList.length === 0">暂无单词数据</view>
</view>
<!-- 刷新按钮 -->
<button class="refresh-btn" @click="getWordList" :disabled="loading">刷新数据</button>
</view>
</template>
<script setup>
import { ref, onLoad } from 'vue'
import { get } from '../../utils/request'
// 响应式数据
const wordList = ref([])
const loading = ref(false)
// 页面加载触发
onLoad(() => {
initPage()
})
// 初始化:先读缓存,再请求
const initPage = () => {
// 读取本地缓存
const cacheData = uni.getStorageSync('wordList')
if (cacheData) {
wordList.value = cacheData
}
// 请求最新数据
getWordList()
}
// 获取单词列表
const getWordList = async () => {
loading.value = true
try {
const res = await get('/api/word/list')
wordList.value = res.data || []
// 缓存最新数据
uni.setStorageSync('wordList', wordList.value)
} catch (err) {
console.log('获取数据失败', err)
} finally {
loading.value = false
}
}
</script>
<style scoped>
.container {
padding: 30rpx;
}
.tip {
text-align: center;
color: #666;
padding: 40rpx 0;
font-size: 28rpx;
}
.list {
margin-bottom: 30rpx;
}
.item {
background-color: #fff;
padding: 30rpx;
border-radius: 12rpx;
margin-bottom: 20rpx;
display: flex;
justify-content: space-between;
}
.en {
font-size: 32rpx;
color: #333;
font-weight: 500;
}
.cn {
font-size: 28rpx;
color: #666;
}
.refresh-btn {
margin-top: 20rpx;
}
</style>
App.vue(全局配置)
vue
<script>
export default {
onLaunch: function () {
console.log('App启动')
}
}
</script>
<style>
/* 全局样式 */
page {
background-color: #f5f5f5;
}
</style>
main.js(入口文件)
javascript
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
return { app }
}
运行方式
-
使用HBuilderX打开项目,安装所需依赖。
-
启动后端接口服务,修改request.js中的baseUrl为正确地址。
-
点击运行,选择运行到浏览器或微信小程序。
-
测试加载、缓存、刷新、异常处理功能。
代码功能说明
本实战作业基于uni-app Vue3语法开发单词列表页面,主打网络请求与缓存两大核心功能。项目封装了统一请求工具,统一配置基础域名、请求头、加载提示和异常处理,支持GET请求;页面加载时先读取本地缓存数据,快速展示内容,再发起网络请求更新数据和缓存,提升加载体验。页面包含加载状态、空数据提示、异常提示,适配H5和微信小程序端,数据渲染流畅。代码实现了接口对接、缓存读写、状态管理全套逻辑,完整贴合课程知识点,巩固uni-app网络交互与本地存储技能。
注意事项
-
H5端运行需开启后端跨域,小程序端需配置request合法域名。
-
网络请求为异步操作,推荐使用async/await简化代码逻辑。
-
数据更新需用响应式赋值,保证视图正常刷新。
-
缓存键名保持语义化,避免和其他项目缓存冲突。
-
调试时关闭浏览器缓存,防止接口数据不更新。
-
请求加载期间,禁止重复点击、重复发起请求。
-
项目路径禁止出现中文、空格和特殊字符,防止编译报错。
-
修改工具文件后,需重新编译项目,确保配置生效。
作业验收标准
-
项目正常编译运行,无控制台报错。
-
请求接口成功,正常渲染单词列表,加载提示流畅。
-
网络异常时,能正常读取缓存数据展示。
-
刷新按钮可重新请求并更新缓存。
-
适配H5和微信小程序,无兼容性问题。
-
代码规范,注释清晰,请求封装合理。