ExpressアプリをNext.jsにリファクタリング① Drawerで表示分割
IPO(新規上場株)の評価表示アプリをNext.jsでリファクタリングする
Expressアプリで作っていたIPOの評価をまとめて表示するアプリをNext.jsにリファクタリングしていきます。詳細については以前投稿したリファクタリングの設計記事を参考にしてください。なお、完成形のイメージは以下画像のようになります。これはExpressで作った画面なので、これをNext.jsで作り直すイメージですね。
今回の記事では上図のように画面を3つに分割する作業をしていきます。
設計記事でも書きましたがデザインはMaterial UIを使って整形し、今回の画面3分割はMaterial UIのDrawerを活用します。
Material UIのDrawerで画面分割していく(ソースコードあります)
Material UIを使うためには公式サイトから取得する必要があります。その前に一応開発環境と使用言語を以下に書いておきます。
- 開発環境:Visual Studio Code
- 使用言語:TypeScript
それではまずMaterial UIのDrawerページに行って、使えそうな項目を探してみましょう。
Drawerページで上図のように常時左側に項目を表示できる例を見つけました。この画像の下側に見切れていますがソースコードの使用例が紹介されているのでそちらを使用します。そのソースコードをとりあえずコピペして私のプロジェクトに張り付けると以下のような出力が出てきました。
サンプルでは左側のコンテンツにアイコンがありましたが、今回は使わないので消しました。アイコンを使いたい場合は必要なライブラリをインストールすれば表示できます。サンプルに使わせてもらって恐縮なのですが、正直ソースコードが見にくいので少し修正して全体的なデザインを見やすくします。
はい、不必要なコンテンツを排除し、必要な機能だけを残したプログラムに変更しました。ソースコードはこの記事の最後の方で共有しますね。
これで左側と中央のコンテンツを分離する事ができました。画面は3分割する予定なので右側のコンテンツも表示できるようにソースコードを改修していきます。先ほどと同様にMaterial UIのDrawerページから右側コンテンツを常時表示できるような項目を探します。
Drawerページにありました。右側にコンテンツが固定表示されています。そしてソースコードを確認すると、どうやら左側コンテンツで固定するタグのCSSを1行変更するだけで右側に固定できるようです。非常に簡略な作りで助かります。開発者の方、ありがとうございます。
そして、それを踏まえて私のプロジェクトを作りこむと、以下のような表示になりました。
はい、無事表示を3分割できました。これからは左側コンテンツ、中央コンテンツ、右側コンテンツをそれぞれのタグとして作りこんで、組み込むだけです。まぁそこが少し大変なのですが。
とりあえず分割できましたし、Drawerの作り方も把握できたのでソースコードの中身について解説していこうと思います。
ソースコード紹介とちょっとだけ解説
先ほど作成したブラウザ画面を3分割するWebアプリのソースコードを公開していきます。
とりあえずの表示だけなのでそこまで大きいプログラムではありませんし、ファイル分割もしていないので分かりやすいとは思います。
import Head from 'next/head'
import React from 'react';
import { createStyles, Theme, makeStyles } from '@material-ui/core/styles';
import Drawer from '@material-ui/core/Drawer';
import CssBaseline from '@material-ui/core/CssBaseline';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
const drawerWidth = 240;
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
display: 'flex',
},
appBar: {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: drawerWidth,
},
drawer: {
width: drawerWidth,
flexShrink: 0,
},
drawerPaper: {
width: drawerWidth,
},
// necessary for content to be below app bar
toolbar: theme.mixins.toolbar,
content: {
flexGrow: 1,
backgroundColor: theme.palette.background.default,
padding: theme.spacing(3),
},
}),
);
export default function Home() {
const classes = useStyles();
return (
<div>
<Head>
<title>IPOまとめサイト</title>
</Head>
<div className={classes.root}>
{/*題名部分*/}
<CssBaseline />
<AppBar position="fixed" className={classes.appBar}>
<Toolbar>
<Typography variant="h6" noWrap>
IPOまとめサイト
</Typography>
</Toolbar>
</AppBar>
{/*以下左側コンテンツ*/}
<Drawer className={classes.drawer} variant="permanent" classes={{paper: classes.drawerPaper,}} anchor="left">
<div className={classes.toolbar} />
<Typography paragraph>
左側のコンテンツ
</Typography>
</Drawer>
{/*以下中央コンテンツ */}
<main className={classes.content}>
<div className={classes.toolbar} />
<Typography paragraph>
中央のコンテンツ
</Typography>
</main>
{/*以下右側コンテンツ */}
<Drawer className={classes.drawer} variant="permanent" classes={{paper: classes.drawerPaper,}} anchor="right">
<div className={classes.toolbar} />
<Typography paragraph>
右側のコンテンツ
</Typography>
</Drawer>
</div>
</div>
)
}
ちょっと記事としてまとめるには大きいかな・・?Githubに公開する気はないので見にくい方は我慢してください・・・。
まぁ上のimportの部分は必要な項目を取得しているだけです。const useStylesの部分で今回のDrawerで画面分割する上で必要なCSSデザインを調整しています。このuseStylesは実はもっときれいに書けるのですが、個人的にはそのままMaterial UIの公式からコピペして使うので十分だと思っています(会社だとそのまま使うと怒られます・・・)。
そしてまぁ一応これがトップページなので題名を入れる<Head>タグが入っていますね。
それより下にいくと、Drawerタグが2回でてくると思います。これが左側と右側の分割画面です。イメージ図を入れておきます。
あとは「左側のコンテンツ」とか「右側のコンテンツ」とか書いてある場所に、それぞれ入れたいタグを自作して入れるだけで綺麗に表示されるはずです。
この説明で分かる人いるのかな・・・?Youtubeか何かに音声付きの説明をアップロードした方がいいのか少し迷いますね。
さて、次回の記事では中央のコンテンツを作成して埋め込むところまでをやっていきます。