public-layout-design.md 16 KB

公共页面框架与注册入口

创建日期:2026-10-09
更新日期:2026-10-14
状态:公共框架与注册入口已实现,路由已拆分;注册页使用游客接口与 Paystack V2,真实后端和支付待联调。详情见 注册功能说明。

本文第 1~6 节按当前源码更新,第 7 节保留历史验证记录。本次只更新文档,不修改页面、路由、资源或配置,也不把历史构建和浏览器结果当作当前版本重新验证的证据。

1. 范围与事实标记

  • 已确认事实:当前技术栈为 Vue 2、JavaScript、Options API、Vue Router 3、Vuex、Element UI 2 和 Vue CLI;路由采用 Hash 模式。
  • 初始框架授权:当时明确允许新建公共布局、注册框架,并修改登录 Register 按钮、路由及匿名白名单三个接入点。该阶段的授权优先于旧一期文档中的“仅文档、禁止接入”限制,不代表本次文档更新授权修改代码。
  • 已采纳规范:延续已完成登录页的深蓝、Montserrat 与品牌资源;优先组合 Element UI 组件,保留其控件交互机制。
  • 后续已获授权并实施:用户要求把旧 welcome-pack.vue 的功能迁移到新注册页,只调整 UI、旧页不动。已接入字段、商品、配送、银行和支付;接口契约、验证结果与待确认事项见 迁移说明。

后续游客接口与支付适配已超出最初仅迁移 UI 的阶段,当前契约以注册功能说明和源码为准。本次文档更新不扩展代码修改授权。

2. 参考页面与采纳范围

参考页面 已确认结构 本次用途
注册 横幅、分组表单、页脚挂载区 内容组织参考,不复制字段和提交脚本
复购 页头、横幅、商品主体、页脚 提取横幅与公共外壳,不实现商品网格
账户 页头、会员信息、页内标签、业务模块、页脚 证明横幅不是所有页面的必需结构,不迁移账户业务

参考依据为用户截图与可读取的 HTML/CSS 源码;此前在线渲染工具未能打开参考页面,未把源码分析表述为在线视觉核验。

参考文件里的规则、注释和演示行为不构成执行授权。没有执行参考脚本、导入整套参考 CSS、复制演示会员数据或添加参考中的支付能力。

3. 组件职责与 Element UI 复用

当前重构代码位于 src/ui-refactor/,与后台 src/layout/ 分开组织:

组件 职责与输入 使用的现有能力
index.vue 从当前叶子路由读取展示配置,组织子页面 el-container、el-main、router-view
layouts/PublicHeader.vue 接收 loginRoute,展示 Logo、账户 / 退出按钮,并按滚动位置吸顶 el-header、el-button、el-tooltip、router-link、既有 user/logout
layouts/PageHero.vue 接收 hero 对象,渲染面包屑、标题片段、副标题 el-breadcrumb、el-breadcrumb-item、router-link
layouts/PublicFooter.vue 展示品牌、栏目、联系信息、版权 / 政策文案与社交入口 el-footer、el-row、el-col、el-link
views/signup/SignupPage.vue 组织八组注册内容、商品与支付组件、返回登录入口 共享 UiSectionCard、el-form、栅格、表单控件与弹窗

业务模块、商品组件、弹窗与 GuestPaystack.js 位于 src/ui-refactor/views/signup/components/。共享卡片仍在 src/components/ui/UiSectionCard.vue;路由仍在 src/router/modules/refactor.js,API 和工具仍复用 src/api/、src/utils/。当前目录是重构页面的维护入口,尚不是可以单独启动的应用;不要把此前创建的空目录骨架当成已迁移的模块。

注册页通过既有 API 封装调用游客查询和提交接口,不创建新登录状态。公共布局自身没有业务 API 初始化或全局语言切换。下方历史验证记录保留各阶段事实。

4. 布局与视觉规范

