今回の狙い
Web画面の機能といえば、メニューがあり、色々なサブ画面から成り立つ と。
今回は、今までの環境をそのまま流用して、その辺りを作ってみたいと思います。
実装
多く見えますが、site1~site3までは、今までの勉強①~③の寄せ集めです。
今回は、「Menu.js」だけとなってます。
フォルダ構成
└── src
├── site1 (勉強1のRestAPIと一覧表示)
| └── WebApi.js (index.jsは不要)
├── site2 (勉強2の入力画面)
| ├── App.js (index.jsは不要)
| ├── ErrCheck.js (入力チェック処理部)
| └── msg.jp.js (エラーメッセージ)
├── site3 (勉強3のポップアップ)
| ├── components (画面プログラム)
| | ├── Form.js (入力画面処理)
| | └── AlertDialog.js (ポップアップ画面処理)
| └── pages (index.jsは不要)
| └── App.js (画面制御処理)
├── Menu.js (★今回の主役★)
└── index.js (カレントパスの起動プログラム)
以下、起動プログラムはいつも通りです。
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './Menu';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
以下が本丸のプログラムです。
Menu.js
import { useState } from 'react';
import App1 from './site1/WebApi';
import App2 from './site2/App';
import App3 from './site3/pages/App';
import { Box, IconButton, Drawer, List, ListItem, ListItemButton, ListItemText, ListItemIcon } from '@mui/material';
import { Home, Add, Message, Menu } from '@mui/icons-material';
import ListIcon from '@mui/icons-material/List';
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';
const menu = [
{ title: 'ホーム', href: '/', icon: Home },
{ title: 'Redmineユーザ一覧', href: '/list', icon: ListIcon },
{ title: 'Redmineユーザ登録', href: '/add', icon: Add },
{ title: 'ポップアップ', href: '/dialog', icon: Message },
];
export default function Menu1() {
const [show, setShow] = useState(false);
const handleDraw = () => setShow(!show);
return (
<>
<Box mb={2}>
<IconButton onClick={handleDraw} color="inherit" aria-label="menu">
<Menu />
</IconButton>
</Box>
<BrowserRouter>
<Routes>
<Route path="/" element={<p>お知らせ・・・</p>} />
<Route path="/list" element={<App1 />} />
<Route path="/add" element={<App2 />} />
<Route path="/dialog" element={<App3 />} />
</Routes>
<Drawer anchor="left" open={show}>
<Box sx={{ height: '100vh' }} onClick={handleDraw}>
<List>
{menu.map(obj => {
const Icon = obj.icon;
return (
<ListItem key={obj.title}>
<ListItemButton component={Link} to={obj.href}>
<ListItemIcon><Icon /></ListItemIcon>
<ListItemText primary={obj.title} />
</ListItemButton>
</ListItem>
);
})}
</List>
</Box>
</Drawer>
</BrowserRouter>
</>
);
}
アイコン画像は、色々と準備されているのですが、下記のURLから検索が可能です。
https://mui.com/material-ui/material-icons/
ここまで色々とまとめられると、「もっとイケル」と思う訳で。。。
簡単に出来そう… と思うと、罠が待ち受けます。
例えば、今回用意したプログラム群を1階層下のフォルダにまとめたいと…。
(例として、「sub」のフォルダ配下に、全てを配置します)
そんな時のコツとして、呼び出し元で下層の複数のリンクに対応する為、パスに*が付きます。
(下層のMenuは、区別する為、「Menu1.js」に変更)
上層.js(Menu.js)
import App from './sub/Menu1'; (下層のLinkプログラム)
・・・
const menu = [
{ title: 'ホーム', href: '/', icon: Home },
{ title: 'サブ', href: '/sub', icon: Message },
・・・
<Routes>
<Route path="/" element={<p>お知らせ・・・</p>} />
<Route path="/sub/*" element={<App />} /> (下層は/sub/・・・となります)
</Routes>
下層のLinkプログラムも改修が必要です。
下層.js(Menu1.js)
・・・
const menu = [
{ title: 'ホーム', href: '', icon: Home },
{ title: 'Redmineユーザ一覧', href: 'list', icon: ListIcon }, (パスの頭の/は削除)
・・・ (<BrowserRouter>のタグは削除する必要があります)
<Routes>
<Route path="dialog" element={<App3 />} /> (パスの頭の/は削除)
・・・
コツが解れば、画面単位に開発者が別で、大規模開発も狙えそうですね。
以上、御疲れ様でした~。