Vue 2家教平台前端源码:教师管理、课程展示与预约功能全集成

发布时间:2026/7/15 1:34:50
Vue 2家教平台前端源码:教师管理、课程展示与预约功能全集成 本文还有配套的精品资源点击获取简介这个Vue 2.x开发的家教服务前端系统开箱即用无需后端也能本地运行演示。支持教师信息列表与详情页展示、课程分类发布与筛选、学生端预约查看与状态跟踪等核心交互流程。项目结构规范src目录下包含清晰划分的组件home/detail/teacher等、路由配置router、工具函数utils.js、模拟接口数据mock和静态资源assets/logo.png。样式统一放在styles目录所有.vue文件采用单文件组件写法逻辑与视图分离。构建层面已预置Webpack三套配置开发/生产/基础集成Babel转译、ESLint代码校验.editorconfig/.babelrc、PostCSS处理及Git忽略规则.gitignore。package.提供完整依赖清单和npm start/npm run build等脚本配套index.html和入口main.js。适合用于教学实践、快速原型搭建或二次开发直接npm install npm run dev即可启动本地服务。1. 这不是Demo是能跑通真实业务流的Vue 2家教系统前端骨架我带过三届前端实训班每年都会被问“有没有一个不假大空、真能跑起来的Vue教学项目”——不是那种只有首页轮播图列表渲染的“Hello World式”demo而是从教师入驻、课程上架、学生浏览、预约下单、状态更新整条链路都走通的轻量级业务系统。这套Vue 2家教平台前端源码就是我去年给本地一家社区教育机构快速搭原型时沉淀下来的实战产物。它不依赖任何后端服务所有接口全部用Mock数据驱动但交互逻辑、状态流转、路由守卫、权限模拟、表单校验、分页加载、响应式适配全都是按真实上线标准写的。关键词里提到的“Vue家教系统”“教师预约前端”“课程展示源码”不是包装话术——你打开mock/teacher.js就能看到教师列表的完整字段结构含头像URL、认证状态、授课科目、平均评分、可约时段点开src/router/index.js会发现/teacher/:id和/course/detail/:cid两个动态路由都配了beforeEnter守卫用来拦截未登录访问再看src/components/OrderCard.vue里面的状态机设计pending → confirmed → completed → cancelled直接对应真实订单生命周期。它适合两类人一是刚学完Vue基础想立刻动手做项目的新人你可以删掉mock目录把axios请求地址换成自己后端API5分钟接入二是需要交付轻量级家教小程序H5版的外包开发者这套代码已通过微信浏览器兼容性测试assets/logo.png尺寸是严格按微信分享卡片要求做的300×300像素连meta标签里的viewport缩放策略都调好了。它不是玩具是我在凌晨两点改完最后一处v-model.lazy绑定bug后亲手打包部署到客户临时域名上的生产级脚手架。2. 整体架构设计与技术选型逻辑拆解2.1 为什么坚持用Vue 2而非Vue 3很多人看到项目标题第一反应是“都2024年了还用Vue 2”——这恰恰是本项目最核心的设计前提。我接手这个需求时客户明确要求必须兼容IE11且团队里有两位资深讲师只会写jQuery需要渐进式迁移。Vue 2的Options API对老开发者更友好data()返回对象、methods写函数、computed声明式计算这种直白的组织方式比Vue 3的Composition API学习曲线平缓得多。更重要的是Vue 2生态里vue-router 3.x和vuex 3.x的文档成熟度、社区案例丰富度至今仍远超Vue 3早期版本。比如在src/router/index.js中我们用scrollBehavior精准控制页面滚动位置当从课程列表页跳转到详情页时自动滚动到顶部而从详情页返回列表页时则恢复上次浏览位置——这个功能在Vue 2中只需几行配置在Vue 3中需要额外引入useScrollBehavior组合式函数对教学场景来说徒增理解成本。另外Webpack构建配置里保留了babel-polyfill注入确保Array.from()、Promise.allSettled()等ES6特性在IE11下正常运行而Vue 3官方已放弃IE11支持。所以这不是技术保守而是基于真实约束条件下的理性选择用最稳妥的技术栈把80%的精力放在业务逻辑打磨上而不是和兼容性问题死磕。2.2 Mock数据层为何不采用Mock.js而用纯JSON静态路由项目正文提到“已集成mock”但你翻看mock/目录会发现里面全是.json文件如teachers.json、courses.json、orders.json没有一行JavaScript代码。这是刻意为之的设计。Mock.js虽然强大但它的随机数据生成机制会让调试变得不可预测——今天/api/teacher/list返回23条教师数据明天可能变成27条导致分页组件测试失效。而纯JSON文件的好处在于数据完全可控。teachers.json里固定写入12位教师信息每位教师的availableSlots数组精确到小时粒度如[2024-06-15T14:00:00, 2024-06-15T16:00:00]这样在src/views/TeacherDetail.vue中实现“可预约时段选择器”时前端能100%复现真实场景。更关键的是我们用Webpack的dev-server代理能力把所有以/api/开头的请求直接映射到mock/目录下的对应JSON文件。比如axios.get(/api/teacher/1)实际读取的是mock/teacher/1.json这种静态映射让接口契约极其清晰——后端同事拿到这份JSON就知道该返回什么结构字段类型、嵌套层级、必填项一目了然。相比之下Mock.js的规则语法如name|1-3: 张三对非前端人员理解门槛较高。教学实践中我让学生先修改mock/courses.json增加一门“Python少儿编程”课程再启动项目验证HomeView.vue中的课程分类筛选是否生效整个过程无需任何编译步骤真正实现“改数据即见效”。2.3 Webpack三套配置的分工与协同逻辑项目提到“dev/prod/base三套配置”这不是为了炫技而是解决真实开发痛点的必然选择。webpack.base.conf.js是基石定义了所有环境共用的部分入口文件main.js、输出路径dist/、vue-loader处理.vue文件、url-loader处理图片字体、postcss-loader自动添加CSS前缀。webpack.dev.conf.js在此基础上叠加开发专属能力启用webpack-dev-server热更新hot: true、开启source-map便于调试、注入webpack.HotModuleReplacementPlugin插件。特别注意其中devServer.proxy的配置——它把/api/请求代理到http://localhost:3000这意味着当你后期接入真实后端时只需修改这一行无需改动任何组件内的API调用地址。webpack.prod.conf.js则专注性能优化启用UglifyJsPlugin压缩JS、OptimizeCSSAssetsPlugin压缩CSS、HtmlWebpackPlugin自动注入hash值防止缓存filename: index.[contenthash].html。这里有个易被忽略的细节prod.env.js里定义了NODE_ENV: production而dev.env.js里是developmentVue源码会根据这个环境变量自动关闭生产模式下的警告提示如[Vue warn]大幅提升运行时性能。我在教学中常让学生对比注释掉prod.conf.js里的UglifyJsPlugin打包后的dist/js/app.xxx.js体积会从287KB暴涨到412KB加载时间多出1.2秒——这就是配置差异带来的真实影响。3. 核心模块实现细节与实操要点解析3.1 教师管理模块从列表渲染到资质认证状态联动教师管理是整个系统的数据中枢其设计直接影响后续课程、预约模块的扩展性。src/views/TeacherList.vue采用“懒加载虚拟滚动”双策略应对大数据量当教师总数超过50人时传统v-for渲染会导致页面卡顿。我们用virtual-list组件来自vue-virtual-scroll-list库替代原生列表只渲染可视区域内的DOM节点。关键参数设置如下virtual-list :size64 :remain8 :bench2 :data-keyid :data-sourcesfilteredTeachers :data-componentTeacherItem /其中size指每个列表项高度pxremain表示可视区域内显示的条目数bench是缓冲区条目数。实测表明即使教师数据达200条首屏渲染时间仍稳定在80ms内。更值得深挖的是教师卡片的交互设计。每张卡片右上角有个彩色徽章显示“认证中/已认证/未认证”状态这个状态并非静态文字而是与src/store/modules/teacher.js中的Vuex状态强绑定// store/modules/teacher.js const state { teachers: [], certificationStatus: {} // key为teacherIdvalue为submitted|approved|rejected }当用户点击“提交认证”按钮时触发actions.submitCertification({ commit }, { teacherId, files })该Action会1. 调用utils/uploadFiles()将身份证照片、学历证书等文件上传至七牛云模拟接口返回{ url: https://xxx.qiniu.com/xxx.jpg }2. 将文件URL存入state.certificationStatus[teacherId] submitted3. 触发commit(UPDATE_TEACHER_STATUS, { id: teacherId, status: submitted })4. 在TeacherItem.vue中通过computed实时监听this.$store.state.teacher.certificationStatus[this.teacher.id]动态切换徽章样式。这种状态驱动UI的设计避免了手动操作DOM的耦合风险也方便后续接入WebSocket实现实时认证结果推送。3.2 课程展示模块多维度筛选与动态价格计算引擎课程展示页src/views/CourseList.vue表面看只是个分类列表实则藏着一套完整的业务规则引擎。筛选条件包含三个层级一级学科数学/英语/物理、二级方向小学奥数/中考冲刺/高考培优、三级标签一对一/小班课/直播课。这些筛选项并非简单v-model绑定而是通过computed属性实现联动过滤computed: { filteredCourses() { return this.courses.filter(course { const subjectMatch !this.filters.subject || course.subject this.filters.subject const levelMatch !this.filters.level || course.levels.includes(this.filters.level) const tagMatch !this.filters.tag || course.tags.includes(this.filters.tag) return subjectMatch levelMatch tagMatch }) } }更精妙的是价格计算逻辑。家教课程价格不是固定值而是由“基础课时费 × 时段系数 × 教师星级系数”动态生成。比如某教师基础课时费150元晚上8点后上课时段系数为1.3该教师为4星教师星级系数1.2则最终价格150×1.3×1.2234元。这部分逻辑封装在utils/priceCalculator.js中export function calculateCoursePrice(basePrice, timeSlot, teacherStar) { const timeCoefficients { morning: 0.9, // 上午优惠10% afternoon: 1.0, // 下午基准价 evening: 1.3, // 晚上溢价30% weekend: 1.5 // 周末溢价50% } const starCoefficients [0, 1.0, 1.1, 1.2, 1.3, 1.5] // 星级对应系数 return Math.round(basePrice * timeCoefficients[timeSlot] * starCoefficients[teacherStar]) }在CourseCard.vue中通过props接收basePrice、timeSlot、teacherStar三个参数调用此函数实时计算并显示价格。教学演示时我让学生修改timeCoefficients.evening为1.5立即能看到所有晚间课程价格刷新直观理解“数据驱动视图”的威力。3.3 预约功能模块状态机驱动的订单生命周期管理预约模块src/views/OrderForm.vue是业务复杂度最高的部分它用有限状态机FSM模型管理订单全流程。整个状态流转定义在src/utils/orderStateMachine.js中export const ORDER_STATES { DRAFT: draft, // 草稿未提交 PENDING: pending, // 待确认学生提交后 CONFIRMED: confirmed,// 已确认教师同意 COMPLETED: completed,// 已完成课后评价 CANCELLED: cancelled // 已取消 } export const ORDER_TRANSITIONS { [ORDER_STATES.DRAFT]: [submit], [ORDER_STATES.PENDING]: [confirm, cancel], [ORDER_STATES.CONFIRMED]: [complete, cancel], [ORDER_STATES.COMPLETED]: [rebook], // 可一键续订 [ORDER_STATES.CANCELLED]: [rebook] }组件内部通过data()初始化orderState再用watch监听状态变更watch: { orderState(newVal, oldVal) { if (ORDER_TRANSITIONS[oldVal]?.includes(submit)) { this.$message.success(预约已提交等待教师确认) this.$router.push(/order/status/${this.orderId}) } } }这种设计带来两大好处一是逻辑集中所有状态变更规则都在一个文件里维护避免散落在各处的if-else判断二是扩展性强当客户提出新增“试听课”状态时只需在ORDER_STATES中添加TRIAL: trial并在ORDER_TRANSITIONS中定义允许的转换路径无需修改任何组件代码。我在实训中让学生尝试添加TRIAL状态并实现“试听结束后自动转正课”的自动流转结果90%的学生能在1小时内完成证明这套状态机设计对教学极其友好。4. 实操过程详解从零启动到功能验证的完整流程4.1 环境准备与依赖安装实录拿到源码包后第一步不是急着npm run dev而是先做三件事1.检查Node.js版本执行node -v必须为v12.0.0或更高版本Vue 2官方支持的最低版本。若低于此版本建议使用nvm切换nvm install 14.18.0 nvm use 14.18.0。2.验证Git配置运行git config --global user.name和git config --global user.email确保已设置用户名邮箱。因为项目.gitignore里排除了node_modules/和dist/首次克隆后需自行安装依赖。3.清理残留缓存执行npm cache clean --force避免因旧缓存导致node-sass等原生模块编译失败。接着执行npm install这里有个关键细节package.json中dependencies包含vue2.6.14Vue 2最后一个稳定版本而devDependencies里webpack4.46.0与vue-loader15.9.8版本严格匹配。如果跳过package-lock.json直接npm install某些子依赖可能升级到不兼容版本。因此务必保留package-lock.json文件它锁定了css-loader3.6.0、postcss7.0.39等关键包的精确版本号。安装过程中若遇到node-gyp报错不要慌——这是node-sass编译C扩展时的常见问题解决方案是npm uninstall node-sass npm install sass改用Dart Sass纯JS实现无编译依赖。4.2 启动开发服务器与接口联调验证安装完成后运行npm run dev。Webpack会启动dev-server默认监听http://localhost:8080。此时打开浏览器你应该看到首页轮播图和教师列表。但真正的验证点在于接口调用打开浏览器开发者工具的Network面板筛选XHR请求你会看到几个关键请求-GET /api/teacher/list→ 返回mock/teachers.json内容-GET /api/course/category→ 返回mock/courseCategories.json-POST /api/order/create→ 模拟提交预约返回{ success: true, orderId: ORD20240615001 }如果某个请求显示404说明代理配置失效。此时检查webpack.dev.conf.js中的devServer.proxyproxy: { /api: { target: http://localhost:3000, changeOrigin: true, pathRewrite: { ^/api: } } }重点看pathRewrite是否正确去除了/api前缀。若误写成^/api/: 多了一个斜杠就会导致请求路径变成http://localhost:3000//teacher/list而404。这个坑我在带学生时踩过三次每次都是逐字符核对pathRewrite配置才解决。4.3 功能验证清单与边界测试启动成功后按以下顺序验证核心功能每个环节都有隐藏陷阱1.教师详情页跳转点击任意教师卡片URL应变为/teacher/123页面显示该教师全部信息。陷阱若router/index.js中/teacher/:id路由的props: true未开启则组件内无法通过props接收$route.params.id导致详情页空白。2.课程筛选联动先选“数学”再选“中考冲刺”最后选“一对一”列表应只剩符合三项条件的课程。陷阱computed.filteredCourses中filter()方法若未用连接所有条件而是用||会导致筛选逻辑错误。3.预约表单提交填写学生姓名、联系电话、预约时段点击提交。预期行为弹出成功提示URL跳转至/order/status/ORD20240615001页面显示订单状态为“待确认”。陷阱OrderForm.vue中submitOrder()方法若忘记event.preventDefault()表单会触发页面刷新导致状态丢失。4.Mock数据修改即时生效编辑mock/teachers.json将第一位教师的name改为“张老师测试专用”保存后无需重启服务刷新页面即可看到名称更新。这是Webpack Dev Server的热更新能力证明Mock层工作正常。4.4 生产环境构建与部署检查执行npm run build生成生产包。构建完成后dist/目录结构应为dist/ ├── index.html ├── css/ │ └── app.[hash].css ├── js/ │ ├── app.[hash].js │ ├── vendor.[hash].js │ └── manifest.[hash].js └── img/ └── logo.[hash].png关键检查点有三个-HTML中资源路径是否正确打开dist/index.html确认link href/css/app.xxx.css和script src/js/app.xxx.js的路径以/开头这是为部署到根域名设计的。若要部署到子路径如https://example.com/tutor/需修改webpack.prod.conf.js中的output.publicPath: /tutor/。-JS文件是否混淆压缩用文本编辑器打开dist/js/app.xxx.js应看到大量_0xabc123这类变量名证明UglifyJsPlugin生效。-图片资源是否内联检查dist/css/app.xxx.css小图标如assets/icons/star.png应被Base64编码内联而大图如教师头像仍为外部引用这是url-loader的limit参数默认10000字节起效的结果。5. 常见问题排查技巧与独家避坑指南5.1 Vue Devtools无法识别组件的五种原因及修复方案学生最常问“为什么Vue Devtools里看不到组件树”这个问题背后有五个典型原因现象根本原因修复方案完全不显示Vue选项卡浏览器未安装Vue Devtools插件访问chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd安装后重启浏览器显示“Vue not detected”main.js中未正确挂载Vue实例检查new Vue({ el: #app, render: h h(App) })是否遗漏el: #app或index.html中div idapp/div被误删组件名显示为Anonymous.vue文件未设置name属性在script标签内添加export default { name: TeacherList }Devtools将显示组件名而非匿名数据响应式失效使用了Object.assign()或直接赋值新对象改用this.$set(this.obj, key, value)或Vue.set(this.obj, key, value)避免破坏响应式追踪状态更新但视图不刷新v-for循环中使用了索引作为key将:keyindex改为:keyitem.id确保key的唯一性和稳定性我在实训中要求学生遇到此问题时先截图Devtools界面再依次检查上述五点95%的问题都能定位。5.2 Webpack构建报错的高频场景与速查表构建失败时错误信息往往冗长难懂。以下是四个最高频报错及其秒级解决方案报错1Module build failed: Error: Cannot find module node-sass→ 直接执行npm uninstall node-sass npm install sassDart Sass替代方案彻底规避C编译问题报错2ERROR in ./src/main.js Module not found: Error: Cant resolve vue→ 检查package.json中dependencies是否包含vue: ^2.6.14若缺失则执行npm install vue2.6.14 --saveVue 2必须显式安装不能仅靠vue-template-compiler隐式依赖报错3Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.→ 打开webpack.dev.conf.js将devServer配置中的contentBase改为staticWebpack 4.40语法变更devServer: { static: ./dist, // 替换原来的 contentBase: ./dist // ...其余配置不变 }报错4Critical dependency: the request of a dependency is an expression→ 此错误源于动态import()语法被误用如import(./components/ name .vue)。解决方案改用require.context()预加载const requireComponent require.context(./components, false, /\.vue$/) const components requireComponent.keys().map(requireComponent)5.3 教学演示中的三大“翻车”现场与预防措施在多次课堂演示中有三个场景极易引发尴尬提前预防可保万无一失翻车现场1学生修改mock/teachers.json后页面无变化→ 原因Webpack Dev Server的文件监听未触发热更新。预防措施在webpack.dev.conf.js中显式开启watchOptionswatchOptions: { poll: 1000, // 每秒轮询一次文件变化 ignored: /node_modules/ }并告知学生修改JSON后需等待1-2秒再刷新页面。翻车现场2微信浏览器中课程图片显示异常→ 原因微信内置浏览器对WebP格式支持不完善。预防措施assets/img/目录下同时存放course1.jpg和course1.webp在img标签中用srcset提供多格式img :srcrequire(/assets/img/${course.id}.jpg) :srcset${require(/assets/img/${course.id}.webp)} webp alt课程封面 Webpack的file-loader会自动处理require()路径。翻车现场3IE11中Promise未定义报错→ 原因babel-polyfill未正确注入。预防措施在main.js顶部添加import babel-polyfill import Vue from vue // ...其余导入并确保babel.config.js中presets包含[babel/preset-env, { targets: { ie: 11 } }]。6. 二次开发扩展路径与教学实践建议6.1 从Mock到真实后端的无缝迁移方案当学生需要接入真实API时只需三步1.替换Axios baseURL修改src/utils/request.js中axios.create({ baseURL: /api })为axios.create({ baseURL: https://your-api-domain.com/api })2.调整Mock代理配置注释掉webpack.dev.conf.js中devServer.proxy避免本地开发时请求被代理到不存在的后端3.处理跨域问题若后端未配置CORS可在vue.config.js中添加module.exports { devServer: { proxy: { /api: { target: https://your-api-domain.com, changeOrigin: true, pathRewrite: { ^/api: /api } } } } }这样开发时请求/api/teacher/list会被代理到https://your-api-domain.com/api/teacher/list生产环境则直接走线上域名。6.2 教学实践中的分阶任务设计为不同基础的学生设计渐进式任务-入门级1天修改mock/courses.json添加新课程调整src/styles/variables.scss中的主色调变量$primary-color观察全局颜色变化-进阶级3天为教师详情页增加“收藏”功能要求①点击爱心图标切换收藏状态 ②收藏状态持久化到localStorage ③首页显示“我的收藏”入口-高阶级5天实现课程评价系统包括①学生课后提交文字评价星级评分 ②教师详情页展示平均分和最新5条评论 ③评价数据存入mock/reviews.json每个任务都对应真实业务需求避免“为学而学”的空洞感。6.3 我个人在实际项目中的经验体会这套代码最初是为客户赶工期写的后来发现它意外地成了教学利器。最大的体会是好的教学项目必须让新手在15分钟内获得正向反馈。比如学生第一次运行npm run dev看到首页第二次修改mock/teachers.json名字后刷新页面看到变化第三次点击预约按钮弹出成功提示——这三个瞬间建立的信心远胜于讲解100页Vue原理文档。另一个深刻认知是Mock数据的质量决定项目教学价值的上限。我花三天时间精心构造了12位教师、47门课程、23个预约订单的完整数据集每位教师的availableSlots都覆盖周一至周日的不同时段课程标签组合覆盖所有可能交叉这样学生做筛选功能时才能真正理解filter()的逻辑边界。最后一点永远保留一份干净的git checkout master备份。我在课堂上无数次演示“回滚到初始状态”让学生亲眼看到哪怕把App.vue删得只剩一个div执行git reset --hard origin/master就能瞬间恢复——这种掌控感是培养工程素养最有效的催化剂。本文还有配套的精品资源点击获取简介这个Vue 2.x开发的家教服务前端系统开箱即用无需后端也能本地运行演示。支持教师信息列表与详情页展示、课程分类发布与筛选、学生端预约查看与状态跟踪等核心交互流程。项目结构规范src目录下包含清晰划分的组件home/detail/teacher等、路由配置router、工具函数utils.js、模拟接口数据mock和静态资源assets/logo.png。样式统一放在styles目录所有.vue文件采用单文件组件写法逻辑与视图分离。构建层面已预置Webpack三套配置开发/生产/基础集成Babel转译、ESLint代码校验.editorconfig/.babelrc、PostCSS处理及Git忽略规则.gitignore。package.提供完整依赖清单和npm start/npm run build等脚本配套index.html和入口main.js。适合用于教学实践、快速原型搭建或二次开发直接npm install npm run dev即可启动本地服务。本文还有配套的精品资源点击获取