当前位置: 首页 > news >正文

JavaScript基础课程三十、微信小程序实战

本课聚焦微信小程序实战开发,覆盖从环境搭建到项目上线前的全流程知识点。微信小程序作为主流轻应用,语法贴合前端基础,上手难度低,传播和使用场景广泛。课程从项目结构、配置文件、页面语法,到网络请求、缓存、路由传参,用单词小程序案例贯穿全程,拆解开发细节与避坑要点。学习本课不仅能掌握小程序独立开发能力,更能理解平台规则与用户体验优化逻辑,适配企业轻量化产品开发需求。小程序项目体量小、开发周期短,是前端开发者必备的实战技能,掌握本课内容,可独立完成各类轻量化小程序开发,拓宽就业与实战方向。

一、课程学习目的

  1. 掌握微信小程序的开发流程、环境搭建,熟悉小程序官方开发工具。

  2. 理解小程序的项目结构、配置文件、页面组成,分清页面与全局逻辑。

  3. 熟练运用小程序基础语法、数据绑定、事件处理、列表渲染。

  4. 学会小程序网络请求、本地缓存、页面跳转与参数传递。

  5. 规避小程序开发常见坑,适配小程序平台规范。

  6. 独立开发完整小程序项目,实现从搭建到运行的全流程,贴合上线标准。

二、核心知识点讲解

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全局配置