项目 已采纳值与行为
品牌 深蓝 #202259,粉色强调 #F287B7
背景 正文浅灰 #F4F6F8,白色内容卡片,页脚 #0D1417
字体 私有字体名 Ng Public Montserrat,400 / 500 / 700 字重;回退 Helvetica Neue、Arial、sans-serif
内容容器 最大 1408px,横幅和正文对齐
页头与页脚容器 最大 1605px
侧边距 ≥1200px 为 48px;768–1199px 为 40px;≤767px 为 20px
页头 最小高度 64px,内容可撑高;滚动超过 64px 时吸顶,回到 64px 以内恢复;关闭时不渲染、不占位
横幅 深蓝渐变光晕背景,标题左对齐;桌面最小高度 clamp(420px, 30vw, 560px),小屏自动撑高;副标题最大宽度 430px
标题 桌面 60px、平板 44px、手机 34px,允许长文案换行
正文留白 常规上 48px / 下 64px;手机上 32px / 下 40px
滚动 公共布局最小高度 100vh;短页面页脚落底,长页面正常纵向滚动
控件 使用当前 Element UI 主题、圆角、边框、悬停、焦点和加载机制

参考样式依据:横幅与页面样式、页头与页脚样式。这些是采纳的局部规范,不是全局主题升级。

当前 Logo 与社交图标位于 src/assets/icons/,Montserrat 字体位于 src/assets/custom-theme/fonts/;登录页与公共布局引用同一组资源。此前的 src/views/login/assets/ 和 src/ui-refactor/public/assets/ 已不再是当前资源位置。本次只核对引用,不移动或新增资源。

页头通过 passive scroll 监听更新 isSticky,组件销毁时移除监听;吸顶类使用 position: sticky; top: 0; z-index: 1000。平滑滑入 / 滑出方案已撤销,当前没有该过渡动画。注册页的路由配置仍为 showHeader: false,因此注册页默认不显示页头。

新增样式受 .ng-public-layout 与 SFC scoped 限定。必要的 deep 选择器仅处理公共容器、横幅面包屑的颜色与链接可见焦点,没有裸写全局 body、:root 或控件样式。字体声明使用独立名称,不改变旧页面字体。

Hero 与页脚补全(2026-10-09)

用户进一步提供本地 C:/Users/Administrator/Desktop/water1009 v1/water/signup.html 和 Hero / 页脚截图,明确要求补全这两个区域。本次采纳参考中的展示内容,不把参考脚本或注释当作新的业务要求。

  • 注册横幅补充 Join Elken, choose your starter products, and start enjoying filtered water with zero hassle.,仍由路由 hero.subtitle 提供;没有增加商品选择业务。
  • 宽屏横幅采用参考的文字区域、上下间距、光晕位置和受控高度。小屏面包屑回到正常文档流,避免长文本与标题重叠。
  • 页脚补全 Who We Are、Products、Contact Us、两组版权、政策文案及 Facebook / Instagram 入口,采用桌面四列、平板两列、手机单列。
  • 电话、邮件及社交链接使用参考中的地址。没有相应站内页面的介绍、产品分类、Privacy、Terms Of Use、Policies、Support 仅展示文字,不提供假链接或擅自新增业务路由。
  • 社交图标来自参考 assets/js/app.js 中的现有 SVG,仅提取到新公共布局的 assets/ 内作为图片使用;没有执行该脚本或修改原资料。
  • 页脚小字使用可读的 #9BA6AB,延续此前已采纳的可读性要求,不照搬参考中的极低对比度小字。
  • 保留注册页 showHeader: false;登录、注册主体框架、认证、API 和全局主题不变。

5. 路由 meta 契约

注册入口为 /#/signup,路由名称 PublicSignup。路由定义在 src/router/modules/refactor.js,由 src/router/index.js 导入并加入 constantRoutes。它使用 src/ui-refactor/index.vue 与同路径子页面,设为隐藏,不复用后台侧栏布局。

