ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

vue+uniapp+Python实战:从零搭建微信小程序英语学习平台

vue+uniapp+Python实战:从零搭建微信小程序英语学习平台 如果你也在琢磨做一个英语学习类的小程序或者正被毕业设计卡在技术选型上我可以先给个结论vue uniapp Python这套组合做微信小程序英语学习平台是目前投入产出比最高的路线之一。uniapp用vue语法开发一套代码能编译到微信小程序、H5和App端前端不用为三端各写一套Python后端出接口快Flask几百行就能把核心业务跑起来微信小程序本身又有天然的分发优势学英语这类高频工具型场景特别适合。这篇文章就把项目从技术选型、功能拆解、环境搭建、前后端联调到上线发布踩过的坑全流程捋一遍。代码和配置都是可以直接抄的只要你按步骤走本地就能把整套东西跑出来。1. 项目设计与技术选型思路1.1 为什么锁定uniapp vue这套前端组合先说uniapp最核心的价值跨端复用。英语学习平台这种项目如果只做微信小程序后面用户想在浏览器里打开或者想上架成独立App原生小程序代码就要推倒重来。uniapp用vue语法开发底层编译到不同平台一套业务代码三端跑光是这一点就能省掉后期大量的重复工作。再拉出来和原生微信小程序对比一下差异更清楚维度原生微信小程序uniapp vue语法体系WXML WXSS JS自成一派vue单文件组件生态成熟跨端能力仅微信小程序小程序、H5、App三端组件复用组件机制较原始vue组件化、easycom组件规范热更新体验一般vite构建开发热更新很快团队上手需要额外学一套会vue就能直接干活这个项目里我选的是vue3版本配合vite构建开发时热更新速度比vue2 webpack快不少。如果你图稳妥想用vue2uniapp也完全支持但新项目建议直接上vue3官方长期维护的方向就在这边。1.2 Python后端轻量优先的Flask方案后端用Python具体选了Flask而不是Django理由很直接项目阶段要的是快速交付和灵活控制。Django自带ORM、Admin后台、认证体系功能全但对这类中小型项目来说大量用不上模板和配置反而占用心智。Flask只有核心路由和请求处理其余按需引入一个app.py就能把服务跑起来控制力很强。数据库层加上SQLAlchemyORM能力一点不比Django的弱整体却清爽很多。接口风格从一开始就统一成RESTful JSON。前端按/api/user/login、/api/words/daily、/api/study/record这种路径调用前后端完全解耦。后期如果用户量上来Flask加gunicorn部署或者把接口平滑迁移改造成本都可控。1.3 整体架构与数据流转整个平台的请求链路是这样的uniapp前端 → uni.request封装 → Flask REST API → SQLAlchemy → MySQL/SQLite → 返回JSON → 前端渲染并缓存数据库设计上我按业务拆分最小表集合用户表、单词表、课程表、学习记录表。核心是做英语学习闭环所以表设计上让用户-单词-学习状态的关系尽量简单避免复杂的多表关联。本地开发用SQLite零配置启动部署到服务器再切换到MySQL整个切换动作在SQLAlchemy里只需要改一行连接串。这样的架构带来的直接好处是前端同学可以专注页面交互后端同学专注接口逻辑两边只要把接口文档定好并行开发完全不冲突。我自己一个人开发时也按这个方式组织各个模块边界清晰后期改bug快很多。2. 英语学习平台的功能拆解与前端落地2.1 主要功能模块与页面规划英语学习平台这类产品功能再多也不如把一条学习链路做透。我用四个标签页组织前端页面首页今日学习概览、打卡入口、推荐课程单词每日单词卡、生词本、词汇测验课程听力训练和视频课程列表支持m3u8格式播放我的个人数据、学习日历、设置这几个模块的划分逻辑很简单用户进小程序第一眼看到的是今天要做什么首页然后进入核心学习动作单词、课程最后在我的里看到自己的学习成果形成正向激励闭环。工具类小程序最忌讳把功能平铺乱放用户进来不知道点哪里留存一定差。2.2 vue语法在页面中的实际应用整个前端页面大量用到vue3组合式API。以单词卡组件为例核心逻辑大概是用ref维护当前单词索引computed计算学习进度百分比v-for渲染释义选项点击选项后更新状态并调用后端打卡接口。相比原生小程序的setDatavue的响应式机制写起来顺手得多页面状态和数据流也清晰。代码结构大致长这样script setup import { ref, computed } from vue const currentIndex ref(0) const answers ref([]) const wordList computed(() props.words) const progress computed(() (currentIndex.value / wordList.value.length) * 100) /script路由这块uniapp的pages.json是页面管理配置虽然和vue-router长得不一样但本质都是页面路由表。navigationBarTitleText统一设置页面标题tabBar配置四个底部导航入口。如果项目里要做H5版本vue-router也能用只是小程序端仍然以pages.json为准。组件复用方面我把单词卡、题组、课程卡片都抽成了独立组件。比如单词卡在首页和单词页都要出现组件本身管理自己内部的状态和交互父页面只需要传入单词数据。这套组件的组织方式做出来之后越到后期越省力。2.3 登录授权与缓存策略微信小程序的登录逻辑我一开始就确定了静默登录为主、手机号授权为辅助的方案进入小程序先调uni.login拿到code传给后端换openid自动创建用户并保存登录态需要用手机号做账号体系打通时再引导用户点getPhoneNumber按钮走手机号快速验证组件授权登录态和用户资料通过uni.setStorageSync缓存到本地启动时优先读缓存减少重复请求。这个思路避免了一进入就弹授权框的高流失设计。很多小程序上来就强制授权用户连功能都没看到就关掉了这对工具类产品是致命的。静默登录保证用户体验顺畅等用户真正需要用到手机号能力时再授权转化率会高很多。3. 实操全过程环境配置、项目搭建与联调3.1 开发环境准备按我实际搭建的顺序把关键环境和版本列一下Node.js建议装LTS版本v18或v20vite项目对node版本有最低要求老版本直接编译失败包管理器npm即可国内网络下npm install慢的话把registry配置到国内源就行微信开发者工具下载稳定版注册小程序账号拿到AppID个人主体也能用测试号跑通全流程Python3.8到3.11都行建议3.10左右pip安装Flask、flask-cors、SQLAlchemy数据库本地开发用SQLite零配置部署时切换MySQL。安装Python依赖时如果慢同样把pip源配置到国内镜像这是常规操作。环境这块最需要注意的是版本统一团队协作时最好写一个requirements.txt和package.json锁住版本避免我本地能跑你那边报错这种经典问题。3.2 创建支持TypeScript的uniapp项目创建项目我用的是官方预设模板命令行方式执行npx degit dcloudio/uni-preset-vue#vite-ts english-app cd english-app npm install npm run dev:mp-weixin执行完最后一条命令后项目会编译到dist/dev/mp-weixin目录用微信开发者工具导入这个目录就能看到小程序页面。如果你用HBuilderX图形化操作也能达到同样效果但命令行方式更利于版本管理和团队协作git记录也更干净。这里有一个高频坑项目创建后经常报failed to load tsconfig vue/tsconfig/tsconfig.web.json: tsconfig not found原因就是依赖没装全或者tsconfig.json引用的路径有问题。处理办法很直接npm i -D vue/tsconfig然后检查项目根目录tsconfig.json的extends路径是否指向vue/tsconfig/tsconfig.web.json依赖装完后重启dev命令问题基本就消失了。TypeScript带来的类型提示在写接口请求参数和页面数据时非常有用强烈建议保留。3.3 Python后端接口开发后端用Flask组织了一个精简的分层结构english-server/ ├── app.py ├── models.py ├── api/ │ ├── __init__.py │ ├── user.py │ ├── word.py │ └── study.py ├── requirements.txt └── english.db以用户登录接口为例核心代码逻辑是接收前端传回的wx.login code调用微信接口换openid本地开发用模拟方式查询用户表里有没有这个人没有就自动注册最后返回userId和token。# app.py 核心片段 from flask import Flask, request, jsonify from flask_cors import CORS from models import db, User app Flask(__name__) CORS(app) app.config[SQLALCHEMY_DATABASE_URI] sqlite:///english.db db.init_app(app) app.route(/api/user/login, methods[POST]) def login(): code request.get_json().get(code) # 真实环境用code换openid本地模拟直接生成 openid openid_ code[-6:] user User.query.filter_by(openidopenid).first() if not user: user User(openidopenid) db.session.add(user) db.session.commit() return jsonify({code: 0, data: {userId: user.id, token: tk_ str(user.id)}})数据库三张核心表用户表保存openid和昵称单词表保存每日单词、释义、音标、例句学习记录表保存用户和单词的关系以及掌握状态。用SQLAlchemy定义模型后建表只要几行代码class User(db.Model): id db.Column(db.Integer, primary_keyTrue) openid db.Column(db.String(64), uniqueTrue) nickname db.Column(db.String(64)) class Word(db.Model): id db.Column(db.Integer, primary_keyTrue) word db.Column(db.String(64)) meaning db.Column(db.String(128)) phonetic db.Column(db.String(64)) example db.Column(db.String(256)) class StudyRecord(db.Model): id db.Column(db.Integer, primary_keyTrue) user_id db.Column(db.Integer) word_id db.Column(db.Integer) status db.Column(db.Integer, default0)3.4 前后端联调与请求封装前端所有请求统一走封装好的request模块这样后面切换环境只需要改一个常数// utils/request.js const BASE_URL http://127.0.0.1:5000 export function request(url, method GET, data {}) { return new Promise((resolve, reject) { uni.request({ url: BASE_URL url, method, data, success: (res) resolve(res.data), fail: (err) reject(err) }) }) }本地联调有一个非常关键的设置在微信开发者工具右上角详情配置里必须勾选不校验合法域名、web-view业务域名、TLS版本以及HTTPS证书。否则工具会拦截所有到127.0.0.1的请求页面永远拿不到数据这个操作不打开联调无从谈起。真机调试的时候还要注意127.0.0.1在手机上指向手机自己需要把BASE_URL改成电脑在局域网里的IP比如http://192.168.x.x:5000并且保证手机和电脑在同一个WiFi下。这个坑我踩过一次卡了半小时才反应过来。另外Flask本地默认只监听127.0.0.1真机访问时需要把host改成0.0.0.0python app.py --host0.0.0.0 --port50004. 常见问题与排查技巧实录4.1 微信开发者工具与编译问题先列一个高频问题速查表都是我实际遇到过的问题现象常见原因解决思路导入dist目录后白屏编译产物不完整或appid未配置重新执行npm run dev:mp-weixin检查manifest.json的appid控制台不打印console.log日志级别过滤或工具版本问题打开vConsole切到All级别必要时重启工具插件市场安装的组件不生效组件路径或easycom规则冲突检查uni_modules目录是否存在清理缓存重新编译请求后端无响应开发者工具未勾选不校验合法域名详情配置里勾上本地联调必须开TS类型报错一堆tsconfig路径未正确配置重新安装vue/tsconfig并核对extends路径这里专门说一下uniapp不打印日志信息的问题这是很多新手抓狂的点。我自己的排查顺序是先看HBuilderX控制台有没有代码编译错误再在微信开发者工具的Console面板把日志级别勾到Verbose如果还不行直接挂一个vConsole组件把日志打到页面上看。小程序环境里日志不可见并不代表代码没执行很多时候只是被过滤了。经验之谈是先确认日志级别再确认工具缓存最后才怀疑代码本身。4.2 顶部导航栏与弹窗适配微信小程序的顶部导航栏高度在不同机型上不一样尤其带刘海的机型状态栏高度差异很明显。如果要做自定义导航栏不要写死高度用系统API动态获取const systemInfo uni.getSystemInfoSync() const statusBarHeight systemInfo.statusBarHeight // 胶囊按钮的位置可以从uni.getMenuButtonBoundingClientRect()获取 const menuButton uni.getMenuButtonBoundingClientRect()拿到这两个值以后再计算导航栏总高度就不怕不同机型错位了。这类适配问题在模拟器里看不出差别一定要拿真机去测几台主流机型。我自己做下来发现模拟器上看着居中的自定义标题到iPhone上的刘海屏会偏上到安卓的挖孔屏又会偏下必须动态计算。4.3 登录、手机号获取与权限相关微信小程序获取手机号现在走的是官方手机号快速验证组件用button绑定open-typegetPhoneNumber的方式。这里有两个实际提醒一是个人主体小程序在这方面的能力受限很多接口需要企业主体认证之后才能完整使用开发前先查清自己主体类型对应的权限列表二是开发阶段不要反复点授权弹窗测试容易被平台风控。我测试的时候遇到过授权按钮点了没反应的情况排查半天发现不是代码问题是频率限制。Token这块建议后端用简单的token哈希或者JWT放在每次请求的header里统一校验不要用明文openid做凭证这算基本的安全底线。毕竟小程序跑在微信环境里也不能保证不受恶意请求干扰。4.4 m3u8与多媒体播放经验网上搜vue播放m3u8的人特别多我多说几句。H5端播放m3u8需要hls.js解析因为原生video标签不支持这个格式微信小程序端video组件本身支持HLS协议src直接填m3u8地址就能播但如果视频编码不是H.264部分机型会黑屏。所以英语学习平台的视频课程在转码环节就要固定输出H.264 AAC的HLS流不要在播放端临时兼容否则就会出现这个手机能放那个手机放不了的尴尬。音频方面小程序的audio组件和uni.createInnerAudioContext都够用听力训练用这两者足够了。课件如果用了外部CDN地址记得在小程序后台配置downloadFile合法域名不然真机会下载失败。4.5 上线与源码交付的注意事项项目做完下一步就是上线和交付。这一块有几个容易忽略的要点小程序发布发布前要在小程序后台配置request合法域名必须是HTTPS地址且不能带端口本地联调用的域名不能直接用主体与认证个人主体可以上架部分类目但接口权限受限企业主体有认证费用流程要提前走别等开发完了才去申请安卓App打包uniapp打安卓包用DCloud云打包或本地离线打包本地离线需要Android Studio和对应SDK第一次建议直接用云打包省去环境配置的麻烦应用市场上架安卓应用市场一般需要软件著作权这个东西审批周期长提前几个月准备都不过分源码交付把项目源码发给别人时一定先删掉node_modules目录把package.json保留好对方拿到后执行npm install就能恢复依赖别把几百兆的依赖包直接发过去。后端代码同理数据库文件如果包含测试数据最好清空或做脱敏。最后再聊几句整个项目做下来我最深的体会是英语学习平台这类工具型小程序功能不用贪多把单词和听力这条核心学习闭环做好就已经能覆盖大部分用户的实际需求。技术选型上vue uniapp Python这个三件套的组合解决的核心问题是让一个人也能高效交付一个完整产品——前端复用率高、后端开发快、部署简单算是一条把精力真正花在业务上的路。框架版本千万不要拖动依赖一次到位。我见过太多同学卡在版本不一致上同一个项目一个人用vue2一个人用vue3互相之间代码都跑不通这种坑比业务逻辑难查多了。如果你也在做类似的项目可以先按这篇文章把骨架搭起来功能再做减法逐步迭代。环境配置或者代码上有问题欢迎评论区随时聊。
返回列表