news 2026/8/22 15:24:30

如何用Viewi构建登录守卫:组件级中间件完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何用Viewi构建登录守卫:组件级中间件完整指南

如何用Viewi构建登录守卫:组件级中间件完整指南

【免费下载链接】viewiUnique and efficient front-end framework for PHP项目地址: https://gitcode.com/gh_mirrors/vi/viewi

Viewi 是一款独特的 PHP 前端框架(Unique and efficient front-end framework for PHP)。它内置的组件级中间件(Middleware)机制,让你只需一个类、一行属性,就能为任意页面组件添加登录守卫(Login Guard),在组件渲染前拦截未登录用户,无需手写任何路由判断逻辑。

为什么需要登录守卫 🔐

传统做法是在每个受保护页面里手动判断"用户是否登录",代码重复且容易遗漏。Viewi 把守卫做成组件属性:

  • ✅ 声明式:在组件类上一行声明,无需侵入页面逻辑
  • ✅ 组件级生效:守卫只对绑定的组件起作用,粒度比全站中间件更细
  • ✅ 可组合:一个组件可挂多个守卫,按顺序执行

客户端渲染入口 renderApp.ts 会在组件渲染前先跑完整个守卫链,任何一个守卫拒绝(next(false)),组件就不会被渲染

3步搭建登录守卫

第1步:安装 Viewi

git clone https://gitcode.com/gh_mirrors/vi/viewi

第2步:编写守卫类

守卫只需实现 IMIddleware 接口,在run()方法中调用next()决定是否放行:

use Viewi\Components\Middleware\IMIddleware; use Viewi\Components\Middleware\IMIddlewareContext; use Viewi\Components\Browser\BrowserSession; use Viewi\Components\Routing\ClientRoute; class AuthGuard implements IMIddleware { public function __construct( private BrowserSession $session, private ClientRoute $route ) {} public function run(IMIddlewareContext $c) { $user = $this->session->getItem('user'); if ($user === null) { $this->route->navigate('/login'); // 跳转登录页 $c->next(false); // 拦截 return; } $c->next(true); // 放行 } }

💡 小技巧:Viewi 的 BrowserSession 可读写浏览器 sessionStorage,ClientRoute 负责页面跳转,两者可直接注入守卫构造函数。

第3步:把守卫绑定到组件

使用 Middleware 属性 声明式绑定,一行搞定:

use Viewi\Components\Attributes\Middleware; #[Middleware([AuthGuard::class])] class DashboardPage extends BaseComponent { // 未登录时,这个页面根本不会渲染 }

构建时,Builder 会自动解析Middleware属性,把守卫清单写入组件元数据,并在客户端渲染前按序执行——整个过程零配置。

带参数的守卫:一份代码,多处复用 🔁

守卫支持参数化绑定:在类名后追加位置参数,Viewi 会自动按构造函数参数名注入。

class RoleGuard implements IMIddleware { public function __construct(public string $role) {} public function run(IMIddlewareContext $c) { // 只允许 $role 角色访问 $c->next(checkRole($this->role)); } } #[Middleware([[RoleGuard::class, 'admin']])] class AdminPage extends BaseComponent {} #[Middleware([AuthGuard::class, [RoleGuard::class, 'editor']])] class EditPage extends BaseComponent {}

注意两点:

写法含义
'Class::class'字符串无参数守卫
['Class::class', 参数1, ...]数组带参数守卫,参数按构造函数形名注入

一个组件可以同时挂多个守卫,从左到右依次执行,任一项拦截即终止。

登录守卫最佳实践清单

  • 🎯只拦截、少渲染next(false)后客户端会直接停止渲染,配合navigate()跳转登录页体验最佳
  • 🔁复用守卫:用参数化守卫(如 RoleGuard)避免为每种权限写一个新类
  • 🧪登录页保持无守卫:给登录页加AuthGuard会造成跳转死循环
  • 守卫内保持轻量:守卫在每次组件渲染前执行,避免在其中做耗时 IO

常见问题排查 🛠️

Q:守卫不生效,页面还是渲染了?检查Middleware属性是否写在组件类上(它只支持Attribute::TARGET_CLASS),且守卫类已实现IMIddleware接口。

Q:拦截后页面空白,没有跳转?确保在next(false)之前调用了$route->navigate('/login'),或自行处理重定向。

Q:多个守卫的执行顺序?#[Middleware([...])]数组中的声明顺序依次执行,全部next(true)才会渲染组件(见 renderApp.ts 中的守卫链实现)。

核心源码路径速查

文件作用
Middleware.php组件级守卫声明属性
IMIddleware.php守卫接口定义
IMIddlewareContext.phpnext(bool)放行/拦截上下文
Builder.php构建期解析守卫清单
routes.php路由注册示例(可放登录页路由)

掌握这套机制后,登录守卫、角色权限、功能开关等场景都可以用同一个模式优雅解决——这正是 Viewi "高效"理念的体现。

【免费下载链接】viewiUnique and efficient front-end framework for PHP项目地址: https://gitcode.com/gh_mirrors/vi/viewi

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/22 15:21:21

vaststars科技树实现解析:techtree与laboratory研究队列系统全攻略

vaststars科技树实现解析:techtree与laboratory研究队列系统全攻略 【免费下载链接】vaststars A game demo for Ant engine 项目地址: https://gitcode.com/gh_mirrors/va/vaststars vaststars 是一款基于 Ant 引擎的火星工厂模拟游戏,其科技树系…

作者头像 李华