Skip to content

项目深挖 必问(UniApp 实战) ​

项目:飞啾运动微信小程序(uni-app)
本人主责:登录回跳 / 高德选点 / 活动列表滚动
签到、埋点、分享等为协作模块, 只简要带过。

口述开场先划清职责,再展开难点与方案;被追问协作模块时,可转回自己的三块主责。

默题口述(精简版)→ 题面卡 · 项目 · 实战
项目如何接到八股追问,见 知识串联 · 链 I。


你最熟悉的项目整体架构和技术选型是什么?为什么这么选? ​

项目是什么 ​

运动类微信小程序:活动浏览/报名、发布活动、定位选点、个人中心等。技术栈是 uni-app + Vue3(构建走 Vite),主端微信小程序。

选型怎么讲(重要) ​

uni-app 不是我定的。 入职时技术栈已定:业务以微信小程序为主、希望一套代码留 H5 扩展、团队熟 Vue。面试别吹成「我拍板选的」,可以说:

  • 我接手的是这套栈,主责是登录门控、选点、列表体验
  • 这套选型也有代价:接第三方能力时,先要过微信小程序合规,再可能撞上 SDK 与 Vite(ESM)形态不一致(见 高德)

地图相关取舍(我侧落地):

点怎么说
微信原生 <map>小程序底图拖拽用原生组件
高德能力公司已有高德配额;先踩过「开放文档接口 → 不合规 → 改 SDK」,再撞 bundle vs Vite ESM,加导出适配、不动内部
为何不换腾讯 LBS数据和配额已在高德,再买一套成本高

架构一句话:

text
业务页(Vue3 / uni-app)
  + 登录门控 / 请求封装 / 用户信息分发
  + 微信原生 map(底图)
  + 高德能力(检索 / 逆地理等,SDK 导出适配 Vite)

🎤 口述精简版 ​

飞啾是 uni-app + Vue3 的运动小程序,栈是团队定的。高德接入上:先按开放文档接口做,对照微信合规发现小程序不允许,改接 SDK;SDK 又是 bundle 导出、Vite 要 ESM,后来二次改造加 ESM 导出、不动内部。


该项目中你独立负责哪些核心模块? ​

模块你做什么怎么定位
登录回跳鉴权拦截、登录后回到原意图页、Composable 抽离主亮点
高德选点合规踩坑 → 改 SDK → bundle vs Vite ESM;二次改造加导出、不动内部主讲(合规 + 工程适配)
活动列表滚动iOS 假白与横跳治理,滚动模型改造主亮点(有排障深度)
签到 / 埋点 / 分享协作,联调过入口与登录门控只带过,不深挖

🎤 口述精简版 ​

我独立负责三块:登录回跳、高德地图选点、活动列表滚动。签到埋点分享是同事做的,我只联调过。


项目开发中遇到的最大难点是什么?如何排查、如何解决? ​

下面三块可任选深挖;建议按「高德接入 → 登录回跳 → 列表滚动」准备。口述总览见 题面卡 · 项目实战。

难点 1:高德接入(合规 → SDK → Vite/ESM) ​

怎么定位这段经历

面试里我会主动说:这段说难不算硬核——不是算法、也不是复杂业务建模。真正的问题分两层:一层是对微信小程序合规不熟,走了弯路;一层是接 SDK 时撞上构建形态不一致。后面那层技术上并不玄,难在当时排查方向偏了,在 import 写法上钻了很久。

完整链路(建议按时间讲)

① 第一版:照高德开放文档接口做

业务要做选点(检索、逆地理这类能力),公司侧地图是高德。我一开始就按高德开放平台文档里常见的接口方式接入——文档全、示例多,本地联调起来也快,功能上是能跑通的。当时注意力主要在「接口怎么调、选点流程怎么串」,没有先把「微信小程序允不允许这种接法」当成前置条件。

② 对照微信合规:小程序端不允许这条路

