面试题答案
一键面试Solid.js路由导航守卫工作原理
- 导航流程触发:当用户点击链接或通过编程方式(如调用
history.push
等方法)尝试访问一个新路由时,导航流程开始。 - 守卫触发顺序:
- 前置守卫:在导航开始,即将进入新路由组件渲染之前触发。可以用来进行权限验证、检查用户登录状态等操作。
- 解析守卫:在路由配置中的
children
被解析时触发,用于处理嵌套路由相关逻辑。 - 组件内守卫:在路由组件被创建时触发,如
onMount
阶段等,可以在组件层面进行导航控制。 - 后置钩子:在导航完成后触发,一般用于进行页面加载完成后的一些操作,比如设置页面标题等。
- 守卫决策:守卫函数可以返回
true
允许导航继续,返回false
阻止导航,也可以返回一个Promise
,当Promise
resolve 为true
时允许导航,reject 时阻止导航。
自定义全局前置导航守卫实现权限验证
- 安装依赖:首先确保项目中安装了
@solidjs/router
。假设项目已初始化并安装好相关依赖。 - 实现代码:
import { Router, Route, Routes, navigate, createLocation } from '@solidjs/router';
import { createEffect, createSignal } from 'solid-js';
// 模拟权限验证函数,返回true表示有权限,false表示无权限
const hasPermission = (to) => {
// 这里可以根据路由信息to,比如to.pathname判断权限
// 例如:某些特定路由需要登录权限
const protectedRoutes = ['/admin', '/settings'];
return!protectedRoutes.includes(to.pathname) || true; // 这里简单返回true模拟有权限
};
const GlobalBeforeEach = () => {
const [location] = createLocation();
createEffect(() => {
const { pathname } = location();
const nextLocation = createLocation();
if (!hasPermission(nextLocation())) {
navigate('/login'); // 无权限则导航到登录页
}
});
return null;
};
const App = () => (
<Router>
<GlobalBeforeEach />
<Routes>
<Route path="/" component={() => <div>Home</div>} />
<Route path="/admin" component={() => <div>Admin Page</div>} />
<Route path="/settings" component={() => <div>Settings Page</div>} />
<Route path="/login" component={() => <div>Login Page</div>} />
</Routes>
</Router>
);
export default App;
在上述代码中:
hasPermission
函数模拟权限验证逻辑,根据目标路由路径判断是否有权限。GlobalBeforeEach
函数利用createEffect
和createLocation
实现全局前置导航守卫。在路由变化时,检查权限,若没有权限则导航到登录页。- 在
App
组件中,将GlobalBeforeEach
放置在Router
内部,确保在路由导航过程中能触发权限验证。