All Projects → fattypanda → umi-plugin-menus

fattypanda / umi-plugin-menus

Licence: MIT license
将 umi 生成的 routes 转换成 tree 结构 menus 数据,开发中可直接引入该文件来进行导航菜单的生成

Programming Languages

javascript
184084 projects - #8 most used programming language
CSS
56736 projects

Projects that are alternatives of or similar to umi-plugin-menus

umi-plugin-electron-builder
umi的electron插件
Stars: ✭ 115 (+296.55%)
Mutual labels:  umi, umi-plugin
umi-plugin-mobx
😍 use mobx-state-tree gracefully in umijs.
Stars: ✭ 33 (+13.79%)
Mutual labels:  umi, umi-plugin
umi-plugin-md
🍚 Markdown(*.md) component plugin for umi.
Stars: ✭ 16 (-44.83%)
Mutual labels:  umi, umi-plugin
umi-plugins
Umi Plugins
Stars: ✭ 14 (-51.72%)
Mutual labels:  umi, umi-plugin
umi-react-native
umi preset plugins for react-native
Stars: ✭ 54 (+86.21%)
Mutual labels:  umi, umi-plugin
Xrouter
Navigate anywhere in just one line.
Stars: ✭ 411 (+1317.24%)
Mutual labels:  routes
Slim Oauth2
Routes and Middleware for Using OAuth2 Server within a Slim Framework API
Stars: ✭ 121 (+317.24%)
Mutual labels:  routes
Microwebsrv2
The last Micro Web Server for IoTs (MicroPython) or large servers (CPython), that supports WebSockets, routes, template engine and with really optimized architecture (mem allocations, async I/Os). Ready for ESP32, STM32 on Pyboard, Pycom's chipsets (WiPy, LoPy, ...). Robust, efficient and documented!
Stars: ✭ 295 (+917.24%)
Mutual labels:  routes
routemap
DEPRECATED Returns a list of Craft/Vue/React route rules and entry & asset URLs for ServiceWorkers from Craft entries
Stars: ✭ 27 (-6.9%)
Mutual labels:  routes
hapi-routes
Hapi plugin for registering routes
Stars: ✭ 12 (-58.62%)
Mutual labels:  routes
Ziggy
Use your Laravel named routes in JavaScript
Stars: ✭ 2,619 (+8931.03%)
Mutual labels:  routes
Php Wss
Web-socket server/client with multi-process and parse templates support on server and send/receive options on client
Stars: ✭ 117 (+303.45%)
Mutual labels:  routes
Phoenix routes js
Phoenix routes helpers in JavaScript code.
Stars: ✭ 17 (-41.38%)
Mutual labels:  routes
Express Env Example
A sample express environment that is well architected for scale. Read about it here:
Stars: ✭ 130 (+348.28%)
Mutual labels:  routes
Stplanr
Sustainable transport planning with R
Stars: ✭ 352 (+1113.79%)
Mutual labels:  routes
Next Routes
Universal dynamic routes for Next.js
Stars: ✭ 2,354 (+8017.24%)
Mutual labels:  routes
Getx
Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get.
Stars: ✭ 5,578 (+19134.48%)
Mutual labels:  routes
Routegen
Define your API and SPA routes in one place. Use them anywhere. Only 1.3kb.
Stars: ✭ 86 (+196.55%)
Mutual labels:  routes
Php Whois
PHP WHOIS provides parsed and raw whois lookup of domains and ASN routes. PHP 5.4+ and 7+ compatible
Stars: ✭ 179 (+517.24%)
Mutual labels:  routes
Nova Route Viewer
Route viewer tool for Laravel Nova
Stars: ✭ 54 (+86.21%)
Mutual labels:  routes

umi-plugin-menus

NPM version NPM downloads

routes to menus

umi 生成的 routes 转换成 tree 结构 [menus|routes].json 数据,开发中可直接引入该文件来进行导航菜单的生成

PS: routes 更新时 [menus|routes].json 文件也会实时更新

Usage

Configure in .umirc.js And config/config.js,

.umirc.js

import { join } from 'path';

export default {
  plugins: [
    ['umi-plugin-menus', {
      build: join(__dirname, './src/routes.json'),
    }],
  ],
}

src/pages/first/index.js

