宁语之溪
一年好景君须记,最是橙黄橘绿时。 (宋·苏轼· 赠刘景文)
自豪地使用 Typecho 建站搭配使用 🌻Sunny 主题博主 昨天 13:54 在线 · 当前 1 人活跃
文章

Vue 3 用户端与管理端如何共享后端能力

语之溪

·

代码

·

⚠️ 本文最后更新于2026年02月21日,已经过了184天没有更新,若内容或图片失效,请留言反馈

在线视频平台的用户端和管理端面向不同角色:用户端关注浏览、播放、上传和互动,管理端关注用户、内容、审核和权限。两个前端的界面差异很大,但都需要调用同一套后端能力。

在 HAOVP 中,我分别建立 Vue 3 用户端和管理端。共享后端不等于复制接口代码,也不等于让两个前端共用所有页面组件。更重要的是统一接口契约、认证方式、类型定义和错误处理。

先明确两端职责

用户端主要面向普通用户:

  • 注册与登录;
  • 浏览和搜索内容;
  • 播放、上传与互动;
  • 个人资料和使用记录;
  • 移动端访问。

管理端主要面向运营和管理角色:

  • 管理员登录;
  • 用户状态管理;
  • 内容审核与治理;
  • 分类、标签和评论管理;
  • 角色、权限和操作记录。

两端可以调用相同业务服务,但不能只依靠页面入口区分权限。后端仍要根据身份、角色、数据范围和业务状态判断操作是否合法。

共享的是接口契约

一个接口契约至少包括:

请求方法与路径
请求参数
字段类型和必填规则
认证要求
正常响应结构
错误码与错误结构
分页与排序约定

例如用户端和管理端都需要获取视频详情,但返回字段和权限可能不同。普通用户只能看到公开内容,管理员还需要审核状态和治理信息。

可以使用不同接口,也可以在统一服务中根据权限返回合适的数据。关键是契约清楚,不能让前端根据隐藏字段自行判断权限。

建立统一的请求封装

两个前端都需要处理基础地址、Token、超时和错误响应。可以在各自项目中建立相同约定的请求层:

export interface ApiResponse<T> {
  code: string;
  message: string;
  data: T;
}
export async function request<T>(config: RequestConfig): Promise<T> {
  const response = await http<ApiResponse<T>>(config);
  if (response.data.code !== "SUCCESS") {
    throw new ApiError(response.data.code, response.data.message);
  }
  return response.data.data;
}

代码是简化示例,不对应项目的真实响应码、请求库和文件结构。

共享约定可以减少差异,但用户端和管理端仍可根据各自交互方式展示不同错误提示。

TypeScript 类型从哪里来

如果两个前端分别手写同一份接口类型,后端字段变化后很容易漏改一端。

可以考虑:

  • 建立独立的共享类型包;
  • 根据 OpenAPI 生成类型;
  • 从统一接口文档维护模型;
  • 只共享稳定 DTO,页面状态类型留在各端;
  • 在 CI 中检查生成文件是否最新。
export interface VideoSummary {
  id: string;
  title: string;
  coverUrl: string;
  status: string;
}

示例字段是抽象结构。真实业务中,管理端状态和用户端可见状态未必使用同一类型,不能为了共享而暴露内部字段。

认证流程可以统一,令牌存储要谨慎

用户端和管理端都可能使用 Access Token 与 Refresh Token,但认证主体和权限边界可以不同。

我会明确:

  • 用户 Token 不能访问管理接口;
  • 管理员 Token 不能因为权限高就绕过业务服务规则;
  • 刷新接口与普通业务接口分开;
  • 两端分别处理登录失效和刷新并发;
  • 请求日志不记录完整 Token;
  • 客户端存储方式结合 XSS、CSRF 和部署方式决定。

请求封装可以共享思路,但不能硬编码真实 Secret、账号和认证地址。

错误处理分为通用层和页面层

请求层适合处理:

  • 网络失败;
  • 超时;
  • 未认证;
  • 权限不足;
  • 统一业务错误结构;
  • 请求标识记录。

页面层适合处理:

  • 表单字段错误;
  • 当前业务状态不允许操作;
  • 是否保留用户输入;
  • 重试和返回入口;
  • 具体业务提示。

如果所有错误都在拦截器中弹出同一条消息,页面无法根据业务场景提供正确反馈。

分页和筛选要统一约定

用户端和管理端都会出现列表,但管理端通常筛选条件更多。

需要统一:

页码从 0 还是 1 开始
每页数量字段名
总数与总页数
排序字段格式
空值筛选方式
日期范围边界

后端返回统一分页结构,两个前端再根据页面需要组织表格、卡片或移动列表。

文件上传可以共享流程,不共享页面

用户端上传视频,管理端可能上传封面或其他资源。它们都可以复用上传协议:

  • 创建上传任务;
  • 选择或校验文件;
  • 显示进度;
  • 处理取消和失败重试;
  • 查询处理状态;
  • 完成后更新业务记录。

但用户端更关注操作体验,管理端更关注状态、审核和异常处理。共享后端流程不意味着两端使用完全相同的组件。

权限信息怎样驱动页面

后端可以返回当前用户的基础权限或可执行动作,前端据此展示入口。

{
  "actions": ["VIEW", "EDIT"],
  "status": "DRAFT"
}

这是通用示例。隐藏按钮只是用户体验,后端接口仍需再次校验权限和状态。

管理端尤其要避免把全部权限规则写死在前端路由中。角色或权限变化后,前端缓存也需要更新。

是否建立共享前端包

共享代码可以减少重复,但也会增加两个项目之间的耦合。

适合共享的内容:

  • 稳定 API 类型;
  • 通用响应模型;
  • 不含业务页面的工具函数;
  • 日期和文件等基础格式化;
  • 统一错误类型。

不一定适合共享:

  • 页面路由;
  • 角色专属组件;
  • 交互状态;
  • 大量依赖某个 UI 框架的组件;
  • 频繁变化的页面模型。

如果共享包每次修改都迫使两端同时发布,说明边界可能过大。

联调时的检查顺序

接口文档与类型一致
    -> 两端请求参数一致
    -> 认证信息正确
    -> 正常响应能解析
    -> 错误响应能处理
    -> 权限与状态由后端确认
    -> PC 与移动场景分别验证

我会特别检查一个接口在用户端和管理端是否使用了不同字段含义,以及后端变化后是否只有一端完成更新。

Vue 3 用户端与管理端共享后端能力,核心不是复用越多越好,而是稳定契约统一、业务权限清楚、前端职责独立。共享类型和请求约定可以减少重复,页面、交互和角色规则则应保留各自边界。

现在已有 10 次阅读,0 条评论,0 人点赞
评论:共0条
发表
搜索 消息 足迹 排行
你还不曾留言过..
你还不曾留下足迹..
博主 不再显示
博主
未知作品 歌曲封面
立即安装