为导航菜单添加快捷键功能

258 阅读2分钟

最近项目中有个小需求,为导航菜单添加快捷键功能,效果就是通过相应的快捷键可进行页面切换。我本地实现的简易小demo的效果如下:

图片.png

快捷键功能的实现思路是:

  1. 监测keyup事件
  2. 获取键码
  3. 执行相应的操作

快捷键相关的代码如下:

// 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();

好了,本文就记录到这里了,站起来运动一下吧~

b5af6672b1d6444da871404b629b2c90.gif