后面补看微信小程序侧的规范/审核要求,才发现:小程序端不允许直接用开放文档那种通用接口接入方式。开放文档那套更偏 Web / 通用 HTTP 场景;小程序对第三方地图能力有自己的约束,要走平台认可的路径。于是第一版等于白做了一遍,只能推倒重来,改接官方 SDK。

这一步的反思:小程序项目里,第三方能力要先问「平台认不认」,再问「接口好不好调」;合规不熟时,很容易先做出能跑、但不能上的方案。

③ 改接 SDK:又撞上 Vite / ESM

换 SDK 之后,业务调用方式对了,构建却过不去。原因在模块导出形态:

  • 这套高德 SDK 原来按 bundle 方式导出——整包、给偏传统打包/脚本引入用的形态;
  • 项目是 uni-app + Vite,开发期模块默认走 ESM(ECMAScript Modules,也就是规范的 import / export)。

Vite 解析依赖时按 ESM 去吃包,SDK 却不是按 ESM 友好方式把能力暴露出来,两边对不上,业务里怎么写 import 都接不稳。这也说明:栈是团队定的,但第三方包不一定为 Vite 准备好,适配成本会落到具体接入的人身上。

④ 解决:二次改造,向上兼容加导出,不动内部

我的做法不是重写 SDK,也不是在业务里用奇技淫巧硬绕:

  • 不动 SDK 内部实现(检索、鉴权、内部逻辑不乱改)——地图 SDK 动内部风险大,也容易和后续升级、审核搅在一起;
  • 在原有基础上做二次改造 / 向上兼容:补一种 ESM 认可的导出方式,让 Vite 能正常 import 进来;
  • 旧的 bundle 导出可以保留(兼容),业务侧按项目能吃的方式接入。

一句话:改的是「包怎么被工程认出来」,不是改地图能力本身。

⑤ 真正卡久的地方:思维钻牛角尖

回头看,「加一种导出」本身不复杂。当时卡住,是因为一直默认「问题在我怎么引用」——换相对路径、换默认导入/命名导入、换各种 import 写法试,越试越觉得是语法问题。等于在调用侧硬拧,没有先问清楚:这个包到底是以什么形态导出的。

想通「冲突在导出形态,不在 import 写法」的那一下,方案就顺了,偏灵光一现。面试也可以讲这句收获:构建类冲突,优先看包的入口和导出,再改业务引用。

真机其它坑(简表,追问再展开)

点处理
隐私与审核定位前隐私授权;授权三态
合法域名restapi.amap.com 等
cover-view 图钉不用 SVG,改 PNG
map 原生层残留onHide 卸 map(v-if)
拖地图狂请求防抖 + requestId,过期丢弃

🎤 口述精简版(高德单段) ​

选点接高德时,我先按开放文档接口做,功能能跑,但当时对微信小程序合规不熟。后来对照平台要求,发现小程序端不允许那种通用接口接法,只能改接官方 SDK。接 SDK 又撞构建:SDK 是 bundle 导出,项目 Vite 默认 ESM,对不上。我没改 SDK 内部,而是二次改造、向上兼容补了一种 ESM 导出,让工程能正常 import。整段技术上不算玄,真正耗时间的是我一度只在各种 import 写法里打转;想通要改导出形态之后才一下顺了。真机授权、域名那些是后续补的,面试官能问再展开。

难点 2:登录回跳(意图保持) ​

要解决什么

用户点「发布 / 报名」等需要登录的操作时,没登录会被拉去登录页。成功后要回到原来想去的地方;返回键不能再撞回登录页。本质是:意图保持 + 页面栈干净。

关键认知:小程序怎么跳

API白话栈变化
navigateTo打开新页,旧页还在多压一层
navigateBack关掉当前页弹掉一层
redirectTo用新页换掉当前页层数不变
switchTab去 Tab 页非 Tab 会被清掉