{"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结构

<!-- pages/list/list.wxml --><viewclass="container"><!-- 加载提示 --><viewwx:if="{{loading}}"class="tip">加载中...</view><!-- 单词列表 --><viewwx: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><!-- 空数据提示 --><viewwx:elif="{{wordList.length === 0}}"class="tip">暂无单词数据</view></view>

示例3:列表页面js逻辑

// pages/list/list.jsPage({// 页面数据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:()=>{// 读取缓存constcache=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:详情页面接收参数

// pages/detail/detail.jsPage({data:{word:{}},// 接收路由参数onLoad(options){this.setData({word:options})},// 返回上一页goBack(){wx.navigateBack()}})

四、掌握技巧与方法

  1. 开发前配置好合法域名,测试阶段可在开发者工具中关闭域名校验。

  2. 数据更新必须使用setData,直接修改data数据无法触发视图刷新。

  3. 列表渲染必须配置wx:key,推荐用唯一id,不建议使用index。

  4. 样式优先使用rpx单位,实现移动端自适应,适配不同机型。

  5. 网络请求失败时,读取本地缓存,提升用户体验,避免空白页面。

  6. 页面跳转传参,通过data-*属性传递数据,在事件对象中获取。

  7. 全局配置app.json中,pages数组第一项为默认首页。

  8. 调试使用开发者工具控制台,查看请求、缓存、报错信息。

五、课后作业

基础作业

  1. 安装微信开发者工具,使用测试号创建空白小程序项目。

  2. 配置app.json,注册首页、列表页、详情页,设置导航栏样式。

  3. 编写页面结构,完成数据绑定、列表渲染基础效果。

进阶作业

  1. 使用wx.request请求单词数据,渲染到页面,处理加载与异常状态。

  2. 实现页面跳转与参数传递,详情页接收并展示数据。

  3. 配合本地缓存,实现离线展示数据功能。

实战作业

  1. 开发完整单词学习小程序,包含首页、单词列表页、单词详情页,配置底部TabBar,实现网络请求数据、缓存存储、页面跳转、参数接收功能,处理加载、空数据、异常状态,符合微信小程序开发规范,可正常预览运行。

上一课 实战作业代码 答案:uni-app 网络请求与数据缓存

完整实战代码

项目结构

uni-app-request-word/ ├── pages/ │ └── index/ │ └── index.vue ├── utils/ │ └── request.js ├── App.vue ├── main.js └── pages.json

pages.json配置

{"pages":[{"path":"pages/index/index","style":{"navigationBarTitleText":"单词列表"}}],"globalStyle":{"navigationBarTextStyle":"white","navigationBarBackgroundColor":"#42b983","backgroundColor":"#f5f5f5"}}

utils/request.js(封装请求)

// 基础请求地址(替换为自己的后端接口)constbaseUrl='http://localhost:3000'// 封装统一请求constrequest=(options)=>{// 开启加载提示uni.showLoading({title:'加载中...',mask:true})returnnewPromise((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方法exportconstget=(url,data)=>{returnrequest({url,method:'GET',data})}// 导出POST方法exportconstpost=(url,data)=>{returnrequest({url,method:'POST',data})}

pages/index/index.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(全局配置)

<script> export default { onLaunch: function () { console.log('App启动') } } </script> <style> /* 全局样式 */ page { background-color: #f5f5f5; } </style>

main.js(入口文件)

import{createSSRApp}from'vue'exportfunctioncreateApp(){constapp=createSSRApp(App)return{app}}

运行方式

  1. 使用HBuilderX打开项目,安装所需依赖。

  2. 启动后端接口服务,修改request.js中的baseUrl为正确地址。

  3. 点击运行,选择运行到浏览器或微信小程序。

  4. 测试加载、缓存、刷新、异常处理功能。

代码功能说明

本实战作业基于uni-app Vue3语法开发单词列表页面,主打网络请求与缓存两大核心功能。项目封装了统一请求工具,统一配置基础域名、请求头、加载提示和异常处理,支持GET请求;页面加载时先读取本地缓存数据,快速展示内容,再发起网络请求更新数据和缓存,提升加载体验。页面包含加载状态、空数据提示、异常提示,适配H5和微信小程序端,数据渲染流畅。代码实现了接口对接、缓存读写、状态管理全套逻辑,完整贴合课程知识点,巩固uni-app网络交互与本地存储技能。

注意事项

  • H5端运行需开启后端跨域,小程序端需配置request合法域名。

  • 网络请求为异步操作,推荐使用async/await简化代码逻辑。

  • 数据更新需用响应式赋值,保证视图正常刷新。

  • 缓存键名保持语义化,避免和其他项目缓存冲突。

  • 调试时关闭浏览器缓存,防止接口数据不更新。

  • 请求加载期间,禁止重复点击、重复发起请求。

  • 项目路径禁止出现中文、空格和特殊字符,防止编译报错。

  • 修改工具文件后,需重新编译项目,确保配置生效。

作业验收标准

  1. 项目正常编译运行,无控制台报错。

  2. 请求接口成功,正常渲染单词列表,加载提示流畅。

  3. 网络异常时,能正常读取缓存数据展示。

  4. 刷新按钮可重新请求并更新缓存。

  5. 适配H5和微信小程序,无兼容性问题。

  6. 代码规范,注释清晰,请求封装合理。

http://www.cnnetsun.cn/news/1537490.html

相关文章:

  • springboot-vue+nodejs的药膳食谱管理系统
  • FreeSWITCH外线对接避坑指南:IAD网关配置中5个必改的安全参数
  • 别再手动建模了!用C++和Gmsh自动导入STEP文件并生成六面体网格(附完整代码)
  • 3分钟免费获取股票数据:Python通达信接口终极指南
  • 【01】总目录——软件设计师50讲通关地图|从零基础到工程师职称
  • Qwen3-ASR-1.7B实战教程:curl命令行调用API实现无人值守识别任务
  • CI实战:一键配置npm仓库认证的authToken秘笈
  • MPC控制进阶:手把手教你用TCM网络提升预测精度(基于PyTorch实现)
  • 移动端也能跑!实测PaddleOCR PP-OCRv4_mobile_seal_det模型,在安卓上部署印章检测App
  • Swagger-MCP-Server:基于OpenAPI标准,让大模型成为你的API调用与测试专家
  • ROS2 Humble中rosbridge_server配置详解:从安装、启动到自定义端口的完整流程
  • 数字可调电源-1. TL494经典开关电源工作原理
  • 宝塔面板+Spring Boot部署脚本翻车实录:我踩过的5个坑与优化方案
  • YOLO-V8.3镜像部署实战:安全设置一步到位,快速上手物体检测
  • 终极指南:如何用BongoCat桌面虚拟助手提升你的电脑使用体验
  • JavaScript DXF Writer:革命性的一站式浏览器端CAD图纸生成方案
  • 告别终端黑框:在VSCode里优雅地调试和运行Fortran代码(macOS+gfortran实战)
  • CH347的JTAG速率怎么选?实测openFPGALoader下载FPGA到Flash的稳定性与速度权衡
  • SpringBoot启动任务实战:ApplicationRunner与CommandLineRunner深度解析
  • 从SEN1-2到DroneVehicle:手把手教你用Python搞定遥感数据集的下载与预处理
  • cv_resnet18_ocr-detection新手入门:3步完成图片文字识别
  • 大语言模型+进化算法:LLM-LNS如何解决传统MILP优化难题?
  • 北斗网格位置码实战:从编码原理到Java实现(非极地)
  • 2022年中国90米人口密度栅格数据(LandScan)|高精度、单年快照、科研级空间人口产品
  • 从.pro到.vcxproj:深入理解Qt项目在不同IDE间转换的底层逻辑与配置差异
  • 为什么你的Adobe PR导出序列帧这么慢?优化技巧大揭秘
  • 如何快速配置Screencast Keys:面向高级用户的完整优化指南
  • 禅道企业微信消息推送改造实战:如何让群消息自动@指定成员(附源码修改)
  • 【技术解析】Partial Convolutions在图像修复中的创新应用:突破不规则孔洞限制
  • 别再手动校验IP了!用ip2region v3.x + Java做个精准的IP归属地服务(实战代码分享)