前端工程搭建与用户访问流程设计

本阶段我的主要工作是把 StoryVerse 的前端从"可以运行的 Vue 项目"推进到"具备基本产品访问流程的前端应用"。项目的业务目标不是普通信息展示网站,而是一个围绕小说上传、剧情节点选择和实时角色扮演展开的交互式系统。因此前端基础建设不能只停留在页面跳转,而要提前考虑登录态保存、路由权限、统一请求封装、导航结构和后续页面之间的数据流转方式。这个阶段的代码主要集中在

复制代码
frontend/src/router/index.ts

frontend/src/utils/axios.ts

frontend/src/stores/auth.ts

frontend/src/views/LoginView.vue

frontend/src/views/RegisterView.vue 

 frontend/src/components/AppNavBar.vue

我首先梳理了前端页面边界。系统至少需要登录页、注册页、首页、小说上传页、游戏读取页、剧情节点选择页和游玩页。不同页面的访问条件并不一样:登录和注册只应给未登录用户访问,首页、上传、开始游戏、游玩页则必须要求登录。基于这个判断,我在 Vue Router 中给路由增加了 meta 字段,用 requiresAuthguestOnly 表示页面访问规则。这样后续新增页面时,不需要在每个页面组件里重复判断登录状态,而是在路由层统一处理。

关键代码如下:

复制代码
router.beforeEach((to) => {
  const { isLoggedIn } = useAuth()

  if (to.meta.requiresAuth && !isLoggedIn.value) {
    return {
      name: 'login',
      query: { redirect: to.fullPath },
    }
  }

  if (to.meta.guestOnly && isLoggedIn.value) {
    return { name: 'home' }
  }
})

这段代码的意义不只是"未登录跳转登录页"。我在这里保留了 redirect 参数,原因是后续用户可能直接访问 /upload/play/:sessionId,如果简单跳到登录页再回首页,会破坏用户原本的操作意图。保留 redirect 后,登录成功可以回到原目标页面。

登录态管理方面,我没有把用户信息只放在登录页组件里,而是抽成了 useAuth。实现时使用 Vue 的 ref 保存当前用户,同时把用户信息写入 localStorage。这样页面刷新后,登录态不会立即丢失。由于 localStorage 中的数据可能被用户手动修改,也可能因为旧版本结构变化导致不符合预期,所以读取时我做了类型校验和异常清理。

复制代码
function readStoredUser(): AuthUser | null {
  const raw = window.localStorage.getItem(STORAGE_KEY)
  if (!raw) {
    return null
  }

  try {
    const parsed = JSON.parse(raw) as Partial<AuthUser>
    if (typeof parsed.userId === 'number' && typeof parsed.username === 'string') {
      return {
        userId: parsed.userId,
        username: parsed.username,
      }
    }
  } catch {
    window.localStorage.removeItem(STORAGE_KEY)
  }

  return null
}

这个实现解决了两个问题。第一,刷新页面后 router.beforeEach 依然能判断用户是否登录;第二,本地存储出现异常时不会让整个页面白屏,而是自动清理错误数据并回到未登录状态。这个细节在调试时很有价值,因为前端状态和浏览器缓存经常会影响测试结果。

接口层我封装了 axios 实例,并设置统一的 baseURL 和超时时间。项目后端默认运行在 http://127.0.0.1:8080,但前端不能把这个地址散落在每个页面里,否则后续切换环境会非常麻烦。因此我在 frontend/src/utils/axios.ts 中处理:

复制代码
const request = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL || 'http://127.0.0.1:8080',
  timeout: 30000,
})

响应拦截器目前只返回 response.data,这让页面层不需要每次都写 response.data.data 或处理 Axios 的完整响应结构。这个封装也为后续统一错误提示、统一鉴权头、统一登录失效处理留下扩展位置。

登录页和注册页的开发,我重点处理了表单状态和用户反馈。登录页使用 reactive 保存用户名、密码,用 loading 控制按钮禁用,用 errorMessage 显示失败原因。提交前先做空值校验,避免明显无效请求打到后端。登录成功后调用 setUser 写入用户状态,然后根据路由中的 redirect 跳转。

复制代码
const redirect = typeof route.query.redirect === 'string' ? route.query.redirect : '/'
await router.push(redirect)

这个细节和路由守卫形成闭环:用户访问受保护页面,被重定向到登录页,登录成功后再回到原页面。注册页则在注册成功后跳回登录页,并携带 registeredusername 参数,便于后续扩展注册成功提示。

导航栏部分,我实现了 AppNavBar.vue,负责展示主导航、品牌名、当前用户和退出按钮。退出逻辑调用 logout() 清理本地登录态,然后跳转登录页。这让"登录、受保护路由、导航展示、退出登录"形成完整的访问闭环。

本阶段遇到的主要问题是:前端页面之间并不是孤立的,登录状态、路由跳转和接口调用会互相影响。如果每个页面都自己处理登录和请求,短期看能运行,后期会很难维护。因此我把用户态、请求实例和路由权限提前抽离出来。虽然这部分没有复杂算法,但它决定了后续页面能否稳定扩展。后面开发小说上传、首页、剧情选择、游玩页时,都直接复用了这个基础结构,没有再重复写登录判断和请求配置。

从工作量上看,本阶段完成了前端项目的基础访问框架,包括登录注册页面、登录态持久化、路由权限控制、统一请求层、导航栏和页面标题管理。更重要的是,我在这个阶段明确了前端的责任边界:前端不仅负责展示页面,还要负责把用户操作组织成连续、可恢复、可验证的业务流程。这为后续核心功能开发打下了基础。

相关推荐
海上彼尚2 小时前
Nodejs也能写Agent - 16.LangGraph篇 - 条件分支与循环
前端·后端·langchain·node.js
To_OC3 小时前
从 “卡死半天” 到 “打字机效果”:大模型流式输出前端实现全记录
前端·javascript·llm
SoaringHeart3 小时前
Flutter最佳实践:键盘辅助视图输入框天添加图片附件
前端·flutter
kyriewen3 小时前
我看完这篇安全论文——AI推荐的npm包,92%是编出来的
前端·javascript·ai编程
小心我捶你啊5 小时前
数据采集和Web解锁不是一回事,从用途到规则区分
前端·爬虫·网络协议
hunterandroid5 小时前
[鸿蒙从零到一] ArkUI 基础组件实战:Text、Image、Button 与 TextInput
前端
fsssb5 小时前
Chromium 源码学习笔记(五):一次点击,在进入 JS 之前先经历了什么?
前端
hunterandroid5 小时前
WorkManager 可靠性实战:唯一任务、重试与幂等设计
android·前端
鹿目5 小时前
使用 Vant CLI 搭建 UI 组件库:从 H5 到小程序跨平台
前端·javascript