十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

基于UniApp的校园维修小程序开发复盘:从需求到上线全流程

基于UniApp的校园维修小程序开发复盘:从需求到上线全流程 做校园维修小程序这个想法最早是从一个特别真实的场景冒出来的宿舍灯管坏了不知道找谁报修打听一圈终于加上了维修群结果接单全看缘分好不容易报了修又完全不知道师傅什么时候来只能干等。后来我把这个业务完整落地成了基于微信小程序 UniApp 的校园维修系统从需求梳理、技术选型、代码实现到最后跑通上线的完整流程大概用了三周。这篇就把整个项目从头到尾复盘一遍里面不少坑都是我亲手踩过的你照着做能少走很多弯路。这个项目本身不算复杂但它涉及的链条其实挺长的前端小程序、后端接口、图片上传、消息通知、权限配置、审核发布每一步都有细节。如果你正在做毕设、练手项目或者刚接触 UniApp 想找个完整案例这篇内容基本能覆盖你的需要。我会把业务设计、工程配置、核心代码逻辑、发布流程和问题排查全部讲清楚不只是给代码还会解释为什么这么做。1. 需求理清楚再做代码1.1 校园维修不是“报修接单”这么简单很多第一次做这类系统的人第一个念头就是做一个表单收集报修信息然后让维修工看列表去接单。但这个思路漏掉了校园场景里最核心的一个问题信任感。你可以把校园维修想象成一个简化版的外卖平台——用户需要知道“我的单子有人接了吗”“师傅到哪了”“大概什么时候能处理”。如果没有这些信息用户就会反复打电话、发消息催管理员和维修工都会被烦死。所以这个系统的核心不是“记录报修”而是“让工单的状态透明化”。另外还要考虑角色之间的利益诉求。学生的诉求是报修方便、进度可见、修得好不好能评价维修工的诉求是任务集中、不用手工登记、干完活能证明管理员的诉求是派单合理、响应快慢有据可查、每月还能导出统计。一套合格的校园维修系统必须同时满足这三方的诉求而不是只做一个学生端提交页面。我最终把业务拆成了这么几个核心模块用户报修填写位置、分类、问题描述上传现场照片提交后生成工单。工单流转待派单 → 待接单 → 维修中 → 待验收 → 已完成 → 已评价。管理后台管理员可以派单、改派、驳回查看统计报表。消息通知工单状态变化时通过微信订阅消息触达用户。评价闭环用户确认完成之后可以对维修质量打分评论。其中工单流转是整个系统的灵魂后端的表结构、前端的页面跳转、消息触发的时机全部是围绕状态机来设计的。1.2 三条核心链路和一套状态机这个系统里最频繁发生的有三条链路你在设计阶段就要把它们捋清楚用户报修链路登录 → 填写报修单 → 上传图片 → 提交 → 生成工单 → 等待派单。维修工处理链路查看待接单列表 → 接单 → 联系用户/上门 → 提交完成 → 等待用户验收。管理员管理链路查看新增工单 → 指派给维修工 → 跟踪进度 → 处理用户评价和投诉。这三条链路对应到状态机上就是那一串状态流转。实操中我建议后端存一个整数状态字段前端根据状态码渲染对应的样式和按钮不要用字符串状态满天飞否则后期加状态、加逻辑的时候会非常痛苦。状态机的关键节点和触发动作是这样的状态含义触发者可执行操作0待派单用户提交管理员派单、用户取消1待接单管理员派单维修工接单、管理员改派2维修中维修工接单维修工提交完成3待验收维修工提交完成用户确认完成、用户申诉4已完成用户确认完成用户评价5已取消用户/管理员无6已驳回管理员管理员备注原因这里有一个非常容易忽略的点用户取消和申诉的入口。我的第一版里没有做用户取消结果用户报错单子想撤回只能打电话找管理员体验很差。后来加了“待派单状态下允许用户取消”这一个小功能直接减少了一大半管理员的人工干预。1.3 技术栈选型UniApp 不是唯一解但确实省事选型时我其实纠结过直接用微信原生小程序写还是用 UniApp 跨端框架原生小程序的好处是文档齐全、工具链稳定、踩坑资料多。但它有两个硬伤一个是语法体系独立于主流前端WXML WXSS 自定义组件学一遍之后出了微信生态用不上另一个是如果未来想同时出支付宝小程序、抖音小程序或者 H5 版原生方案要全部重写。UniApp 解决的就是这两个问题。它基于 Vue 语法你在网页前端积累的经验可以迁移过来一套代码可以编译到微信小程序、H5、App 等平台。对校园维修这种“工具型、多端潜在需求”的业务来说UniApp 的性价比非常高。我最终选的组合是前端UniApp Vue3 ViteHBuilderX 创建项目UIuView Plus或者干脆自己写样式避免组件库体积过大后端Java Spring Boot 或者 Node.js 都可以关键是接口要规范数据库MySQL如果只是演示用 SQLite 或者 uniCloud 云数据库也行后端我额外多说一句。如果你是为了快速验证功能用 uniCloud 云开发可以省掉服务器部署的麻烦小程序端直接调用云函数。但如果你是想练技术或者做毕设建议还是单独写一套后端接口因为 Spring Boot 那套 JWT 登录、拦截器、文件上传的东西还是值得过一遍的。2. 前端工程搭建目录、配置和前后端约定2.1 能直接抄的目录结构和页面规划UniApp 的工程结构本身不复杂但如果你不规划写到后面就会变成一个巨大的pages目录堆满各种页面。我的习惯是先把页面按角色分清楚再落到目录里。├── pages │ ├── login/index.vue // 登录页 │ ├── index/index.vue // 首页角色不同显示不同内容 │ ├── repair/add.vue // 提交报修 │ ├── repair/detail.vue // 工单详情 │ ├── order/list.vue // 工单列表管理员/维修工用 │ ├── order/process.vue // 维修工处理页 │ ├── mine/index.vue // 个人中心 ├── components │ ├── status-tag.vue // 状态标签组件 │ ├── repair-card.vue // 工单卡片组件 ├── api │ ├── request.js // uni.request 封装 │ ├── repair.js // 工单相关接口 │ └── user.js // 用户相关接口 ├── store │ └── user.js // 用户登录态管理 ├── utils │ ├── format.js // 时间、状态格式化 │ └── auth.js // token 存取 └── static页面规划上我建议不要让用户端和维修工端完全分两个小程序而是同一个 App 内通过角色判断来渲染不同的 tabBar 和页面入口。这样开发和维护成本最低也符合微信小程序的体验习惯。角色信息可以在登录后由后端返回存入本地 storage。2.2 manifest.json基础库、权限和 AppIDmanifest.json是 UniApp 的全局配置文件微信小程序相关的配置全部集中在mp-weixin节点。这里有几个地方我必须提醒你第一个是 AppID。如果你只是本地开发预览可以用测试号但一旦要发布上线必须用正式的小程序 AppID。在 HBuilderX 的manifest.json - mp-weixin - appid里填上就行也可以在微信开发者工具里导入后配置。填写错误会直接导致无法上传。第二个是基础库版本。这个不少新手找不到入口。在 UniApp 中最低基础库版本其实是在manifest.json - mp-weixin - setting中设置或者在微信公众平台的“设置-基本设置”里配置。更保险的做法是在代码里判断比如const version wx.getSystemInfoSync().SDKVersion if (compareVersion(version, 2.20.0) 0) { // 提示用户升级微信 }基础库版本决定了你能用哪些新 API 和特性。设置得太高老版本微信的用户就用不了设置得太低代码里用了新 API 又要做兼容。一般建议最低 2.20.0 左右同时启用“自动向上兼容”。第三个是权限声明。小程序涉及相机、相册、定位时需要提前在manifest.json中声明否则调用相关 API 时会直接失败。比如我要做拍照报修和扫码报修就必须配置mp-weixin: { permission: { scope.userLocation: { desc: 用于获取报修设备所在位置 } }, requiredPrivateInfos: [getLocation, chooseLocation] }另外如果你要调用chooseImage和scanCodeIOS 端还要在微信公众平台的“用户隐私保护指引”中如实声明收集的信息类型否则审核会被驳回甚至真机调试时会被拦截。2.3 后端接口规范与关键表设计后端接口我强烈建议统一返回结构不然前端request.js封装会很痛苦。我常用的格式是{ code: 0, message: success, data: {} }其中code为 0 表示成功非 0 表示业务错误。前端request.js里统一拦截非 0 的 code弹出message同时识别 HTTP 401 状态码自动清除本地 token 并跳转登录页。数据表设计方面最核心的是repair_order这张表。我建表的经验是不要把所有字段堆在一张表里但也不要拆得太细。核心字段大概这样id工单 IDorder_no业务编号给用户看和查询用user_id报修人 IDhandler_id处理维修工 IDcategory_id维修分类水电、门窗、网络、设备等title报修标题description报修描述address报修地点images图片 URL 列表用逗号分隔或存 JSONstatus状态码assign_time派单时间accept_time接单时间finish_time完成时间rating评分comment评价内容图片字段我建议不要单独建表除非你要做非常复杂的图片管理。用逗号分隔存在images字段里前端拿到后split(,)成数组渲染就行简单直接。当然如果图片数量很多或者要做原图压缩、审核那再考虑拆表。登录逻辑上小程序端先用wx.login获取 code然后请求后端接口后端拿着 code 调用微信接口换 openid生成 JWT token 返回给前端。前端把 token 存起来后续请求统一放在 header 的Authorization字段里。3. 核心功能逐个落地3.1 报修表单图片上传的坑与优化报修表单是整个系统的入口也是用户感知最直接的页面。除了基本的表单校验图片上传是最容易出问题的环节。用 UniApp 的uni.chooseImage选择图片后返回的tempFilePaths是本地临时路径这个路径只有小程序运行期间有效不能直接给其他用户看也不能直接存储。你必须通过uni.uploadFile上传到自己的服务器然后把服务器返回的 URL 存到工单数据里。上传图片时有几个细节非常关键第一控制数量和大小。我前端限制最多上传 6 张每张压缩后不能超过 1MB。uni.chooseImage的sizeType参数里建议选compressed这样能有效减少上传流量和服务器压力。第二多图上传要串行或控制并发。我第一版用Promise.all同时传 6 张结果后端瞬间并发太大偶尔会出现连接超时。后面改成了一次传 3 张、分批上传的策略稳定了很多。第三上传失败要有重试提示。校园网环境不稳定用户可能在宿舍信号差的地方报修。上传失败不要只是 toast 一下应该给出“重新上传”的操作入口不然用户填了半天表单图片全挂心态直接崩。核心代码大概长这样async uploadImages(tempFiles) { const uploadTasks tempFiles.map((file) { return new Promise((resolve, reject) { uni.uploadFile({ url: ${baseUrl}/api/upload, filePath: file.path, name: file, success: (res) { const data JSON.parse(res.data) resolve(data.url) }, fail: (err) reject(err) }) }) }) // 分批上传每批3个 const results [] for (let i 0; i uploadTasks.length; i 3) { const batch uploadTasks.slice(i, i 3) const batchResult await Promise.all(batch) results.push(...batchResult) } return results }3.2 工单流转列表刷新和状态判断工单列表页是用户打开最多的页面。这里最核心的是状态筛选和下拉刷新。0 待派单 1 待接单 2 维修中 3 待验收 4 已完成 5 已取消我顶部做了一个横向滚动的 tab 栏点击不同状态就切换列表。第一次做的时候踩了一个坑每次切换 tab 都重新请求接口然后 loading 转圈体验还行但用户从详情页返回时列表又重新加载了滚动位置也丢了。这个问题的解法是列表数据做本地缓存切换 tab 时只更新当前状态的数据返回页面时用onShow判断是否需要刷新而不是无脑请求。再有一个细节不同状态下的操作按钮完全不同。比如待派单状态用户只能看到“取消工单”待接单状态维修工看到的是“接单”按钮维修中状态维修工看到的是“提交完成”。这些都不能写死在卡片组件里我封装了一个status-tag组件根据状态和角色动态渲染button v-ifstatus 1 role worker clickacceptOrder(item)接单/button button v-ifstatus 2 role worker clickfinishOrder(item)提交完成/button button v-ifstatus 3 role user clickconfirmOrder(item)确认完成/button页面切换有一个几乎每个人都会遇到的坑工单详情页修改了状态返回列表页后列表还是旧的。我的处理方式是在详情页操作完成后通过uni.$emit(refreshList)发一个事件列表页在onShow里监听并刷新对应数据。这个比每次都强制刷新要优雅得多。3.3 扫码报修与定位一行代码背后的权限逻辑有些报修场景是设备本身有二维码比如实验室仪器、机房设备。这种情况下扫码报修比手动填表快得多。UniApp 的扫码接口是uni.scanCode在微信小程序端内部映射的是wx.scanCode。uni.scanCode({ onlyFromCamera: true, success: (res) { // res.result 就是扫码得到的字符串 // 把设备编号自动填入表单 this.equipmentNo res.result }, fail: (err) { console.log(扫码失败, err) } })实际运行中扫码“不清晰”的问题很常见很多人以为是小程序的问题其实大部分是环境原因。微信扫码对光线和距离非常敏感在室内灯光比较暗时扫码成功率会明显下降。这时候要么引导用户把设备移近一点要么在页面显眼位置放一个“手电筒”开关。另外onlyFromCamera: true这个参数很关键它可以让用户直接扫而不是先打开相册选图。还有权限问题。扫码本身不要求定位权限但如果你在扫码成功之后要通过uni.getLocation获取设备位置就必须在manifest.json里声明scope.userLocation并且需要用户主动授权。这个授权弹窗不能由代码直接触发必须在用户点击某个操作时触发比如点击“扫码报修”按钮之后。如果用户之前拒绝过要去“设置”页手动开启小程序里可以用uni.openSetting引导用户。3.4 消息订阅别在用户犹豫时弹窗消息通知是提升工单流转体验的关键。没有通知用户提交完报修就只能自己时不时打开小程序看一眼体验很差。微信小程序提供的是“订阅消息”能力UniApp 里对应的是uni.requestSubscribeMessage。这个 API 只在微信小程序端生效所以代码里最好做平台判断。订阅消息有一个很坑的限制普通小程序的一次性订阅消息用户每次同意只能下发一条。也就是说用户点了十次“允许”你才有十条下发额度。而且这个“同意”不能是在页面加载时弹窗必须在用户有点击操作的时候调用类似支付操作的交互场景。所以我的做法是在用户提交报修、点击“提交工单”按钮的success回调里才请求订阅消息权限。这样用户是为了“收到这个工单的进度通知”这个明确目的而授权成功率最高也符合微信的审核规范。submitOrder() { // 提交工单逻辑... // 提交成功后请求订阅消息 uni.requestSubscribeMessage({ tmplIds: [模板ID1, 模板ID2], // 在微信公众平台申请 success: (res) { // 用户可能拒绝了部分模板这里可以根据 res[模板ID1] 判断 } }) }模板 ID 需要在微信公众平台 → 功能 → 订阅消息里申请建议提前申请“工单状态通知”“维修完成通知”两个模板。tmplIds数组最多可以传 3 个模板用户同意后每个模板各获得一条下发额度。后端下发订阅消息时要用到小程序的 appid 和 secret 换取 access_token然后调用subscribeMessage.send接口。注意 access_token 的有效期是 2 小时需要缓存起来不能每次都重新获取否则会被微信接口频率限制。3.5 分享好友让工单可以找同学代看校园场景里经常有这种情况室友报修的工单宿舍其他人也想看进展或者维修工想让自己的同事帮看一下工单内容。所以分享功能也是必须的而且分享时最好带参数。UniApp 里自定义分享通过onShareAppMessage实现。需要注意这个钩子只在页面被分享时生效不是分享功能本身。如果你的分享入口是右上角菜单页面里直接定义这个钩子就行如果你想在页面里放一个“分享给同学”按钮按钮要设置open-typeshare。onShareAppMessage() { return { title: 宿舍报修进度${this.order.order_no}, path: /pages/repair/detail?id${this.order.id}, imageUrl: this.order.images ? this.order.images[0] : } }对方通过分享卡片点进小程序后会在onLoad的options.id里拿到工单 ID。这里要做一个权限判断如果对方不是该工单的相关人员可以开放只读权限但不能操作避免信息泄露和不必要的修改。还有一个容易踩的坑分享出去的详情页如果用户没有登录直接进入后会要求登录但登录成功后跳回详情页时要记得带上原本的id参数。我一开始没处理导致分享链路永远进不了详情页被同学吐槽了几次。4. 从 HBuilderX 到微信开发者工具再到上线4.1 发行小程序完整步骤记录UniApp 项目最终要变成微信小程序靠的是 HBuilderX 的发行功能。这一步看似简单实际上有几个地方特别容易踩坑。正确的流程是在 HBuilderX 中打开项目点击菜单栏“发行 → 小程序-微信”。发行前确认manifest.json里的mp-weixin.appid已填好。等待编译完成控制台会输出项目目录通常是unpackage/dist/dev/mp-weixin。打开微信开发者工具选择“导入项目”目录选上面那个路径AppID 保持一致。导入后先在开发者工具里跑一遍确认没有报错再进行真机预览。这里有个新手非常容易搞混的点HBuilderX 生成的是编译后的微信原生小程序代码不是让你在 HBuilderX 里去调试微信小程序。你在 HBuilderX 里写的是 Vue 代码微信开发者工具里跑的是编译后的WXMLWXSSJS。另一个容易踩坑的点如果你用了uni_modules里的插件发行前最好确认所有插件的兼容性。有些插件没有适配 Vue3在 HBuilderX 里编译时不会报错但跑到微信开发者工具里会出现各种怪异问题比如样式丢失、组件不渲染。这种情况检查控制台编译输出把 Vue 版本和插件支持的版本对应上。HBuilderX 发行时如果遇到“文件过多”或者编译超时绝大多数情况是node_modules被误编译了。检查一下项目根目录下的.gitignore或者 HBuilderX 的排除配置确保node_modules、unpackage不在源码目录内被重复扫描。4.2 审核提交类目、隐私和常见驳回原因微信小程序上线前必须经过审核。校园维修系统这类业务类目我建议选择“教育 → 校园服务”如果是综合性的后勤服务也可以选“工具 → 效率”。审核被驳回是常态不用怕。常见的驳回原因和被套路我都帮你总结好了第一个是“涉及用户隐私未声明”。只要你的小程序用了wx.login、chooseImage、getLocation、requestSubscribeMessage这些能力微信公众平台的“设置 → 用户隐私保护指引”里就必须如实声明对应字段。很多第一次上线的项目都是在这个环节被卡住的。解决方案很简单把收集的信息类型勾选清楚并写明用途。第二个是“功能需要登录才能使用”被认定为体验不完整。这个有点冤枉因为校园维修系统的核心功能确实需要登录才能用。处理方式是让首页至少能浏览一些公开内容比如维修进度查询入口、公告信息、报修须知等不要一进来就弹登录框。我当时在首页放了一个“报修进度查询”的公开入口用户输工单号就能查状态审核就通过了。第三个是“类目与服务内容不符”。如果你的系统里做了维修工接单管理这种偏企业内部的功能但类目选了工具类审核员可能觉得你有“信息服务平台”属性要求补充对应资质。校园场景一般还好如果被要求提供资质可以在类目描述里写清楚“仅服务于本校区后勤维修”并附上相关说明。还有一个高频驳回原因是“含有诱导分享行为”。特别注意不要在界面上写“分享给好友领红包”“分享后才能查看”之类的话这在微信规则里是红线。我上面的分享设计是纯功能性的不会触发这个限制。4.3 上线后的监控与版本迭代小程序发布之后不是完事了。这里给几个实用建议第一微信公众平台的数据分析里可以看访问趋势、用户画像但看不到具体的接口报错。所以要在代码里埋点比如封装request.js的时候把所有请求失败的地方统一上报。我实际用的是一个简单的方案把错误信息uni.setStorage存到本地下次启动时批量上报到后端一个日志接口或者直接在onError里捕获全局错误。第二版本更新要克制。小程序发布后不是立刻覆盖所有用户的微信自带“小程序更新”机制但你可以在App.vue里做主动检查更新onLaunch() { if (uni.getUpdateManager) { const updateManager uni.getUpdateManager() updateManager.onUpdateReady(() { uni.showModal({ title: 更新提示, content: 新版本已经准备好是否重启应用, success: (res) { if (res.confirm) { updateManager.applyUpdate() } } }) }) } }第三权限和数据安全。维修工的姓名、电话、用户的宿舍地址都是敏感信息前端展示时要考虑脱敏比如电话显示成138****1234。后端日志不要打印完整的入参出参token 过期时间也不要调太长我一般是 7 天配合微信的静默登录逻辑用户基本无感知。5. 我踩过的坑排查思路和解决实录5.1 扫码不清晰的问题之前有个用户反馈说扫码报修“扫半天扫不出来”一开始我以为是设备二维码不平整后来发现是小程序扫码时默认使用的是后台相机有微距场景下对焦很慢。解决方案有两个改进一是给uni.scanCode增加onlyFromCamera: true和scanType: [qrCode]参数减少扫码类型识别范围二是引导用户把手机靠近二维码保持二维码在取景框内稳定 2 秒以上。如果是在实验室机柜这种光照不足的环境里扫码还可以在扫码页加一个“打开手电筒”按钮。这个功能需要自己建一个扫码页面而不是直接用wx.scanCode。如果嫌麻烦至少要在操作说明里提醒用户“光线不足时请打开闪光灯”。5.2 底部导航闪烁的真相很多用 UniApp 开发 tabBar 页面的同学应该都遇到过切换 tab 时底部导航栏“闪一下”的问题。刚开始我还以为是微信的渲染 bug后来查了代码才发现是自己写的锅。我在首页index.vue的onShow里做了数据请求而且请求回来之后直接修改了一个全局依赖的数据。页面切换时tabBar 页面可能会重新触发onShow导致整个页面数据重新渲染底部导航就跟着被重绘了。解决方法是把“切换 tab 后必须重新请求”的逻辑去掉改成只请求一次除非页面下拉刷新或者收到特定事件。如果确实需要每次进入页面都拉最新数据可以用uni.$once监听详情页的事件只在需要时刷新而不是一onShow就请求。另外一个小技巧如果 tabBar 页面本身很重不要把所有逻辑都塞到index.vue把不直接展示的内容拆成子组件并用v-show控制显隐减少不必要的挂载和销毁。5.3 web-view 高度与返回键冲突我在系统里做了一个“维修知识库”模块里面直接嵌了校园后勤的网页。小程序内嵌网页用web-view最简单但它有几个天生让人头疼的问题。第一个是高度。web-view在小程序页面里高度默认占满全屏如果你要自定义导航栏就会发现导航栏下面直接盖住了一大块网页内容。这个没有完美的解决方案最实用的做法是把web-view放整页不要和别的组件混排导航栏用微信自带的导航栏或者自己计算安全区域。第二个是返回键冲突。web-view里用户点了网页上的链接跳到了新页面这时点击手机返回键默认会直接退出小程序页面而不是先往回退一级。这是web-view的“历史栈”和小程序自身的页面栈不互通导致的。一个可用的处理方案是在网页内部通过wx.miniProgram.navigateBack()手动控制返回或者在小程序页面的onBackPress里想办法通知网页执行history.back()。但注意web-view网页与小程序之间的消息通信不是实时的postMessage的回调只能在特定时机触发比如页面被分享、组件销毁、后台切换到前台时。所以我在实际项目里是能少用web-view就少用纯功能部分都写成了原生页面之后维护也省心。5.4 iOS 静音模式下没声音如果系统里做了语音播报维修进度、或者维修完成后的提示音你大概率会遇到一个坑安卓上明明好好的一到 iPhone 上切了静音就完全没声音。这是因为 iOS 静音开关会阻止绝大多数音频从扬声器播放。小程序里的wx.createInnerAudioContext、UniApp 里的uni.createInnerAudioContext默认会跟随 iOS 静音开关。解决办法是在创建音频实例时设置const audioCtx uni.createInnerAudioContext() audioCtx.obeyMuteSwitch false把obeyMuteSwitch设为false音频就不会被 iOS 的静音开关拦截。obeyMuteSwitch只对 iOS 有效安卓端设置后没有副作用所以建议统一加上。另外如果维修进度提醒是用订阅消息而不是语音就没有这个烦恼。所以我的建议是语音播报只作为辅助核心通知还是要靠订阅消息兜底毕竟用户可能根本没有打开小程序。5.5 样式穿透与 Vue2 转 Vue3最后一个实用细节样式问题。UniApp 的scoped样式默认不会影响子组件内部但是在组件化开发中我们经常需要微调第三方组件的内部样式这个时候就涉及样式穿透。在 Vue2 的 Sass/Less 中深度选择器是/deep/在 Vue3 中推荐使用:deep()。我在项目里统一用的是:deep()写法是.test-card { :deep(.u-card__content) { padding: 20rpx; } }如果你从 Vue2 迁移到 Vue3除了深度选择器还要留意这些差异Vue2 的过滤器filters在 Vue3 中删掉了需要改成函数或计算属性this.$set不再需要Vue3 的响应式系统已经全面支持动态属性添加v-model的.sync修饰符统一变成了参数v-model:propName。UniApp 在 Vue3 模式下默认使用 Vite 编译首次编译会稍微慢一点但热更新体验比旧版好不少。如果项目里用的 UI 组件库比较老建议先检查是否发布了 Vue3 版本uView 2.0 之后对 Vue3 的支持才算完善uView Plus 是专门为 Vue3 出的。做校园维修系统这段时间下来我最深的体会是这类业务系统真正的难度从来不在某一个技术点上而在于把所有环节串起来的时候每个链接处都有意想不到的细节。比如一个“用户提交报修”的小功能背后可能就是表单校验、图片压缩、上传重试、权限申请、订阅消息、生成工单号、通知管理员这么一长串链路。你把这些链条上的细节都处理好了系统自然就稳定了。如果后面有时间我打算在这个项目上再扩展几个方向一个是维修耗材的库存管理维修工提交完成时可以顺手扣除对应材料库存另一个是维修数据的可视化报表按楼栋、按报修类型统计高频问题方便后勤有的放矢地维护。这些都是在现有状态机之上做增量骨架不用大改。如果你照着这个结构做后续扩展也基本不会遇到推倒重来的情况。
返回列表