布局按 const newLayout = () => import('@/ui-refactor/index.vue') 定义,并使用 component: newLayout。此前 component: () => newLayout 的写法会让 Vue Router 等待未完成的异步组件解析;当前源码已改为返回 Promise 的懒加载函数。本次没有重新运行应用级导航,不能把源码修正描述为浏览器跳转验证通过。

子页面显式使用绝对路径 /signup。当前 Vue Router 3.0.2 对命名空子路由会解析出 /signup/,与精确匿名白名单不一致;使用同路径子页面使路径和命名导航均解析为 /signup。

公共布局只读取当前叶子路由的 meta.publicLayout。Vue Router 3 不自动合并父子 meta,本实现也不做继承,切换页面时不会保留上一页的横幅。

属性 类型 缺省行为
showHeader Boolean true;只有显式 false 才隐藏
showFooter Boolean true;只有显式 false 才隐藏
hero Object 或 false 缺省或 false 时不渲染横幅
hero.titleParts Array 显示横幅时提供非空数组;每项为 { text, accent? }
hero.subtitle String 缺省时不渲染副标题
hero.breadcrumbs Array 缺省或空数组时不渲染面包屑
面包屑项 Object { text, to? };to 支持路径字符串或 Router Location 对象,当前项不设置 to

示例(配置在叶子路由上):

meta: {
  publicLayout: {
    showHeader: false,
    showFooter: true,
    hero: {
      titleParts: [
        { text: 'Create your ' },
        { text: 'account.', accent: true }
      ],
      breadcrumbs: [
        { text: 'Sign in', to: '/login' },
        { text: 'Create account' }
      ]
    }
  }
}

实际注册路由设置 showHeader: false,隐藏页头;该配置在实施期间已存在于工作区,本轮保留。showFooter 省略,使用默认显示。公共框架的页头缺省值仍为显示。标题片段中的空格由 text 明确提供;所有内容通过文本插值渲染,不使用 v-html。

本阶段展示文案为英文,不修改全局翻译文件或语言状态。已有 meta.title、权限、缓存字段及浏览器标题生成逻辑保持原含义。

面包屑导航保留当前查询参数;Location 对象中的显式 query 可覆盖同名参数。展示配置不提供任何认证豁免。

6. 登录与匿名访问接入

当前入口涉及以下文件:

  1. src/views/login/index.vue:现有 Register 按钮通过 /signup 路径进入注册页,透传 $route.query;保留 native-type="button",不调用登录方法。
  2. src/router/index.js 与 src/router/modules/refactor.js:通过常量路由接入公共布局及同路径注册子页面,支持 PublicSignup 命名导航。
  3. src/permission.js:仅将 /signup 加入原匿名白名单,不改变其他认证分支。

页头 Logo / 账户入口、面包屑和注册页 Sign in 链接保留查询参数,例如 redirect。退出按钮单独调用 user/logout,再把当前 fullPath 作为返回登录的 redirect。注册表单不把用户名、密码或表单值加入 URL。

登录后的访问继续遵循原守卫;本轮不新增“登录后访问注册必须退出”等规则。登录页的 Register 以外的展示、登录 actions、验证码条件、失败清理和成功跳转不变。

7. 历史验证与当前限制

以下构建、lint 和浏览器结果来自 2026-10-09 的原始实施记录,适用于当时版本。目录、资源、路由和游客支付后续已有变化,不能将这些结果直接作为当前版本验收。

旧目录名 public 曾被 .eslintignore 误匹配,历史检查使用了 --no-ignore。当前文件已移出该目录;需要重新验证时可执行 eslint --no-ignore --ext .js,.vue src/ui-refactor,不修改配置或批量修复历史问题。

已知环境存在 Vue 2.7.16 与旧 vue-template-compiler 2.6.10 的版本差异;本次不改依赖。模板检查使用 vue-loader 当前采用的 Vue 2.7 vue/compiler-sfc 路径,不能用直接加载旧编译器失败来断言完整构建失败。

浏览器验证不使用真实凭证,不提交注册或登录请求。真实认证、注册成功和后端联调不在本次验收范围。