两种场景

  1. 仍在当前页办事(详情报名):navigateTo 去登录 → 成功 navigateBack 回详情继续
  2. 登录后要去另一页(首页点发布):先记 pendingUrl → 打开登录 → 成功用 redirectTo 换掉登录页进入目标页
text
正确:[首页] → [首页][登录] → redirectTo → [首页][发布]  (返回是首页)
错误:登录成功再用 navigateTo 打开发布 → 返回会先撞登录

怎么封装

  • 页面 / 弹窗:只管协议勾选、getPhoneNumber 等手势
  • Composable(如 useWechatLogin):拿 code、换 token、拉用户信息、广播登录态、清 code
  • 业务入口统一:ensureLogin / withLogin / goPageAfterLogin,不要每个按钮自己判断 token
  • pendingUrl 放内存,取消登录立刻清;跳登录加锁防连点;Tab 取消登录记拒绝态,避免 onShow 死循环

难点 3:活动列表 iOS 假白 / 横跳 ​

现象

活动列表在 iOS 上:筛完或列表变短后,底部还能滑出一块空白(假白);有人修过之后滑动还会左右/乱抖(横跳)。

假白原因

页面用的是整页滚动(page 滚,类似网页 body 滚)。筛选后内容高度变矮,iOS 上整页「可滚动高度」有时没收干净,滚动范围仍按旧的长列表算,底部就滑进空洞。

横跳原因

前人用「锁死外层高度」或疯狂 pageScrollTo 去纠偏假白 → 和手指抢滚动控制权 → 横跳。治标不治本。

正解

换滚动模型:外层页面不滚;内层用一屏高的 scroll-view 滚列表(类似 height:100vh; overflow:auto)。吸顶筛选用占位 + fixed;下拉刷新/触底走 scroll-view 事件。假白和横跳一起消。

注意:这和「虚拟列表」不是一类题——虚拟列表是 DOM 太多;这题是谁在滚选错了。

🎤 口述精简版 ​

难点可挑高德先讲:说难不算硬核。先按开放文档接口把选点跑通,但当时合规不熟;对照微信要求后发现小程序不允许那种接法,改接官方 SDK。SDK 又是 bundle 导出、Vite 要 ESM,对不上。做法是二次改造、向上兼容加 ESM 导出,不动 SDK 内部。真正耗时是一度只换 import 写法;想通改导出形态才顺。登录、列表另展开。


你对项目做过哪些性能优化、体验优化?优化前后对比? ​

优化点之前之后
活动列表滚动iOS 假白,锁高后又横跳,滑动体验差页内 scroll-view,滚动跟手,假白基本消失
登录跳转返回易撞登录页、连点多开登录redirectTo 换页 + 跳转锁 + 取消清意图
拖地图选点regionchange 狂打接口、偶发串数据防抖 + requestId,过期丢弃
选点页残留返回后输入框点不到隐藏页卸载 map 原生层
体积/启动(协作&常规)主包压力分包、资源压缩等(按项目实际补充数字)

对比话术:列表从「能滑但经常抖/露白」到「跟手且滚到底贴内容」;登录从「返回陷阱」到「栈干净」。

🎤 口述精简版 ​

体验上我重点修了列表滚动和登录回跳:列表换成容器内滚动,登录成功用换页而不是再叠一层。选点拖拽加了防抖和请求序号,避免乱序回写。


UniApp 项目中遇到过多端兼容问题吗?具体怎么处理? ​

本项目主端是微信小程序,兼容问题更集中在小程序原生层 + uni 封装:

问题处理
map / cover-view 限制不按 H5 思路嵌 JS 地图;图钉用图片;注意原生层生命周期
整页滚动 iOS 表现差改 scroll-view 内滚
样式/安全区rpx 统一;刘海用安全区变量;差异大再条件编译
Tab 页不能 url 传参登录意图、业务状态走内存/store,不靠 query 硬传

