整理几条真正会在项目里碰到的跨界面传参场景题,带参考答案,面试时可以直接讲。
先记一张选型表(面试先讲这个很加分)
| 场景 | 推荐方式 | 原因 |
|---|---|---|
| 列表点进详情,只传 id | 路由 query/params | 可收藏、可分享、刷新不丢 |
| 待办/邮件外链进审批页 | URL 带单号 | 和你们 ?reduceno=xxx 一样 |
| 列表筛选条件返回后要保留 | sessionStorage / Pinia | 参数多,不适合全塞 URL |
| 多步骤表单暂存 | Pinia / sessionStorage | 数据大、临时性强 |
| 全局用户信息、权限 | Pinia + 接口 | 跨很多页面都要用 |
| 兄弟组件通信 | 事件总线 / provide-inject | 不跨路由 |
| 大对象、敏感信息 | 不要放 URL | 长度限制、泄露风险 |
场景题 1:列表页点「查看」,详情页怎么拿参数?
题目: 项目查询列表,点击某一行的「查看」,跳到详情页,你怎么传 projectId?
参考答法:
只传 id,详情页自己调接口拉数据,不要把整行对象塞进路由。
Vue Router 用 query 或 params 都行,我们项目里常见是 query,方便外链和待办跳转。
// 列表页
this.$router.push({
path: '/report/project/detail',
query: { projectId: row.id }
})
// 详情页
const projectId = this.$route.query.projectId
// 或 Vue3: const route = useRoute(); route.query.projectId
追问:query 和 params 区别?
- query:
?projectId=123,刷新还在,适合你们这种?reduceno=xxx - params:动态路由
/detail/:id,更 REST,改 id 要配路由
加分点: 详情页要判断 id 为空时提示并返回列表,避免白屏。
场景题 2:详情页返回列表,筛选条件怎么不丢?
题目: 用户在列表搜了条件、翻了第 3 页,进详情再返回,怎么保持原来的筛选和页码?
参考答法:
URL 只适合传少量参数,筛选条件多时用 sessionStorage 或 Pinia 存列表状态;
或用
router.push返回时把 query 原样带回去。
方案 A:离开列表时缓存(常用)
// 列表页 beforeRouteLeave / onBeforeUnmount
sessionStorage.setItem('projectListState', JSON.stringify({
form: this.searchForm,
page: this.pageNum
}))
// 列表页 mounted / onActivated
const cache = sessionStorage.getItem('projectListState')
if (cache) {
const { form, page } = JSON.parse(cache)
this.searchForm = form
this.pageNum = page
this.fetchList()
}
方案 B:列表用 keep-alive
<keep-alive include="ProjectList">
<router-view />
</keep-alive>
列表组件名要固定,返回时组件实例还在,状态自然保留。
面试话术:
「简单场景用 keep-alive;要跨标签页或刷新后还要恢复,用 sessionStorage + Pinia。」
场景题 3:待办/ OA 外链跳进你们系统审批页(你们项目真实场景)
题目: 后端待办里拼的 URL 是 /approve/reduceform?reduceno=xxx&clientId=yyy,前端怎么处理?
参考答法:
这种是 标准外链场景,参数必须放 URL,前端在审批页
created里读 query,用单号调详情接口。和你们 Java 里
param.put("pcurl", frontUrl + pcRoute + "&clientId=" + clientId)是一套思路。
// 审批页
const { reduceno, clientId } = this.$route.query
if (!reduceno) {
this.$message.error('缺少单号')
return
}
await this.loadForm(reduceno)
注意点:
- 单号放 URL 可以,token 不要长期放 URL
clientId等多租户参数要一并带上- 页面要处理「无权限 / 单号不存在」
场景题 4:列表勾选多条,跳到批量处理页,怎么传?
题目: 列表勾选 20 条记录,点「批量审批」,下一页要用这些 id,怎么传?
参考答法:
不要把 20 个 id 拼成超长 query。
做法:Pinia / sessionStorage 存
selectedIds,路由只传一个标记或业务类型。
// 列表页
sessionStorage.setItem('batchIds', JSON.stringify(selectedIds))
this.$router.push({ path: '/batch/approve', query: { type: 'reduce' } })
// 批量页
const ids = JSON.parse(sessionStorage.getItem('batchIds') || '[]')
追问:为什么不用 Vuex 全局变量?
可以,但刷新就丢了;sessionStorage 关标签页可清,更适合「一次性批量操作」。
处理完要 清掉缓存,避免下次误用旧数据。
场景题 5:新建页填了一半,切到别的菜单再回来,数据要不要留?
题目: 用户填了半张表单,误点侧边栏走了,回来希望数据还在,你怎么做?
参考答法:
分两种产品要求:
-
要保留:
sessionStorage按表单 key 自动保存草稿,或 Pinia 存 draft -
不要保留:
beforeRouteLeave弹确认框,离开就丢beforeRouteLeave(to, from, next) {
if (this.isDirty) {
this.$confirm('有未保存内容,确定离开?').then(() => next())
} else next()
}
加分点: 定时 debounce 写 localStorage 做草稿恢复,你们 ERP/审批系统很实用。
场景题 6:父页面打开子页面填完带回数据(弹窗 vs 新路由)
题目: 详情里点「选择供应商」,选完要把供应商带回当前页,怎么做?
参考答法:
| 方式 | 适用 |
|---|---|
| 弹窗/抽屉组件 | 最常用,选完 $emit 回传,不走路由 |
| 子路由 | 流程复杂、要保留浏览器历史时 |
| EventBus / mitt | 老项目,解耦但不推荐滥用 |
// 弹窗选完
this.form.supplierId = row.id
this.form.supplierName = row.name
this.supplierDialogVisible = false
面试话术:
「能弹窗解决就不新开页;必须跨页时,回传用 emit 或 Pinia,别用 URL 传对象。」
场景题 7:keep-alive 页面怎么在「再次进入」时刷新数据?
题目: 列表被缓存了,但从详情改完数据返回,列表要更新,怎么办?
参考答法:
// Vue2
activated() {
// 从详情返回时重新拉列表
if (this.$route.meta.refreshList) {
this.fetchList()
this.$route.meta.refreshList = false
}
}
// 或详情页返回前
this.$router.replace({
path: '/list',
query: { _t: Date.now() } // 触发更新
})
Vue3 用 onActivated,思路一样。
场景题 8:新标签页打开详情,参数怎么传?
题目: 列表右键「新窗口打开」,怎么做?
参考答法:
const route = this.$router.resolve({
path: '/detail',
query: { id: row.id }
})
window.open(route.href, '_blank')
关键: 新标签是全新应用实例,不能依赖 Pinia 内存,只能靠 URL 或 localStorage。
场景题 9:哪些参数绝对不能乱传?
面试常问,直接背:
- Token、密码 → 不放 URL,放 Header / HttpOnly Cookie
- 大对象、整表数据 → 不放 URL,调接口或 sessionStorage
- 敏感业务数据 → URL 会进浏览器历史、服务器日志
- 只靠前端传参做权限 → 不行,后端必须再校验
场景题 10(综合题):设计「项目查询 → 详情 → 审批」整条链路
题目: 从项目查询进详情,再点审批,参数和状态你怎么设计?
参考答法(结构化):
- 列表 → 详情:
query.projectId - 详情 → 审批:
query.reduceno或planno(和你们后端一致) - 列表状态:
keep-alive+sessionStorage存筛选 - 审批结果回写:审批完
router.back()或跳回列表,并设meta.refreshList = true - 待办外链:和后端约定统一
pcurl格式,前端审批页只认 query 单号
面试时 30 秒总结(可原样说)
我们项目跨页传参原则是:能放 URL 的只放 id、单号这类标识;筛选、批量选中、草稿用 sessionStorage 或 Pinia;全局用户权限放 状态管理;弹窗选人用 emit。外链待办和 OA 跳转必须 URL 带单号,详情页自己调接口,前后端都校验权限,不依赖前端传参做安全控制。