最近项目中有个小需求,为导航菜单添加快捷键功能,效果就是通过相应的快捷键可进行页面切换。我本地实现的简易小demo的效果如下:
快捷键功能的实现思路是:
- 监测keyup事件
- 获取键码
- 执行相应的操作
快捷键相关的代码如下:
// utils.js
import { useEffect} from 'react';
export const useKbd = (callback) => {
const handleClick = (e) => {
callback(e);
};
//监听keyup事件,在组件卸载时取消监听
useEffect(() => {
document.addEventListener('keyup', handleClick);
return () => {
document.removeEventListener('keyup', handleClick);
};
});
};
//菜单项组件.js
import {useKbd} from './utils/utils'
//注:该方法要在渲染菜单项的组件中使用
useKbd((e) => {
const { keyCode } = e; // 获取键码
switch (keyCode) {
case 113: // 'F2'
navigate('/'); //进行相应的页面跳转
break;
case 118: // f7
navigate('/setting');
break;
case 119: // f8
navigate('/user');
break;
default:
break;
}
});
完整代码如下:
1.路由表 router.js
注:在需要设置快捷键的路由项中添加一个属性:kbd
例:kbd: 'F2',
import Home from '../pages/home/Home'
import Setting from '../pages/setting/Setting'
import User from '../pages/user/User'
const routers = [
{
path: '/',
name: '首页',
exact: true,
hide: false,
kbd: 'F2',
key: 'home',
component: Home,
element:<Home/>
},
{
path: '/setting',
name: '基础设置',
exact: true,
hide: false,
kbd: 'F7',
key: 'Setting',
component: Setting,
element:<Setting/>
},
{
path: '/user',
name: '用户管理',
exact: true,
hide: false,
kbd: 'F8',
key: 'User',
component: User,
element:<User/>
}
]
export default routers
菜单项渲染页 XX.js
import React from 'react';
import routers from './route/router'
import { Outlet,NavLink,Routes,Route,useNavigate } from 'react-router-dom';
// ↓ utils这个文件的内容就是本篇文章的第一段代码,麻烦爬楼自取下,这里就不重复粘贴了。
import {useKbd} from './utils/utils'
function Layout () {
const navigate = useNavigate()
useKbd((e) => {
const { keyCode } = e;
switch (keyCode) {
case 113: // 'F2'
navigate('/');
break;
case 118: // f7
navigate('/setting');
break;
case 119: // f8
navigate('/user');
break;
default:
break;
}
});
return (
<div style={{display:'flex'}}>
<div style={{display:'flex',flexDirection:'column',background:'#FF9800',height:'200px'}}>
{routers?.map(
(item) =>
!item.hide && (
<NavLink
key={item.key}
to={item.path}
style={{textDecoration:'none',padding:'2px 15px',margin:'5px 0',color:'#fff'}}
>
{item.name}{item.kbd && <span style={{paddingLeft:8}}>{item.kbd}</span>}
</NavLink>
),
)}
</div>
<div style={{padding:20,width:1000,background:'#eee'}}>
<Outlet/>
</div>
</div>
)
}
const App = () => {
return (
<div>
<Routes>
<Route path="/" element={<Layout />}>
{
routers?.map(
(item) =>
!item.hide && (
<Route key={item.key} path={item.path} element={item.element} />
),
)
}
</Route>
</Routes>
<div>
</div>
</div>
)
}
export default App;
另外这里提醒下,在入口文件 index.js
记得要用BrowserRouter包裹
<BrowserRouter> <App /> </BrowserRouter>
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {BrowserRouter} from 'react-router-dom'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
reportWebVitals();
好了,本文就记录到这里了,站起来运动一下吧~