🎤 口述精简版 ​

我们主打微信小程序。兼容上主要是原生组件和滚动模型:map 按原生方式管生命周期,列表避免依赖整页滚动的坑,单位用 rpx,端差异用条件编译。


Vue 项目中组件封装有哪些经验?如何实现组件复用?(结合本项目) ​

本项目里最典型的是登录逻辑复用,不是单纯 UI 组件:

  • 登录页 / 弹窗只负责协议勾选、按钮手势(如 getPhoneNumber)
  • useWechatLogin 一类 Composable 负责:校验、拿 wxCode、换 token、拉用户信息、广播登录态、清理 code
  • 业务侧统一走 withLogin / ensureLogin,列表按钮不要各自判断 token

好处:多入口同一套副作用;页面变薄;后续改登录协议只改一处。

🎤 口述精简版 ​

我把登录副作用抽成 Composable,页面只管授权手势;业务用统一的 withLogin 包一层。复用的是流程,不只是一个按钮组件。


项目中如何处理权限、登录态、用户信息持久化? ​

登录链路(简述) ​

text
勾选协议 → getPhoneNumber 拿 phoneCode → uni.login 拿 wxCode
→ 后端换手机号/openid 并签发 token → 本地存 token
→ 拉用户信息 → 写入全局状态 + 广播分发到各页

未勾选协议时不走手机号授权;code 用完清理,避免复用脏 code。

存储 vs 分发(面试常问) ​

东西放哪为什么
token本地存储(如 uni.setStorage)刷新/杀进程还要带着请求
用户信息登录后请求一次,进全局 store / 响应式状态各页读同一份,别每页各自打接口拼
分发登录成功 / 401 失效时广播(事件或 store 订阅)「我的」、首页头像等一起刷新或清空
回跳意图 pendingUrl只放内存取消登录立刻扔掉,别持久化脏地址

请求与 401 ​

  • 请求拦截:自动带 token、统一 loading
  • 业务码 / HTTP 401:清 token、Toast 节流、广播失效、再走同一套去登录(可带 pendingUrl)
  • 特殊接口可用 raw 请求跳过业务码包装

🎤 口述精简版 ​

token 本地存,请求头统一带。用户信息登录后拉一次放进全局状态,成功或 401 时广播,页面跟着刷新或清空。回跳地址只活在内存里,取消登录就扔。


项目上线前会做哪些打包、测试、优化操作? ​

结合本项目实际,上线前重点看:

  1. 合规:隐私协议弹窗、定位权限文案与拒绝引导、合法域名(含高德)
  2. 真机:选点页(授权三态、map 残留、搜索补坐标)、登录回跳两种场景、活动列表 iOS 滚动
  3. 体积:主包/分包、图片与无用页面、生产构建
  4. 回归:报名/发布等带登录门控的主路径;401 与取消登录
  5. 体验:弱网、连点登录、Tab 取消登录是否死循环

🎤 口述精简版 ​

上线前我最盯三块真机:登录回跳栈对不对、地图授权和选点稳不稳、列表在 iOS 还假白吗。同时查隐私合规、合法域名和主包体积。


1 分钟项目介绍(可直接背) ​

我这边做过不少偏后台的业务,面试里我重点讲 飞啾运动的微信小程序。

先说清楚:小程序是 后面才做的,和 App 不是同一套产品形态,版本也差了不少。App 侧要考虑得很全——客户下单、用户入驻、商家入驻等等,链路长、角色多。小程序一开始目标更聚焦:下单 + 核销 就够用,把「用户到店/到场完成履约」这条短链路跑通。

后面业务再往外延:又慢慢做了 俱乐部入驻、志愿者入驻 等能力,小程序从「轻履约入口」逐步补成更完整的一端,但整体仍然比 App 更收敛,不会把 App 那套全量角色和流程一锅端过来。

(技术细节、我具体啃的模块,面试官往下问再展开。)