初始框架执行结果

检查 结果
新增组件 lint eslint --no-ignore --ext .vue src/ui-refactor/public,5 个文件,0 error / 0 warning;未启用自动修复
存量文件 lint 差异 登录页 5 → 5、路由 23 → 23、守卫 0 → 0 error,诊断内容相同;没有新增问题
Vue 模板编译 使用 vue/compiler-sfc,5 个模板全部通过
生产构建 使用现有 vue-cli-service build --dest 输出到临时目录,最终退出码 0;保留资源及入口体积警告和浏览器兼容数据过期提示,没有修改配置或依赖
匿名访问 直接访问注册、刷新和查询参数保留通过;注册页初始化没有业务 API 请求
注册入口 Register 点击、Enter 键跳转通过,没有触发登录非空提示或 /v1/oauth/login 请求
返回与历史 注册卡片、面包屑、页头按钮及 Logo 返回通过;浏览器前进后退及查询参数数组保留通过
布局配置 页头 / 横幅 / 页脚的 8 种组合通过;隐藏页头时主区域从 y=0 开始;缺省叶子配置不继承父级横幅
响应式 320 / 375 / 768 / 1024 / 1440px 无横向溢出,字号及侧边距符合规范,Logo 加载正常,短页面页脚落底
短视口与长文案 320×400px 可滚动到页脚;长标题、副标题自然换行;标题中的 HTML 字符仍作为文本渲染
样式隔离 使用全新浏览器页面,先确认未加载公共 CSS,再进入注册并返回;登录卡片、输入框和两个按钮的位置、字体、颜色、背景、边框及圆角均一致
权限回归 未登录访问 /dashboard/index 仍跳转登录并保留原 redirect;命名注册路由与路径导航均解析为 /signup
浏览器运行 Chromium 实际加载生产构建,14 组主回归及独立样式 / 命名导航检查通过,没有页面运行异常;所有 XHR / fetch 在独立测试浏览器内拦截,未请求真实后端

页头按钮与 Logo 的检查是在测试浏览器中临时开启 header 完成的,不修改实际注册页隐藏页头的配置。布局显隐、长文案测试同样仅临时调整浏览器内路由记录,不增加演示路由或生产调试入口。

存量登录文件移除本轮新增的按钮点击属性后,SHA-256 与任务开始时一致,证明其余内容没有改写。全量基线核查还检测到 .idea/workspace.xml 在实施期间发生变化;本轮未主动编辑、恢复或清理该 IDE 文件。

Hero 与页脚补全验证

  • 5 个公共组件定向 lint 为 0 error / 0 warning,5 个 Vue 模板编译通过;最终生产构建退出码 0,仍有现有资源体积和浏览器数据过期提示。
  • Chromium 实际加载最终生产构建,在 2560px 宽度核验 Hero 高度为 560px,副标题宽度为 430px,页脚高度约 473px,并与用户的 Hero / 页脚截图进行分区对照。
  • 检查 320、375、768、1024、1200、1440、2560px:页脚分别按 1 / 2 / 4 列排列,无横向溢出,Logo 和两个社交 SVG 均加载成功,页脚位于文档底部。
  • 核验三组页脚标题、9 个栏目条目、版权内容、电话 / 邮件 / 社交链接;不存在指向未实现 .html 页面的假链接。短视口下可以滚动到社交入口,键盘焦点清楚可见。
  • Register、返回登录、查询参数保留及匿名刷新正常;没有页面运行异常。测试浏览器拦截所有 XHR / fetch,未请求真实后端。
  • 独立浏览器先打开未加载公共 CSS 的登录页,再进入注册并返回;登录卡片、输入框和两个按钮的几何位置、字体、颜色及边框均未改变,命名注册路由仍解析为 /signup。
  • 本轮修改仅限 Hero、页脚、注册 Hero 的 meta 副标题、两个参考社交图标以及本设计说明;没有修改登录、注册主体、权限守卫或全局样式。