/**
 * title: 首页           // 菜单名称
 * order: 1             // 菜单排序
 * hideMenu: true       // 隐藏菜单(菜单组件实现)
 * hideChildMenu: true  // 隐藏子菜单(菜单组件实现)
 */
import React from 'react';

export default function First(props){
  return (<div>first page</div>)
};

src/layouts/index.js

import React, {useState, useEffect} from 'react';
import {Layout, Menu} from 'antd';

import Link from 'umi/link';
import _get from 'lodash/get';
import _map from 'lodash/map';
import _find from 'lodash/find';
import _uniq from 'lodash/uniq';
import _concat from 'lodash/concat';
import _compact from 'lodash/compact';
import _split from 'lodash/split';
import _slice from 'lodash/slice';
import _toString from 'lodash/toString';
import _isArray from 'lodash/isArray';
import _isEmpty from 'lodash/isEmpty';

//  引入插件生成的数据
import routes from '../routes.json';

const {Content, Sider} = Layout;

const menus = _get(routes, [0, 'routes']);

/**
 * 递归生成菜单
 * @param {array} menus
 * @param {object} [parent]
 * @param {string|number} [parent.key]
 * @param {array} stack
 * @returns {Array}
 */
function recursiveMenus (menus, parent = {}, stack = []) {
  const {key: parentKey = ''} = parent;

  return _compact(_map(menus, (menu, key) => {

    const {title, path, routes, hideMenu = false, hideMenuChild = false} = menu;
    const k = `${parentKey? `${parentKey}-`: ''}${key}`;
    stack.push({key: k, ...menu});

    if (hideMenu) return undefined;

    if (_isArray(routes) && !_isEmpty(routes) && !hideMenuChild) {
      return (
        <Menu.SubMenu key={k} title={title}>
          {recursiveMenus(routes, {key: k}, stack)}
        </Menu.SubMenu>
      );
    } else {
      return (
        <Menu.Item key={k}>
          <Link to={path}>{title}</Link>
        </Menu.Item>
      );
    }
  }));
}

function BasicLayout(props) {

  const [collapsed, setCollapsed] = useState(false);
  const [openKeys, setOpenKeys] = useState([]);
  const [selectedKeys, setSelectedKeys] = useState(['0']);
  const [menuItems, setMenuItems] = useState([]);
  const [menuItemsComponent, setMenuItemsComponent] = useState();

  useEffect(() => {
    const stack = [];
    const menuItemsComponent = recursiveMenus(menus, {}, stack);
    setMenuItems(stack);
    setMenuItemsComponent(menuItemsComponent);
  }, []);

  useEffect(() => {
    const key = _get(_find(menuItems, ({path, routes}) => !routes && path === props.location.pathname), ['key']);
    if (key) {
      const keys = _split(key, '-');
      if (keys.length > 1) {
        setOpenKeys(_uniq(_concat(_compact(_map(keys, (v, k) => {
          const length = keys.length - 1;
          if (k < length) return _slice(keys, 0, length - k).join('-');
        })), openKeys)));
      }
      setSelectedKeys([_toString(key)]);
    }
  }, [props.location.pathname, JSON.stringify(menuItems)]);

  return (
    <Layout style={{height: '100vh'}}>
      <Sider collapsible collapsed={collapsed} onCollapse={v => setCollapsed(v)}>
        <Menu theme={'dark'} openKeys={openKeys} selectedKeys={selectedKeys} mode={'inline'} onOpenChange={setOpenKeys}>
          {menuItemsComponent}
        </Menu>
      </Sider>
      <Layout>
        <Content>
          <div style={{width: '100vw', height: '100vh'}}>
            {props.children}
          </div>
        </Content>
      </Layout>
    </Layout>
  );
}

export default BasicLayout;

Options

declare enum OrderTypes {asc = 'asc', desc = 'desc'}

/**
 * @param {string} [build='./menus.json'] - 导出的路径
 * @param {string[]} [excludes=['exact','component','Routes']] - 返回忽略字段
 * @param {[[string], [string]]} [order=[['order'], ['asc']]] - 根据字段排序 参考 lodash/orderBy
 */
export interface options {
  build?: string,
  excludes?: string[],
  order?: [[string], [OrderTypes]]
}

LICENSE

MIT

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].